fix: add missing component renderers#166
Merged
Infi-Knight merged 6 commits intostagingfrom Apr 1, 2026
Merged
Conversation
✅ Deploy Preview for interledger-org-v5 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
PAGE_CONTENT_POPULATE includes all block types (cards-grid, carousel, etc.). BLOG_CONTENT_POPULATE includes only blog-relevant blocks (paragraph, ambassador, blockquote, callout-text, pdf-embed, video-embed). Keeps populate params in sync with the content-type schema component lists.
Anca2022
reviewed
Mar 31, 2026
- Align summit-page dynamic-zone components with foundation-page - Remove unused imports from FoundationBlogPostPage - Simplify blog components map to Paragraph + VideoEmbed INTORG-535
Anca2022
approved these changes
Apr 1, 2026
Contributor
Anca2022
left a comment
There was a problem hiding this comment.
Made a commit to add missing imports, other than that, all looks good :D
bosbaber
added a commit
that referenced
this pull request
Apr 9, 2026
…vironment (#195) * fix(ci): remove stray page-for-ambassadors (#111) remove stray page-for-ambassadors * feat(sync-mdx): add Paragraph component handler for MDX import jm/intorg-457-paragraph-component (#102) * add Paragraph to mdx files * fix(cms): delete orphaned localizations before recreating to preserve document links * fix(cms): use js-yaml v4 custom engine for single-quoted YAML frontmatter * feat(cms): add Paragraph block handler for sync-mdx parser * feat: render paragraph blocks as <Paragraph> JSX component * pnpm format * fix(sync-mdx): preserve dash bullet list marker on paragraph import * fix(sync-mdx): fix bullet lists handling in component handlers and add new tests (#108) * add Paragraph to mdx files * feat(cms): add Paragraph block handler for sync-mdx parser * pnpm format * fix bullet list handling, refactor * add and cleanup tests * format --------- Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> * fix(ci): refresh cms lockfile for js-yaml (#113) * feat(404): add custom 404 page for static hosting jm/intorg-484-404page (#114) * feat(404): add custom 404 page for static hosting * pnpm format * refactor(utils): convert create-excerpt to TypeScript - jon/intorg-445 (#115) refactor(utils): convert create-excerpt to TypeScript * ci(lint): add build job to lint workflow jon/intorg-405 (#117) ci(lint): add build job to lint workflow * feat(seo): add per-page meta title, description, image, and canonical… jon/intorg-446 (#116) * feat(seo): add per-page meta title, description, image, and canonical URL * pnpm format * chore(cms): update Strapi dependencies [INTORG-334] (#112) * feat: tailwind setup (#104) * refactor: modular CSS architecture with Tailwind v4 theme tokens - Decompose monolithic tailwind.css and pages.css into focused, layer-aware files - Add src/styles/theme.css with @theme tokens (typography, spacing, colors, animations) - Add src/styles/base/ for reset, typography (@font-face), and runtime CSS variables - Add src/styles/components/ for prose variants (default, blog, foundation, summit) and navigation - Move design tokens out of tailwind.config.mjs into @theme (removes duplication) - Rename [data-category] to [data-pillar] theming system - Standardise variable namespaces: --step-* → --text-step-*, --space-* → --spacing-space-* - Scope Starlight docs variables to :where(.sl-container) to prevent global leakage - Replace inline Tailwind arbitrary-variant classes with data-prose, data-prose-summit, data-nav-links attributes - Delete src/styles/pages.css (content redistributed into new modular files) * fix: update remaining --space-* references to --spacing-space-* AmbassadorGrid, SummitHeader, and FoundationHeader were still using the old --space-s variable name which no longer exists after the CSS variable namespace rename. * cleanup * pillar * fix schema * cleanup * review * Address PR feedback and prepare for staging merge * revert mdxTransformer * Delete cms/scripts/sync-mdx/README.md * ci: any change to the cms folder should trigger a rebuild (#118) * chore: update Astro dependencies [INTORG-333] (#119) * chore(cms): update @strapi/strapi 5.31.3 → 5.38.0, remove dead overrides [INTORG-334] - Bump @strapi/strapi from 5.31.3 to 5.38.0 (latest stable) - Remove inert pnpm.overrides block from cms/package.json — pnpm ignores overrides in workspace packages; only root overrides apply - All three plugins (@_sh/strapi-plugin-ckeditor, @ckeditor/strapi-plugin-ckeditor, @notum-cz/strapi-plugin-record-locking) accept @strapi/strapi ^5.0.0 * foundation-page: sync (2 created) * ambassador: create caroline-sinders * fix(cms): bump @_sh/strapi-plugin-ckeditor to ^7.1.0 The v6 plugin bundles @strapi/design-system 2.0.0-rc.18 which conflicts with Strapi 5.38.0's design-system 2.2.0, causing a styled-components crash in the admin panel. v7.1.0 uses design-system 2.1.2 which is compatible. * foundation-page: update test-page * remove test-page fixtures from content * cleanup, auto generated types * lockfile * foundation-page: sync (2 created) * ambassador: create caroline-sinders * foundation-page: update test-page * chore: upgrade to Astro 6, Node 22, and bump dependencies INTORG-333 Upgrade the Astro site from v5 to v6 and move from Node 20 (lts/iron) to Node 22 (lts/jod). Remove unused @astrojs/node adapter. Bump all major dependencies: @astrojs/mdx 5, @astrojs/netlify 7, @astrojs/starlight 0.38, Tailwind 4.2, Zod 4, marked 17, and eslint/typescript-eslint tooling. Update CI workflows to Node 22. Build, lint, all tests, and visual QA pass with no apparent regressions. * cleanup * cleanup * chore(cms): upgrade Strapi to 5.39.0 * docs: document dual lockfile setup for root and cms * ci(lint): fix build job to use Node 22 (required by Astro 6) * chore: bump deps — starlight-links-validator, better-sqlite3, @types/node, vitest * chore: pin pnpm to v10.27.0 across repo and CI workflows (#120) * chore: pin pnpm to v10.27.0 across repo and CI workflows * fix(ci): remove explicit pnpm version from workflows — read from packageManager field * ci: better file change detection to trigger build (#121) * ci: will now use change api to detect changes * ci: make sure we use pnpm 10.27.0 * Update .github/workflows/staging-merge.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update .github/workflows/staging-merge.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * ci: fixed reference issues --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: align i18n routes and rename slug to pathSlug (#107) * fix: align i18n routes and rename slug to pathSlug * chore(deps): add better-sqlite3 to onlyBuiltDependencies and pin conflicting deps with overrides * ci: pipeline should source basrc for nvm to work (#126) * ci: explicit export of NVM_DIR (#127) * ci: clean node modules before rebuild (#128) * ci: force clean build (#129) * ci: playground merge pipeline cleanup fix (#130) * chore: store Sessionize data as JSON files (#131) * feat: add Netlify-backed contact form (#87) * feat(contact): add contact us page * pnpm format * chore: exclude preview pages from seo (#135) exclude preview from seo * feat(cms): cleanup strapi admin UI INTORG-481 (#106) * fix(cms): disable draft and publish on all content types * feat(cms): configure edit view layouts for ambassador and SEO * feat(cms): customize admin panel styles and navigation * pnpm format * feat(cms): improve admin field labels and edit view layouts * feat(cms): add labels and full-width layout for ambassador, blockquote, callout-text * fix(cms): always apply field labels, not only when Strapi default * fix page title too * update labels * hide preview button * feat(cms): add help text for Directory Structure field * fix - hide preview button * simplify hiding open entity * add mutable observable to doc * stricter ID check in title * refactor(404): reuse shared 404 page instead of inline not-found sect… (#137) * refactor(404): reuse shared 404 page instead of inline not-found sections Replace per-page inline 404 markup in [...page].astro and summit/[...page].astro with redirects to /404, and disable Starlight's built-in 404 route so the shared page is used consistently across the site. * pnpm format * chore: update buildBlogPayload to handle all fields in frontmatter (#105) This PR updates the `sync:mdx` script to handle all frontmatter fields in blog post articles: `tags`, `articleBio`, `featureImage` + alt text, `thumbnailImage` +alt text --------- Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> * fix: remove unused value from interface definition (#139) * feat: PdfEmbed component (#132) * pdf embed * add download attribute * fallback styling * fix(lockfile): remove duplicate overrides keys from pnpm-lock.yaml Merge introduced duplicate @strapi/design-system and @strapi/icons keys in the overrides section, breaking frozen-lockfile installs. * Delete src/content/foundation-pages/test-page.mdx * Delete src/content/es/foundation-pages/test-page.mdx * format * revie and merge * format * fix(cms): target preview aside by nth-child instead of last-of-type (#142) :last-of-type was hiding the wrong aside after a Strapi UI update moved the publish panel. Switch to :nth-child(2) to reliably target only the preview aside. * fix(lockfile): update cms/pnpm-lock.yaml to include pnpm.overrides (#144) The @strapi/design-system and @strapi/icons overrides added to cms/package.json were missing from cms/pnpm-lock.yaml, causing ERR_PNPM_LOCKFILE_CONFIG_MISMATCH during the staging rebuild CI step. * feat: add localization support for foundation-blog-posts (#143) - add localization support for foundation-blog-posts - remove `language` field from Strapi Admin ui for Blog post (redundant, we already use locale)- - add back `afterUpdate` hooks in lifecycles (after switching off drafts for content, the lifecycles have changed they behaviour) * chore: Create list pages for Summit talks and speakers (#136) * chore: add base logic for summit talks list page * chore: add base HTML structure to summit talks page * chore: create Summit Speakers list page * add Spanish summit list pages * add comments * refactor list pages * style(summit): remove redundant .ts extensions from imports * apply changes as per review request --------- Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> * ci: trigger sync on navigation changes and run sync:all jm/intorg-493-syncall (#138) * ci: trigger sync on navigation changes and run sync:all Navigation changes now trigger the sync job, same as MDX content. Switched to sync:all to run both syncs together, and renamed the job to match. * ci: set navigation_changed in all fallback sync paths * feat: added locale awareness to content collections (#134) * foundation-page: sync * foundation-page: sync * chore: added nested grant pages (#153) chore: added nested grant pages * fix: alt text not syncing from MDX frontmatter to Strapi, and inline JSX images breaking in CKEditor. (#141) * image normalisation, alt text fixes * handle conflicts * format * fix set usage and revert to POST * use correct image * feat: add LanguageSwitcher component (#154) * feat: add LanguageSwitcher component * chore: refactor basePath logic * refactor(i18n): centralize home slug usage in route helpers * refactor(i18n): memoize translation map with top-level data module * refactor(i18n): move route context into Astro.locals via middleware Introduces routeContextFromPathname utility and wires it through middleware so layouts and components read routeLocale/currentSlug/currentBasePath from Astro.locals instead of receiving them as explicit props. * chore: formatting --------- Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> * fix(cms): ensure uploads folder exists before Strapi registers (#155) The local upload provider needs public/uploads to exist before the upload plugin registers. Create it eagerly in server config to avoid startup failures on fresh clones. * feat(parser): implement paragraph merging in parseMdxToBlocks (#156) INTORG-514 Consecutive markdown nodes (paragraphs, headings, lists, tables) are now accumulated into a single blocks.paragraph, split only when a JSX component interrupts or EOF is reached. A blog post with 80 markdown nodes now produces 1 block instead of 80. Also fixes missing `@` path alias in cms/vitest.config.ts that was causing mdxTransformer.test.ts to fail (introduced in #133). * chore(assets): add original upload images to public/uploads (#157) * Feat: create summit detail pages (#146) This PR creates detail pages for individual summit session and summit speaker pages - English and Spanish pages: `/summit/[year]/talk/{talk-title-slug}` `/es/summit/[year]/talk/{talk-title-slug}` `/summit/[year]/speaker/{speaker-name-slug}` `/es/summit/[year]/speaker/{speaker-name-slug}` This PR focuses on the main pages logic only. It does NOT handle components, summit JSON data extraction, or translation logic; these will be addressed in follow-up PRs. * feat(blocks): add VideoEmbed component and Strapi schema (#148) * feat(blocks): add VideoEmbed component and Strapi schema INTORG-513 INTORG-515 - Install @astro-community/astro-embed-youtube and astro-embed-vimeo - Create VideoEmbed.astro (facade pattern: thumbnail on load, iframe on click) - Create VideoEmbedBlock.astro for DynamicZone preview rendering - Add shared detectVideoProvider utility (YouTube + Vimeo URL detection) - Add blocks.video-embed Strapi component schema (url + title fields) - Register in foundation-page content-type and pageLifecycle populate - Add video-embed serializer for Strapi-to-MDX export - Wire into DynamicZone.astro and [...page].astro components map * feat(parser): register VideoEmbed handler in parseMdxToBlocks (#158) INTORG-516 - Add VideoEmbedBlock type to types.blocks.ts and ParsedBlock union - Create videoEmbedHandler.ts: extracts url + title props, emits blocks.video-embed - Register handler via side-effect import in config.ts * feat(blog): add components map to blog page rendering (#159) INTORG-521 - Add VideoEmbed to FoundationContentPage.astro components map (replaces the old [...page].astro components map after staging refactor) - Add Paragraph + VideoEmbed components map to FoundationBlogPostPage.astro (blog posts can now render <Paragraph> and <VideoEmbed> from MDX) * feat(summit): add VideoEmbed to summit page components map INTORG-521 Summit pages can now render <VideoEmbed> from MDX, matching foundation pages and blog posts. * format * content(blog): replace EMBEDDED VIDEO links with VideoEmbed components (#160) INTORG-517 Replace 6 broken [EMBEDDED VIDEO: ...](url) markdown links across 5 blog posts with <VideoEmbed url="..." title="..." /> JSX components. Affected posts: - digital-financial-inclusion-igniting-sustainable-development-goals - harnessing-future-insights-global-technology-retreat-digital-trust-and-inclusion - exploring-community-based-identification-systems (2 videos) - why-higher-education-institutions-worldwide-should-embrace-hackathons - interledger-hackathon-intro-open-payments-live-qa-ilf-experts * feat(cms): use route path to dictate page folder structure in lifecycle (#124) * feat(cms): single full path slug for foundation and summit pages - Drop path field; pathSlug is required string (multi-segment URLs)\n- Admin: Full Path Slug label, help text, 12-col layout\n- pageLifecycle: nested MDX paths from slug; legacy path delete; omit path in frontmatter\n- Sync payloads no longer send path * fix(cms): walk nested files when removing localizes from locale MDX * refactor(cms): always use recursive scan in sync-mdx Single readdir pass from collection root; infer locale from path segments. * chore(cms): add vitest alias @ -> src for CMS tests * refactor(site): pathSlug-only page routes and frontmatter - Drop optional path from page schemas; simplify static-paths\n- ES about page: sobre-nosotros slug + localizes link * docs: full path slug and nested foundation/summit MDX layout * fix(cms): handle nullable pathSlug in page lifecycle afterDelete * docs(cms): clarify pathSlug field descriptions per content type * pnpm format * chore: Refactor localized page nesting * feat(cms): add sync:delete-all script and fix Strapi 5 pagination - Add sync-delete-all.ts utility to bulk delete Strapi entries - Fix getAllEntries to use proper pagination (Strapi 5 ignores limit=-1) - Normalize API URL construction to handle trailing slashes * format * fix(cms): delete MDX at old pathSlug per updated locale * refactor(cms): drop legacy path prefix from page MDX resolution * Apply suggestion from @JoblersTune * Apply suggestion from @JoblersTune * refactor(cms): centralize default locale as defaultLang * refactor(cms): clarify Strapi params.where in page lifecycle * refactor(cms): replace module-level Map with event.state in page lifecycle beforeUpdate and afterUpdate now share oldPathSlug via event.state, which is scoped to the lifecycle event pair. This eliminates concurrent update races and potential leaks from the previous module-level Map. * improve comment * fix(cms): warn when MDX file is missing pathSlug in frontmatter The file is always written with pathSlug by the export process, so its absence indicates a corrupted or manually-edited file. Log a warning rather than silently falling back to the Strapi value. * pnpm format * fix mdx * add doc * chore(cms): document locale resolution and log source in readLocaleFromUpdateEvent * refactor(cms): trust Strapi pathSlug for beforeUpdate MDX cleanup * feat(cms): enforce unique pathSlug per locale on page types * fix(cms): scope removeLocalizesFromLocaleFiles to each locale dir * fix(cms): require --confirm for sync-delete-all destructive runs * refactor(cms): derive sync-mdx locale dirs from LOCALES * pnpm format --------- Co-authored-by: JoblersTune <sarah@interledger.org> * feat: create script to import summit data and speaker images from Sessionize (#163) Create script to import summit data and speaker images from Sessionize The script - saves summit data as json files in `/src/data/sessionize/{year}-speakers.json` and `/src/data/sessionize/{year}-talks.json` - imports speakers' profile images under `/public/img/sessionize-speakers/{year}` * feat: Create utility functions for extracting Sessionize data (#161) This PR creates utility functions for extracting Sessionize summit data from json files and making them available to components * feat(cms): migrate blog content from CKEditor to structured blocks (#162) * feat(cms): change blog content field from CKEditor to dynamiczone INTORG-518 Change the blog post `content` field from `type: "customField"` / `customField: "plugin::ckeditor5.CKEditor"` to `type: "dynamiczone"` with the same component list as foundation pages. This allows Strapi to accept block arrays instead of a plain string. Requires Strapi restart to take effect. * feat(sync): wire parseMdxToBlocks into buildBlogPayload INTORG-519 - Add ParserContext parameter to buildBlogPayload - When provided, parse MDX body into structured blocks via parseMdxToBlocks instead of sending raw markdown string - Wire ParserContext in config.ts for foundation-blog-posts (same pattern as buildParsedPagePayload: resolveRelation + resolveMediaUpload) - Parser errors include file pathSlug for context * feat(cms): update blogLifecycle to serialise blocks on save (#164) * feat(cms): change blog content field from CKEditor to dynamiczone INTORG-518 Change the blog post `content` field from `type: "customField"` / `customField: "plugin::ckeditor5.CKEditor"` to `type: "dynamiczone"` with the same component list as foundation pages. This allows Strapi to accept block arrays instead of a plain string. Requires Strapi restart to take effect. * feat(sync): wire parseMdxToBlocks into buildBlogPayload INTORG-519 - Add ParserContext parameter to buildBlogPayload - When provided, parse MDX body into structured blocks via parseMdxToBlocks instead of sending raw markdown string - Wire ParserContext in config.ts for foundation-blog-posts (same pattern as buildParsedPagePayload: resolveRelation + resolveMediaUpload) - Parser errors include file pathSlug for context * feat(cms): update blogLifecycle to serialise blocks on save INTORG-520 - Call serializeContent(post.content) instead of writing raw string - Re-fetch blog post with populate params for dynamiczone content (lifecycle event.result doesn't auto-populate dynamiczone on params) - Change BlogResult.content type from string to blocks array - Extract shared StrapiDocumentAPI/StrapiGlobal types to strapiTypes.ts (was duplicated across pageLifecycle, navigationLifecycle, flatContentLifecycle) * chore(cms): update generated content types after schema change Strapi regenerated types on startup to reflect the blog content field migration from CKEditor to dynamiczone. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cms): support all block types in blog lifecycle and share populate config INTORG-520 - Extract CONTENT_BLOCK_POPULATE into shared contentPopulate.ts to avoid duplicating block populate config between page and blog lifecycles - Add fetchWithPopulate to blogLifecycle.ts so dynamic zone content includes nested relations (ambassador photos, pdf files, etc.) - Call serializeContent() for block arrays when generating blog MDX - Blog lifecycle now handles all block types, not just paragraph + video-embed * docs(decisions): add ADR-001 for content collection path handling (#165) * docs(decisions): add ADR-001 for content collection path handling Introduces Architecture Decision Records and documents the convention for how MDX files are organised under Astro content collections, including the EN/ES directory mirroring strategy. Resolves INTORG-546 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * forma --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: add embedded video recordings on Summit Talk pages (#167) * run syns:sessionize script to update recordingUrl links * Add summit recording videos on pages using VideoEmbed component * fix: add missing component renderers (#166) * add missing component renderers * remove unused comps * refactor(cms): split populate config into page and blog variants PAGE_CONTENT_POPULATE includes all block types (cards-grid, carousel, etc.). BLOG_CONTENT_POPULATE includes only blog-relevant blocks (paragraph, ambassador, blockquote, callout-text, pdf-embed, video-embed). Keeps populate params in sync with the content-type schema component lists. * remove unused compos * fix: address PR #166 review comments - Align summit-page dynamic-zone components with foundation-page - Remove unused imports from FoundationBlogPostPage - Simplify blog components map to Paragraph + VideoEmbed INTORG-535 * add missing imports to SummitContentPage --------- Co-authored-by: Anca Matei <98110730+Anca2022@users.noreply.github.com> * feat: Create / Refine the Summit data Astro components (#170) This PR creates and refines all components required to render speaker and session data. It intentionally does not focus on CSS, prioritizing component structure instead * feat(blog): migrate all 92 blog posts to Paragraph-wrapped component … (#168) * add missing component renderers * feat(blog): migrate all 92 blog posts to Paragraph-wrapped component format Parse each blog post's raw markdown body through parseMdxToBlocks → serializeContent to produce <Paragraph>-wrapped MDX, matching the foundation page format. 87 plain-markdown posts get a single <Paragraph> wrapper; 5 VideoEmbed posts split into Paragraph + VideoEmbed + Paragraph blocks. Synced to Strapi with 0 errors. Includes the migration script (cms/scripts/migrate-blog-to-components.ts) for reproducibility. INTORG-524 * format * refactor(cms): add index signature to StrapiBlockBase, remove cast Add [key: string]: unknown to StrapiBlockBase so ParsedBlock[] satisfies serializeContent's parameter type without a cast. INTORG-524 * fix(cms): preserve content byte-for-byte in paragraph round-trip The paragraph handler was re-serializing children via mdast-util-to-markdown, which decoded HTML entities (& → &) and escaped brackets ([ → \[). Now passes sourceText through ParserContext so the handler can slice raw content from AST positions instead of re-serializing from the AST. INTORG-524 * feat(cms): hard-fail on nested JSX inside Paragraph blocks (#169) * feat(blog): migrate all 92 blog posts to Paragraph-wrapped component format Parse each blog post's raw markdown body through parseMdxToBlocks → serializeContent to produce <Paragraph>-wrapped MDX, matching the foundation page format. 87 plain-markdown posts get a single <Paragraph> wrapper; 5 VideoEmbed posts split into Paragraph + VideoEmbed + Paragraph blocks. Synced to Strapi with 0 errors. Includes the migration script (cms/scripts/migrate-blog-to-components.ts) for reproducibility. INTORG-524 * format * feat(cms): hard-fail on nested JSX inside Paragraph blocks Import guard: paragraphHandler.ts walks <Paragraph> children before childrenToMarkdown runs. If any custom JSX component (capital-letter name) is found nested inside, throws MdxParserError with NESTED_JSX code. HTML elements like <br> and <span> are allowed. Export guard: Koa middleware in src/index.ts intercepts content-manager PUT/POST requests and validates paragraph content via shared contentValidation.ts. Returns a 400 with a descriptive error message visible in the Strapi admin UI — authors can't save until they fix the nesting. Covers blog posts, foundation pages, and summit pages. INTORG-535 * lint, format * fix: restore blog posts to staging state after rebase The migration commit was re-applied during rebase on already-migrated files, causing duplicate <Paragraph> wrappers. Restores all blog posts to the correct state from staging. * fix(cms): increase SEO meta description character limit (#174) fix(cms): increase SEO meta description character limit to 300 The previous 160-character limit was too restrictive for content editors. Bumped to 300 to allow longer descriptions while still staying within commonly recommended SEO ranges. Fixes INTORG-502 * feat: add /.well-known/security.txt (#175) Adds a security.txt file per RFC 9116 with contact info for responsible disclosure. Fixes INTORG-525 * docs: add Summit Data (Sessionize Integration) section to README (#176) * feat(analytics): add Umami event tracking to remaining components (#173) * feat(analytics): add Umami event tracking to remaining components Add data-umami-event attributes to CTA banners, Lander header/footer, blog listing titles, pagination, cross-blog nav, and video embed fallback links. Event names follow the established taxonomy from v4 and the production Umami dashboard. Closes INTORG-360 * feat(analytics): add Umami tracking to CommunityLinks components Add data-umami-event attributes to all links in CommunityLinksFoundation and CommunityLinksDevelopers components. * chore: add analytics for summit data pages (#179) * chore: add analytics for summit data pages * refactor: move Pagination component into shared directory * feat: handle translations for summit data (#171) This PR adds translation support for dynamic Sessionize content (talks and speakers): - Populate translationMap with Sessionize data — ensures the LanguageSwitcher correctly navigates between en and es pages for all summit talks and speakers - Fallback to En — when no Spanish content is found, the pages fall back to English content - update README with info on Adding support for a new language * feat(cms): update Strapi to v5.41.1 (#180) * feat(cms): update Strapi to v5.41.1 and migrate entityService to Document API INTORG-533 Migrate ensureLocales() from deprecated strapi.entityService to strapi.documents() API (enforced in v5.40.0). Bump better-sqlite3 to 12.8.0. All tests pass, sync scripts verified. * lockfiless * sync lockfile * comments * chore: simplify the Strapi SEO component (#177) This PR simplifies the Strapi SEO experience for editors by removing fields that were either unused, redundant, or likely to cause confusion. * summit-page: create home * summit-page: delete sessions * summit-page: create hackathon * foundation-page: create policy-and-advocacy * foundation-page: create team * foundation-page: create media * foundation-page: create open-standards * foundation-page: create interledger * foundation-page: create open-payments * foundation-page: create web-monetization * foundation-page: create join-network * foundation-page: create developers * foundation-page: sync * foundation-page: sync * feat: add caching policy [INTORG-359] (#140) feat: add caching policy with explicit Cache-Control headers [INTORG-359] Define Cache-Control headers in netlify.toml for all asset categories, add no-store response headers on SSR preview pages via applyPreviewNoStore(), and disable runtime caching on fetchStrapi() calls. * chore: added summit page handling (#184) * chore: updated menu links (#185) * chore: updated menu links * formatting * fix(styles): bump docs-design-system to fix h3 style leak (#178) * fix(styles): bump docs-design-system to 0.11.1 Picks up the fix for unscoped h3 highlight selectors that were leaking from Starlight pages into the main site (e.g. footer headings). Resolves INTORG-529 * fix(styles): use GitHub ref for docs-design-system until npm publish INTORG-529 * fix(styles): fix Starlight CSS layer ordering and form selector leaks Pre-declare Starlight CSS layers before Tailwind layers so starlight.reset no longer overrides Tailwind utility classes. Update docs-design-system to include scoped form selectors (label, input, ::placeholder) — prevents Starlight form styles from leaking onto non-Starlight pages like /contact. INTORG-529 * update docs-design-system * ci: will now do dryrun as part of PR checks (#181) * ci: strapi will now dry run against staging * ci: will now use the strapi-staging environment * ci: switch to RO token for dry run * fix: dry run must use read-only key * fix(cms): Astro HERO: background image + remove secondary CTA btns INTORG-572 INTORG-573 (#183) * fix(cms): remove secondary CTA buttons from hero component * fix(cms): clear deleted hero/seo fields from MDX frontmatter * feat(hero): support custom background image on hero sections * fix(styles): add list-style markers to prose content [INTORG-589] (#187) list styles * summit-page: create 2024 * summit-page: create 2023 * summit-page: create 2022 * summit-page: sync * summit-page: sync * summit-page: sync * chore: moved Sessionize speakers images from public/img/sessionize-sp… (#193) chore: moved Sessionize speakers images from public/img/sessionize-speakers to public/sessionize-speakers/img * style(prose): add visible underline to content links (#191) * style(prose): add visible underline to content links Links in prose content now show an underline by default so users can identify them as clickable. Underline fades out on hover. Consistent across default, blog, and foundation prose variants. Fixes INTORG-598 * style(prose): add link underlines to summit and developers-blog - Summit prose: add explicit underline styling for links - Developers blog: replace no-underline with visible underline, fixing the brief flash caused by conflicting hover rules Fixes INTORG-598 * feat(cms): route uploads to img/original and disable image variants (#190) * commit adding images * feat(cms): route uploads to img/original and disable image variants * pnpm format * feat(cms): add helper text for blog post tags field [INTORG-570] (#189) * feat(cms): add helper text for blog post tags field [INTORG-570] Add description to the tags component field in the Strapi admin, indicating that multiple tags can be selected via "+ Add an entry". * format * feat(cms): route uploads to img/original, seed media library from disk INTORG-594 (#192) * commit adding images * feat(cms): route uploads to img/original and disable image variants * pnpm format * feat(cms): seed upload records from disk on bootstrap * delete dup imags * feat(cms): seed public/img/ images into Strapi media library * pnpm format * delete images * delete img variants * also delete images from /img folder * rm uploads img * fix iamge check * fix sync all force * sync all script * feat(cms): brand pillar foundation pages updates INTORG-569 INTORG-568 (#186) - replace `pageType` ("Page Type") field with pillar ("Brand Pillar") field and update values * ci: pr checks are now environment aware * ci: merge was restarting wrong service * ci: added debug info to the pipeline * ci: swop out tokens with ENV prefix * ci: fail fast if not set * ci: ENV_STRAPI_URL is a var not a secret --------- Co-authored-by: Ravi Soni <soni.ravi829@gmail.com> Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Sarah Jones <sarah@interledger.org> Co-authored-by: Anca Matei <98110730+Anca2022@users.noreply.github.com> Co-authored-by: strapi <strapi@vm> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bosbaber
added a commit
that referenced
this pull request
Apr 9, 2026
…vironment (#195) * fix(ci): remove stray page-for-ambassadors (#111) remove stray page-for-ambassadors * feat(sync-mdx): add Paragraph component handler for MDX import jm/intorg-457-paragraph-component (#102) * add Paragraph to mdx files * fix(cms): delete orphaned localizations before recreating to preserve document links * fix(cms): use js-yaml v4 custom engine for single-quoted YAML frontmatter * feat(cms): add Paragraph block handler for sync-mdx parser * feat: render paragraph blocks as <Paragraph> JSX component * pnpm format * fix(sync-mdx): preserve dash bullet list marker on paragraph import * fix(sync-mdx): fix bullet lists handling in component handlers and add new tests (#108) * add Paragraph to mdx files * feat(cms): add Paragraph block handler for sync-mdx parser * pnpm format * fix bullet list handling, refactor * add and cleanup tests * format --------- Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> * fix(ci): refresh cms lockfile for js-yaml (#113) * feat(404): add custom 404 page for static hosting jm/intorg-484-404page (#114) * feat(404): add custom 404 page for static hosting * pnpm format * refactor(utils): convert create-excerpt to TypeScript - jon/intorg-445 (#115) refactor(utils): convert create-excerpt to TypeScript * ci(lint): add build job to lint workflow jon/intorg-405 (#117) ci(lint): add build job to lint workflow * feat(seo): add per-page meta title, description, image, and canonical… jon/intorg-446 (#116) * feat(seo): add per-page meta title, description, image, and canonical URL * pnpm format * chore(cms): update Strapi dependencies [INTORG-334] (#112) * feat: tailwind setup (#104) * refactor: modular CSS architecture with Tailwind v4 theme tokens - Decompose monolithic tailwind.css and pages.css into focused, layer-aware files - Add src/styles/theme.css with @theme tokens (typography, spacing, colors, animations) - Add src/styles/base/ for reset, typography (@font-face), and runtime CSS variables - Add src/styles/components/ for prose variants (default, blog, foundation, summit) and navigation - Move design tokens out of tailwind.config.mjs into @theme (removes duplication) - Rename [data-category] to [data-pillar] theming system - Standardise variable namespaces: --step-* → --text-step-*, --space-* → --spacing-space-* - Scope Starlight docs variables to :where(.sl-container) to prevent global leakage - Replace inline Tailwind arbitrary-variant classes with data-prose, data-prose-summit, data-nav-links attributes - Delete src/styles/pages.css (content redistributed into new modular files) * fix: update remaining --space-* references to --spacing-space-* AmbassadorGrid, SummitHeader, and FoundationHeader were still using the old --space-s variable name which no longer exists after the CSS variable namespace rename. * cleanup * pillar * fix schema * cleanup * review * Address PR feedback and prepare for staging merge * revert mdxTransformer * Delete cms/scripts/sync-mdx/README.md * ci: any change to the cms folder should trigger a rebuild (#118) * chore: update Astro dependencies [INTORG-333] (#119) * chore(cms): update @strapi/strapi 5.31.3 → 5.38.0, remove dead overrides [INTORG-334] - Bump @strapi/strapi from 5.31.3 to 5.38.0 (latest stable) - Remove inert pnpm.overrides block from cms/package.json — pnpm ignores overrides in workspace packages; only root overrides apply - All three plugins (@_sh/strapi-plugin-ckeditor, @ckeditor/strapi-plugin-ckeditor, @notum-cz/strapi-plugin-record-locking) accept @strapi/strapi ^5.0.0 * foundation-page: sync (2 created) * ambassador: create caroline-sinders * fix(cms): bump @_sh/strapi-plugin-ckeditor to ^7.1.0 The v6 plugin bundles @strapi/design-system 2.0.0-rc.18 which conflicts with Strapi 5.38.0's design-system 2.2.0, causing a styled-components crash in the admin panel. v7.1.0 uses design-system 2.1.2 which is compatible. * foundation-page: update test-page * remove test-page fixtures from content * cleanup, auto generated types * lockfile * foundation-page: sync (2 created) * ambassador: create caroline-sinders * foundation-page: update test-page * chore: upgrade to Astro 6, Node 22, and bump dependencies INTORG-333 Upgrade the Astro site from v5 to v6 and move from Node 20 (lts/iron) to Node 22 (lts/jod). Remove unused @astrojs/node adapter. Bump all major dependencies: @astrojs/mdx 5, @astrojs/netlify 7, @astrojs/starlight 0.38, Tailwind 4.2, Zod 4, marked 17, and eslint/typescript-eslint tooling. Update CI workflows to Node 22. Build, lint, all tests, and visual QA pass with no apparent regressions. * cleanup * cleanup * chore(cms): upgrade Strapi to 5.39.0 * docs: document dual lockfile setup for root and cms * ci(lint): fix build job to use Node 22 (required by Astro 6) * chore: bump deps — starlight-links-validator, better-sqlite3, @types/node, vitest * chore: pin pnpm to v10.27.0 across repo and CI workflows (#120) * chore: pin pnpm to v10.27.0 across repo and CI workflows * fix(ci): remove explicit pnpm version from workflows — read from packageManager field * ci: better file change detection to trigger build (#121) * ci: will now use change api to detect changes * ci: make sure we use pnpm 10.27.0 * Update .github/workflows/staging-merge.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update .github/workflows/staging-merge.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * ci: fixed reference issues --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: align i18n routes and rename slug to pathSlug (#107) * fix: align i18n routes and rename slug to pathSlug * chore(deps): add better-sqlite3 to onlyBuiltDependencies and pin conflicting deps with overrides * ci: pipeline should source basrc for nvm to work (#126) * ci: explicit export of NVM_DIR (#127) * ci: clean node modules before rebuild (#128) * ci: force clean build (#129) * ci: playground merge pipeline cleanup fix (#130) * chore: store Sessionize data as JSON files (#131) * feat: add Netlify-backed contact form (#87) * feat(contact): add contact us page * pnpm format * chore: exclude preview pages from seo (#135) exclude preview from seo * feat(cms): cleanup strapi admin UI INTORG-481 (#106) * fix(cms): disable draft and publish on all content types * feat(cms): configure edit view layouts for ambassador and SEO * feat(cms): customize admin panel styles and navigation * pnpm format * feat(cms): improve admin field labels and edit view layouts * feat(cms): add labels and full-width layout for ambassador, blockquote, callout-text * fix(cms): always apply field labels, not only when Strapi default * fix page title too * update labels * hide preview button * feat(cms): add help text for Directory Structure field * fix - hide preview button * simplify hiding open entity * add mutable observable to doc * stricter ID check in title * refactor(404): reuse shared 404 page instead of inline not-found sect… (#137) * refactor(404): reuse shared 404 page instead of inline not-found sections Replace per-page inline 404 markup in [...page].astro and summit/[...page].astro with redirects to /404, and disable Starlight's built-in 404 route so the shared page is used consistently across the site. * pnpm format * chore: update buildBlogPayload to handle all fields in frontmatter (#105) This PR updates the `sync:mdx` script to handle all frontmatter fields in blog post articles: `tags`, `articleBio`, `featureImage` + alt text, `thumbnailImage` +alt text --------- Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> * fix: remove unused value from interface definition (#139) * feat: PdfEmbed component (#132) * pdf embed * add download attribute * fallback styling * fix(lockfile): remove duplicate overrides keys from pnpm-lock.yaml Merge introduced duplicate @strapi/design-system and @strapi/icons keys in the overrides section, breaking frozen-lockfile installs. * Delete src/content/foundation-pages/test-page.mdx * Delete src/content/es/foundation-pages/test-page.mdx * format * revie and merge * format * fix(cms): target preview aside by nth-child instead of last-of-type (#142) :last-of-type was hiding the wrong aside after a Strapi UI update moved the publish panel. Switch to :nth-child(2) to reliably target only the preview aside. * fix(lockfile): update cms/pnpm-lock.yaml to include pnpm.overrides (#144) The @strapi/design-system and @strapi/icons overrides added to cms/package.json were missing from cms/pnpm-lock.yaml, causing ERR_PNPM_LOCKFILE_CONFIG_MISMATCH during the staging rebuild CI step. * feat: add localization support for foundation-blog-posts (#143) - add localization support for foundation-blog-posts - remove `language` field from Strapi Admin ui for Blog post (redundant, we already use locale)- - add back `afterUpdate` hooks in lifecycles (after switching off drafts for content, the lifecycles have changed they behaviour) * chore: Create list pages for Summit talks and speakers (#136) * chore: add base logic for summit talks list page * chore: add base HTML structure to summit talks page * chore: create Summit Speakers list page * add Spanish summit list pages * add comments * refactor list pages * style(summit): remove redundant .ts extensions from imports * apply changes as per review request --------- Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> * ci: trigger sync on navigation changes and run sync:all jm/intorg-493-syncall (#138) * ci: trigger sync on navigation changes and run sync:all Navigation changes now trigger the sync job, same as MDX content. Switched to sync:all to run both syncs together, and renamed the job to match. * ci: set navigation_changed in all fallback sync paths * feat: added locale awareness to content collections (#134) * foundation-page: sync * foundation-page: sync * chore: added nested grant pages (#153) chore: added nested grant pages * fix: alt text not syncing from MDX frontmatter to Strapi, and inline JSX images breaking in CKEditor. (#141) * image normalisation, alt text fixes * handle conflicts * format * fix set usage and revert to POST * use correct image * feat: add LanguageSwitcher component (#154) * feat: add LanguageSwitcher component * chore: refactor basePath logic * refactor(i18n): centralize home slug usage in route helpers * refactor(i18n): memoize translation map with top-level data module * refactor(i18n): move route context into Astro.locals via middleware Introduces routeContextFromPathname utility and wires it through middleware so layouts and components read routeLocale/currentSlug/currentBasePath from Astro.locals instead of receiving them as explicit props. * chore: formatting --------- Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> * fix(cms): ensure uploads folder exists before Strapi registers (#155) The local upload provider needs public/uploads to exist before the upload plugin registers. Create it eagerly in server config to avoid startup failures on fresh clones. * feat(parser): implement paragraph merging in parseMdxToBlocks (#156) INTORG-514 Consecutive markdown nodes (paragraphs, headings, lists, tables) are now accumulated into a single blocks.paragraph, split only when a JSX component interrupts or EOF is reached. A blog post with 80 markdown nodes now produces 1 block instead of 80. Also fixes missing `@` path alias in cms/vitest.config.ts that was causing mdxTransformer.test.ts to fail (introduced in #133). * chore(assets): add original upload images to public/uploads (#157) * Feat: create summit detail pages (#146) This PR creates detail pages for individual summit session and summit speaker pages - English and Spanish pages: `/summit/[year]/talk/{talk-title-slug}` `/es/summit/[year]/talk/{talk-title-slug}` `/summit/[year]/speaker/{speaker-name-slug}` `/es/summit/[year]/speaker/{speaker-name-slug}` This PR focuses on the main pages logic only. It does NOT handle components, summit JSON data extraction, or translation logic; these will be addressed in follow-up PRs. * feat(blocks): add VideoEmbed component and Strapi schema (#148) * feat(blocks): add VideoEmbed component and Strapi schema INTORG-513 INTORG-515 - Install @astro-community/astro-embed-youtube and astro-embed-vimeo - Create VideoEmbed.astro (facade pattern: thumbnail on load, iframe on click) - Create VideoEmbedBlock.astro for DynamicZone preview rendering - Add shared detectVideoProvider utility (YouTube + Vimeo URL detection) - Add blocks.video-embed Strapi component schema (url + title fields) - Register in foundation-page content-type and pageLifecycle populate - Add video-embed serializer for Strapi-to-MDX export - Wire into DynamicZone.astro and [...page].astro components map * feat(parser): register VideoEmbed handler in parseMdxToBlocks (#158) INTORG-516 - Add VideoEmbedBlock type to types.blocks.ts and ParsedBlock union - Create videoEmbedHandler.ts: extracts url + title props, emits blocks.video-embed - Register handler via side-effect import in config.ts * feat(blog): add components map to blog page rendering (#159) INTORG-521 - Add VideoEmbed to FoundationContentPage.astro components map (replaces the old [...page].astro components map after staging refactor) - Add Paragraph + VideoEmbed components map to FoundationBlogPostPage.astro (blog posts can now render <Paragraph> and <VideoEmbed> from MDX) * feat(summit): add VideoEmbed to summit page components map INTORG-521 Summit pages can now render <VideoEmbed> from MDX, matching foundation pages and blog posts. * format * content(blog): replace EMBEDDED VIDEO links with VideoEmbed components (#160) INTORG-517 Replace 6 broken [EMBEDDED VIDEO: ...](url) markdown links across 5 blog posts with <VideoEmbed url="..." title="..." /> JSX components. Affected posts: - digital-financial-inclusion-igniting-sustainable-development-goals - harnessing-future-insights-global-technology-retreat-digital-trust-and-inclusion - exploring-community-based-identification-systems (2 videos) - why-higher-education-institutions-worldwide-should-embrace-hackathons - interledger-hackathon-intro-open-payments-live-qa-ilf-experts * feat(cms): use route path to dictate page folder structure in lifecycle (#124) * feat(cms): single full path slug for foundation and summit pages - Drop path field; pathSlug is required string (multi-segment URLs)\n- Admin: Full Path Slug label, help text, 12-col layout\n- pageLifecycle: nested MDX paths from slug; legacy path delete; omit path in frontmatter\n- Sync payloads no longer send path * fix(cms): walk nested files when removing localizes from locale MDX * refactor(cms): always use recursive scan in sync-mdx Single readdir pass from collection root; infer locale from path segments. * chore(cms): add vitest alias @ -> src for CMS tests * refactor(site): pathSlug-only page routes and frontmatter - Drop optional path from page schemas; simplify static-paths\n- ES about page: sobre-nosotros slug + localizes link * docs: full path slug and nested foundation/summit MDX layout * fix(cms): handle nullable pathSlug in page lifecycle afterDelete * docs(cms): clarify pathSlug field descriptions per content type * pnpm format * chore: Refactor localized page nesting * feat(cms): add sync:delete-all script and fix Strapi 5 pagination - Add sync-delete-all.ts utility to bulk delete Strapi entries - Fix getAllEntries to use proper pagination (Strapi 5 ignores limit=-1) - Normalize API URL construction to handle trailing slashes * format * fix(cms): delete MDX at old pathSlug per updated locale * refactor(cms): drop legacy path prefix from page MDX resolution * Apply suggestion from @JoblersTune * Apply suggestion from @JoblersTune * refactor(cms): centralize default locale as defaultLang * refactor(cms): clarify Strapi params.where in page lifecycle * refactor(cms): replace module-level Map with event.state in page lifecycle beforeUpdate and afterUpdate now share oldPathSlug via event.state, which is scoped to the lifecycle event pair. This eliminates concurrent update races and potential leaks from the previous module-level Map. * improve comment * fix(cms): warn when MDX file is missing pathSlug in frontmatter The file is always written with pathSlug by the export process, so its absence indicates a corrupted or manually-edited file. Log a warning rather than silently falling back to the Strapi value. * pnpm format * fix mdx * add doc * chore(cms): document locale resolution and log source in readLocaleFromUpdateEvent * refactor(cms): trust Strapi pathSlug for beforeUpdate MDX cleanup * feat(cms): enforce unique pathSlug per locale on page types * fix(cms): scope removeLocalizesFromLocaleFiles to each locale dir * fix(cms): require --confirm for sync-delete-all destructive runs * refactor(cms): derive sync-mdx locale dirs from LOCALES * pnpm format --------- Co-authored-by: JoblersTune <sarah@interledger.org> * feat: create script to import summit data and speaker images from Sessionize (#163) Create script to import summit data and speaker images from Sessionize The script - saves summit data as json files in `/src/data/sessionize/{year}-speakers.json` and `/src/data/sessionize/{year}-talks.json` - imports speakers' profile images under `/public/img/sessionize-speakers/{year}` * feat: Create utility functions for extracting Sessionize data (#161) This PR creates utility functions for extracting Sessionize summit data from json files and making them available to components * feat(cms): migrate blog content from CKEditor to structured blocks (#162) * feat(cms): change blog content field from CKEditor to dynamiczone INTORG-518 Change the blog post `content` field from `type: "customField"` / `customField: "plugin::ckeditor5.CKEditor"` to `type: "dynamiczone"` with the same component list as foundation pages. This allows Strapi to accept block arrays instead of a plain string. Requires Strapi restart to take effect. * feat(sync): wire parseMdxToBlocks into buildBlogPayload INTORG-519 - Add ParserContext parameter to buildBlogPayload - When provided, parse MDX body into structured blocks via parseMdxToBlocks instead of sending raw markdown string - Wire ParserContext in config.ts for foundation-blog-posts (same pattern as buildParsedPagePayload: resolveRelation + resolveMediaUpload) - Parser errors include file pathSlug for context * feat(cms): update blogLifecycle to serialise blocks on save (#164) * feat(cms): change blog content field from CKEditor to dynamiczone INTORG-518 Change the blog post `content` field from `type: "customField"` / `customField: "plugin::ckeditor5.CKEditor"` to `type: "dynamiczone"` with the same component list as foundation pages. This allows Strapi to accept block arrays instead of a plain string. Requires Strapi restart to take effect. * feat(sync): wire parseMdxToBlocks into buildBlogPayload INTORG-519 - Add ParserContext parameter to buildBlogPayload - When provided, parse MDX body into structured blocks via parseMdxToBlocks instead of sending raw markdown string - Wire ParserContext in config.ts for foundation-blog-posts (same pattern as buildParsedPagePayload: resolveRelation + resolveMediaUpload) - Parser errors include file pathSlug for context * feat(cms): update blogLifecycle to serialise blocks on save INTORG-520 - Call serializeContent(post.content) instead of writing raw string - Re-fetch blog post with populate params for dynamiczone content (lifecycle event.result doesn't auto-populate dynamiczone on params) - Change BlogResult.content type from string to blocks array - Extract shared StrapiDocumentAPI/StrapiGlobal types to strapiTypes.ts (was duplicated across pageLifecycle, navigationLifecycle, flatContentLifecycle) * chore(cms): update generated content types after schema change Strapi regenerated types on startup to reflect the blog content field migration from CKEditor to dynamiczone. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(cms): support all block types in blog lifecycle and share populate config INTORG-520 - Extract CONTENT_BLOCK_POPULATE into shared contentPopulate.ts to avoid duplicating block populate config between page and blog lifecycles - Add fetchWithPopulate to blogLifecycle.ts so dynamic zone content includes nested relations (ambassador photos, pdf files, etc.) - Call serializeContent() for block arrays when generating blog MDX - Blog lifecycle now handles all block types, not just paragraph + video-embed * docs(decisions): add ADR-001 for content collection path handling (#165) * docs(decisions): add ADR-001 for content collection path handling Introduces Architecture Decision Records and documents the convention for how MDX files are organised under Astro content collections, including the EN/ES directory mirroring strategy. Resolves INTORG-546 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * forma --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: add embedded video recordings on Summit Talk pages (#167) * run syns:sessionize script to update recordingUrl links * Add summit recording videos on pages using VideoEmbed component * fix: add missing component renderers (#166) * add missing component renderers * remove unused comps * refactor(cms): split populate config into page and blog variants PAGE_CONTENT_POPULATE includes all block types (cards-grid, carousel, etc.). BLOG_CONTENT_POPULATE includes only blog-relevant blocks (paragraph, ambassador, blockquote, callout-text, pdf-embed, video-embed). Keeps populate params in sync with the content-type schema component lists. * remove unused compos * fix: address PR #166 review comments - Align summit-page dynamic-zone components with foundation-page - Remove unused imports from FoundationBlogPostPage - Simplify blog components map to Paragraph + VideoEmbed INTORG-535 * add missing imports to SummitContentPage --------- Co-authored-by: Anca Matei <98110730+Anca2022@users.noreply.github.com> * feat: Create / Refine the Summit data Astro components (#170) This PR creates and refines all components required to render speaker and session data. It intentionally does not focus on CSS, prioritizing component structure instead * feat(blog): migrate all 92 blog posts to Paragraph-wrapped component … (#168) * add missing component renderers * feat(blog): migrate all 92 blog posts to Paragraph-wrapped component format Parse each blog post's raw markdown body through parseMdxToBlocks → serializeContent to produce <Paragraph>-wrapped MDX, matching the foundation page format. 87 plain-markdown posts get a single <Paragraph> wrapper; 5 VideoEmbed posts split into Paragraph + VideoEmbed + Paragraph blocks. Synced to Strapi with 0 errors. Includes the migration script (cms/scripts/migrate-blog-to-components.ts) for reproducibility. INTORG-524 * format * refactor(cms): add index signature to StrapiBlockBase, remove cast Add [key: string]: unknown to StrapiBlockBase so ParsedBlock[] satisfies serializeContent's parameter type without a cast. INTORG-524 * fix(cms): preserve content byte-for-byte in paragraph round-trip The paragraph handler was re-serializing children via mdast-util-to-markdown, which decoded HTML entities (& → &) and escaped brackets ([ → \[). Now passes sourceText through ParserContext so the handler can slice raw content from AST positions instead of re-serializing from the AST. INTORG-524 * feat(cms): hard-fail on nested JSX inside Paragraph blocks (#169) * feat(blog): migrate all 92 blog posts to Paragraph-wrapped component format Parse each blog post's raw markdown body through parseMdxToBlocks → serializeContent to produce <Paragraph>-wrapped MDX, matching the foundation page format. 87 plain-markdown posts get a single <Paragraph> wrapper; 5 VideoEmbed posts split into Paragraph + VideoEmbed + Paragraph blocks. Synced to Strapi with 0 errors. Includes the migration script (cms/scripts/migrate-blog-to-components.ts) for reproducibility. INTORG-524 * format * feat(cms): hard-fail on nested JSX inside Paragraph blocks Import guard: paragraphHandler.ts walks <Paragraph> children before childrenToMarkdown runs. If any custom JSX component (capital-letter name) is found nested inside, throws MdxParserError with NESTED_JSX code. HTML elements like <br> and <span> are allowed. Export guard: Koa middleware in src/index.ts intercepts content-manager PUT/POST requests and validates paragraph content via shared contentValidation.ts. Returns a 400 with a descriptive error message visible in the Strapi admin UI — authors can't save until they fix the nesting. Covers blog posts, foundation pages, and summit pages. INTORG-535 * lint, format * fix: restore blog posts to staging state after rebase The migration commit was re-applied during rebase on already-migrated files, causing duplicate <Paragraph> wrappers. Restores all blog posts to the correct state from staging. * fix(cms): increase SEO meta description character limit (#174) fix(cms): increase SEO meta description character limit to 300 The previous 160-character limit was too restrictive for content editors. Bumped to 300 to allow longer descriptions while still staying within commonly recommended SEO ranges. Fixes INTORG-502 * feat: add /.well-known/security.txt (#175) Adds a security.txt file per RFC 9116 with contact info for responsible disclosure. Fixes INTORG-525 * docs: add Summit Data (Sessionize Integration) section to README (#176) * feat(analytics): add Umami event tracking to remaining components (#173) * feat(analytics): add Umami event tracking to remaining components Add data-umami-event attributes to CTA banners, Lander header/footer, blog listing titles, pagination, cross-blog nav, and video embed fallback links. Event names follow the established taxonomy from v4 and the production Umami dashboard. Closes INTORG-360 * feat(analytics): add Umami tracking to CommunityLinks components Add data-umami-event attributes to all links in CommunityLinksFoundation and CommunityLinksDevelopers components. * chore: add analytics for summit data pages (#179) * chore: add analytics for summit data pages * refactor: move Pagination component into shared directory * feat: handle translations for summit data (#171) This PR adds translation support for dynamic Sessionize content (talks and speakers): - Populate translationMap with Sessionize data — ensures the LanguageSwitcher correctly navigates between en and es pages for all summit talks and speakers - Fallback to En — when no Spanish content is found, the pages fall back to English content - update README with info on Adding support for a new language * feat(cms): update Strapi to v5.41.1 (#180) * feat(cms): update Strapi to v5.41.1 and migrate entityService to Document API INTORG-533 Migrate ensureLocales() from deprecated strapi.entityService to strapi.documents() API (enforced in v5.40.0). Bump better-sqlite3 to 12.8.0. All tests pass, sync scripts verified. * lockfiless * sync lockfile * comments * chore: simplify the Strapi SEO component (#177) This PR simplifies the Strapi SEO experience for editors by removing fields that were either unused, redundant, or likely to cause confusion. * summit-page: create home * summit-page: delete sessions * summit-page: create hackathon * foundation-page: create policy-and-advocacy * foundation-page: create team * foundation-page: create media * foundation-page: create open-standards * foundation-page: create interledger * foundation-page: create open-payments * foundation-page: create web-monetization * foundation-page: create join-network * foundation-page: create developers * foundation-page: sync * foundation-page: sync * feat: add caching policy [INTORG-359] (#140) feat: add caching policy with explicit Cache-Control headers [INTORG-359] Define Cache-Control headers in netlify.toml for all asset categories, add no-store response headers on SSR preview pages via applyPreviewNoStore(), and disable runtime caching on fetchStrapi() calls. * chore: added summit page handling (#184) * chore: updated menu links (#185) * chore: updated menu links * formatting * fix(styles): bump docs-design-system to fix h3 style leak (#178) * fix(styles): bump docs-design-system to 0.11.1 Picks up the fix for unscoped h3 highlight selectors that were leaking from Starlight pages into the main site (e.g. footer headings). Resolves INTORG-529 * fix(styles): use GitHub ref for docs-design-system until npm publish INTORG-529 * fix(styles): fix Starlight CSS layer ordering and form selector leaks Pre-declare Starlight CSS layers before Tailwind layers so starlight.reset no longer overrides Tailwind utility classes. Update docs-design-system to include scoped form selectors (label, input, ::placeholder) — prevents Starlight form styles from leaking onto non-Starlight pages like /contact. INTORG-529 * update docs-design-system * ci: will now do dryrun as part of PR checks (#181) * ci: strapi will now dry run against staging * ci: will now use the strapi-staging environment * ci: switch to RO token for dry run * fix: dry run must use read-only key * fix(cms): Astro HERO: background image + remove secondary CTA btns INTORG-572 INTORG-573 (#183) * fix(cms): remove secondary CTA buttons from hero component * fix(cms): clear deleted hero/seo fields from MDX frontmatter * feat(hero): support custom background image on hero sections * fix(styles): add list-style markers to prose content [INTORG-589] (#187) list styles * summit-page: create 2024 * summit-page: create 2023 * summit-page: create 2022 * summit-page: sync * summit-page: sync * summit-page: sync * chore: moved Sessionize speakers images from public/img/sessionize-sp… (#193) chore: moved Sessionize speakers images from public/img/sessionize-speakers to public/sessionize-speakers/img * style(prose): add visible underline to content links (#191) * style(prose): add visible underline to content links Links in prose content now show an underline by default so users can identify them as clickable. Underline fades out on hover. Consistent across default, blog, and foundation prose variants. Fixes INTORG-598 * style(prose): add link underlines to summit and developers-blog - Summit prose: add explicit underline styling for links - Developers blog: replace no-underline with visible underline, fixing the brief flash caused by conflicting hover rules Fixes INTORG-598 * feat(cms): route uploads to img/original and disable image variants (#190) * commit adding images * feat(cms): route uploads to img/original and disable image variants * pnpm format * feat(cms): add helper text for blog post tags field [INTORG-570] (#189) * feat(cms): add helper text for blog post tags field [INTORG-570] Add description to the tags component field in the Strapi admin, indicating that multiple tags can be selected via "+ Add an entry". * format * feat(cms): route uploads to img/original, seed media library from disk INTORG-594 (#192) * commit adding images * feat(cms): route uploads to img/original and disable image variants * pnpm format * feat(cms): seed upload records from disk on bootstrap * delete dup imags * feat(cms): seed public/img/ images into Strapi media library * pnpm format * delete images * delete img variants * also delete images from /img folder * rm uploads img * fix iamge check * fix sync all force * sync all script * feat(cms): brand pillar foundation pages updates INTORG-569 INTORG-568 (#186) - replace `pageType` ("Page Type") field with pillar ("Brand Pillar") field and update values * ci: pr checks are now environment aware * ci: merge was restarting wrong service * ci: added debug info to the pipeline * ci: swop out tokens with ENV prefix * ci: fail fast if not set * ci: ENV_STRAPI_URL is a var not a secret --------- Co-authored-by: Ravi Soni <soni.ravi829@gmail.com> Co-authored-by: Jonathan Matthey <mattheyj@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Sarah Jones <sarah@interledger.org> Co-authored-by: Anca Matei <98110730+Anca2022@users.noreply.github.com> Co-authored-by: strapi <strapi@vm> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Related Issue
Fixes INTORG-520
Fixes INTORG-549
Manual Test
Checks
pnpm run formatpnpm run lintPR Checklist
feat: ...,fix: ...)