Skip to content

Component - blockquote#11

Merged
JonathanMatthey merged 39 commits intoravi/intorg-300from
rs/component-blockquote
Feb 12, 2026
Merged

Component - blockquote#11
JonathanMatthey merged 39 commits intoravi/intorg-300from
rs/component-blockquote

Conversation

@Infi-Knight
Copy link
Copy Markdown
Contributor

@Infi-Knight Infi-Knight commented Feb 9, 2026

PR Checklist

  • Linked issue added (e.g., Fixes #123)
  • I have run bun run format to ensure code is properly formatted
  • I have verified that bun run lint passes without errors
  • If blog post was added:
    • Ensure images have been optimised
    • Update dates to reflect the actual publishing date when merged (file names, folder names, and frontmatter)

Summary

Migrates the Blockquote component from Drupal v4 to the Astro/Strapi v5 architecture, following the same patterns established by the Ambassador component migration.

What's New

Strapi Block Component

  • Created blockquote block with two fields:
    • quote (text, required) - Plain text quote, automatically wrapped with curly quotes
    • source (richtext, optional) - Attribution supporting inline formatting (strong, em, links)

Astro Components

  • src/components/blockquote/Blockquote.astro - Presentation component

    • Renders quote as plain text with automatic curly quote wrapping
    • Smart quote handling: strips any existing quotes (straight/curly, single/double) before adding consistent curly quotes
    • Supports richtext source field with scoped styling for strong/em/link elements
    • Uses primary-color for the border. for per page accent based styling support see feat: page category selector and css accent variables #16
  • src/components/blocks/BlockquoteBlock.astro - Preview adapter

    • Converts source markdown to HTML for SSR preview
    • Passes quote as-is (plain text)

Preview Support

  • Added blockquote to page preview populate params
  • Blockquote renders correctly in SSR preview mode
  • Prose styling applied to preview page (matching published pages)

Implementation Details

Lifecycle Serialization

The serializeBlockquote() function in lifecycles.ts:

  • Quote passed as-is (plain text, no htmlToMarkdown needed)
  • Source processed with htmlToMarkdown() for MDX compatibility
  • Generates: <Blockquote quote="..." source="..." />

CSS Architecture

Used Option B (Astro scoped <style> with :global(), see README)) for styling richtext content:

cite :global(strong) { color: inherit; }
cite :global(em) { font-style: italic; }
Screenshot 2026-02-10 at 4 15 59 PM Screenshot 2026-02-10 at 3 44 12 PM

@Infi-Knight Infi-Knight self-assigned this Feb 9, 2026
@Infi-Knight Infi-Knight added the enhancement New feature or request label Feb 9, 2026
@Infi-Knight Infi-Knight marked this pull request as ready for review February 10, 2026 10:14
trimmedQuote.endsWith("'")
) {
trimmedQuote = trimmedQuote.slice(0, -1)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these 20 lines can be cleaned up with regex

something like
trimmedQuote = trimmedQuote.replace(/^["'"']|["'"']$/g, '');

@JonathanMatthey
Copy link
Copy Markdown
Collaborator

cant run it locally, cleared node-modules and package lock
image

@JonathanMatthey
Copy link
Copy Markdown
Collaborator

i've looked at all the blockquotes on the website, and signatures are always simple text, so i wouldnt use a rich text ckeditor in the inputs, simplify it, but it can be done as a different ticket / PR later

image image image

@JonathanMatthey
Copy link
Copy Markdown
Collaborator

works here

image

FYI

after the sync-mdx branch is merged, each component will need a serializer in order to import/export it into mdx, so that might need to be added / reviewed later

Copy link
Copy Markdown
Collaborator

@JonathanMatthey JonathanMatthey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@JonathanMatthey JonathanMatthey self-requested a review February 12, 2026 09:53
@JonathanMatthey JonathanMatthey merged commit 807227a into ravi/intorg-300 Feb 12, 2026
Infi-Knight added a commit that referenced this pull request Mar 2, 2026
* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* cohort: add "Ambassadors 2025"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2025"

* ambassador: add "Caroline Sinders"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2024"

* cohort: delete "Ambassadors 2024"

* cohort: add "Ambassadors 2025"

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: delete "test-ambassadors" (en)

* wip: ambassador and associated content

* cohort: add "alumni"

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* remove cohort

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: add "test-ambs" (en)

* page: delete "test-ambs" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* setup lifecycle and page to serialise and render ambassador

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* use ordering from strapi instead of sorting

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* fix page previews

* fix linter error

* lint and format

* format & lint

* ambassador: add "Jeremiah Lee"

* ambassador: add "Kokayi Issa"

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: delete "test-page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme with preview setup

* remove @astrojs/tailwind, fixes npm i

* Component - blockquote (#11)

Add BlockQuote as a component

* ambassador: add "Caroline Sinders"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* ambassador: unpublish "Caroline Sinders"

* ambassador: add "Caroline Sinders"

* DRY the code

* error handling in ambassador lifecycle

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* remove order from ambassador colection

* make photo mandatory for ambassador

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme, copy paths utils from main

* ambassador: add "test ambassador"

* ambassador: add "test ambassador 3"

* ambassador: unpublish "test ambassador 3"

* ambassador: add "test ambassador 3"

* ambassador: delete "test ambassador 3"

* ambassador: add "test mdx 4"

* switch to mdx for ambassadors and add import functionality

* ambassador: delete "Kokayi Issa"

* remove test data

* aria fixes

* cleanup

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* refactor

* cleanup

* ambassador: add "Stephanie Perrin"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* cleanup

* ambassador: add "Stephanie Perrin2"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* make heading jsx prop for ambassador grid

* page: add "About Us" (en)

* page: add "Grant for web" (en)

* page: add "Internet of Oppor­tunity" (en)

* page: add "Interledger 2026" (en)

* page: add "new page" (en)

* page: add "policy-and-advocacy" (en)

* update readme with future notes

* Post-merge: add ambassador/blockquote serializers + update @/ imports

- Create cms/src/serializers/blocks/ambassador.serializer.ts
- Create cms/src/serializers/blocks/ambassadors-grid.serializer.ts
- Create cms/src/serializers/blocks/blockquote.serializer.ts
- Register all three in cms/src/serializers/blocks/index.ts
- Update relative imports to @/ alias in ambassador/blockquote components
  and page-preview.astro (AmbassadorGrid, AmbassadorBlock, AmbassadorsGridBlock,
  BlockquoteBlock, Blockquote, page-preview)

* paths and autogenerated types

* lockfiles

* fix: lint — prettier format + eslint no-console in DynamicZone

* ambassador sync script with locale

* --force flag to allow sync from non main branches

* update readme, fix component inclusion in pages

* fix blockquote output

* format

* ci: use Node 20 and frozen lockfile in lint workflow

- Upgrade from EOL Node 18 to Node 20 to match local dev environment
  and avoid subtle runtime differences in Prettier's MDX formatting
- Switch to --frozen-lockfile to prevent pnpm from re-resolving
  dependencies on Linux, which could hoist the transitive prettier@3.3.3
  (from cms workspace) over the pinned root prettier@3.8.1

* fix: pin prettier@3.8.1 in cms workspace and fix pnpm override format

The cms workspace's lockfile had prettier@3.3.3 as a transitive
dependency (via prettier-plugin-packagejson). On Linux, pnpm can
hoist this into root node_modules/.bin, overriding the root
workspace's prettier@3.8.1 and causing the lint CI to fail with
formatting errors on MDX files that pass locally.

- Add pnpm.overrides.prettier = "3.8.1" to cms/package.json so the
  cms lockfile no longer resolves prettier@3.3.3
- Convert the pre-existing esbuild override from npm-style "overrides"
  to pnpm-style "pnpm.overrides" so it's actually applied by pnpm
- Regenerate cms/pnpm-lock.yaml with prettier@3.8.1 throughout

* fix: add root pnpm override to eliminate prettier@3.3.3 from lockfile

The root pnpm-lock.yaml manages cms workspace deps including
prettier-plugin-packagejson which pulls in prettier@3.3.3 as a
transitive peer dep. With pnpm hoisting, this can put prettier@3.3.3
in root node_modules/.bin on Linux, shadowing the intended @3.8.1
and causing the lint CI to fail.

Adding "pnpm.overrides.prettier = 3.8.1" in root package.json
forces the root lockfile to resolve all prettier references to 3.8.1,
eliminating the conflicting version entirely.

The root devDependency alone does not prevent prettier@3.3.3 from
appearing in the lockfile — the override is required for that.

* remove bun lockfiles

* ci: add debug step to show exact prettier diff on Linux

* cleanup

* fix locale lifecycle

* format

* refactor

* format, remove compiled file

* fix tsconfig

* fix previews and quote rendering

* format

* format

* review

* fix(scripts/README): update content type mappings to current dirs

* Update src/components/ambassadors/AmbassadorGrid.astro

Co-authored-by: Sarah Jones <sarah@interledger.org>

* rename client url to astro preview url

* fix cms types

* update preview prefix

* fix sync throwing error even on successful deletion of ambassador after sync

* remove redundant checks

* remove dead code

* cleanup

* format

---------

Co-authored-by: Sarah Jones <sarah@interledger.org>
Infi-Knight added a commit that referenced this pull request Mar 2, 2026
* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* cohort: add "Ambassadors 2025"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2025"

* ambassador: add "Caroline Sinders"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2024"

* cohort: delete "Ambassadors 2024"

* cohort: add "Ambassadors 2025"

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: delete "test-ambassadors" (en)

* wip: ambassador and associated content

* cohort: add "alumni"

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* remove cohort

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: add "test-ambs" (en)

* page: delete "test-ambs" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* setup lifecycle and page to serialise and render ambassador

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* use ordering from strapi instead of sorting

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* fix page previews

* fix linter error

* lint and format

* format & lint

* ambassador: add "Jeremiah Lee"

* ambassador: add "Kokayi Issa"

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: delete "test-page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme with preview setup

* remove @astrojs/tailwind, fixes npm i

* Component - blockquote (#11)

Add BlockQuote as a component

* ambassador: add "Caroline Sinders"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* ambassador: unpublish "Caroline Sinders"

* ambassador: add "Caroline Sinders"

* DRY the code

* error handling in ambassador lifecycle

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* remove order from ambassador colection

* make photo mandatory for ambassador

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme, copy paths utils from main

* ambassador: add "test ambassador"

* ambassador: add "test ambassador 3"

* ambassador: unpublish "test ambassador 3"

* ambassador: add "test ambassador 3"

* ambassador: delete "test ambassador 3"

* ambassador: add "test mdx 4"

* switch to mdx for ambassadors and add import functionality

* ambassador: delete "Kokayi Issa"

* remove test data

* aria fixes

* cleanup

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* refactor

* cleanup

* ambassador: add "Stephanie Perrin"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* cleanup

* ambassador: add "Stephanie Perrin2"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* make heading jsx prop for ambassador grid

* page: add "About Us" (en)

* page: add "Grant for web" (en)

* page: add "Internet of Oppor­tunity" (en)

* page: add "Interledger 2026" (en)

* page: add "new page" (en)

* page: add "policy-and-advocacy" (en)

* update readme with future notes

* Post-merge: add ambassador/blockquote serializers + update @/ imports

- Create cms/src/serializers/blocks/ambassador.serializer.ts
- Create cms/src/serializers/blocks/ambassadors-grid.serializer.ts
- Create cms/src/serializers/blocks/blockquote.serializer.ts
- Register all three in cms/src/serializers/blocks/index.ts
- Update relative imports to @/ alias in ambassador/blockquote components
  and page-preview.astro (AmbassadorGrid, AmbassadorBlock, AmbassadorsGridBlock,
  BlockquoteBlock, Blockquote, page-preview)

* paths and autogenerated types

* lockfiles

* fix: lint — prettier format + eslint no-console in DynamicZone

* ambassador sync script with locale

* --force flag to allow sync from non main branches

* update readme, fix component inclusion in pages

* fix blockquote output

* format

* ci: use Node 20 and frozen lockfile in lint workflow

- Upgrade from EOL Node 18 to Node 20 to match local dev environment
  and avoid subtle runtime differences in Prettier's MDX formatting
- Switch to --frozen-lockfile to prevent pnpm from re-resolving
  dependencies on Linux, which could hoist the transitive prettier@3.3.3
  (from cms workspace) over the pinned root prettier@3.8.1

* fix: pin prettier@3.8.1 in cms workspace and fix pnpm override format

The cms workspace's lockfile had prettier@3.3.3 as a transitive
dependency (via prettier-plugin-packagejson). On Linux, pnpm can
hoist this into root node_modules/.bin, overriding the root
workspace's prettier@3.8.1 and causing the lint CI to fail with
formatting errors on MDX files that pass locally.

- Add pnpm.overrides.prettier = "3.8.1" to cms/package.json so the
  cms lockfile no longer resolves prettier@3.3.3
- Convert the pre-existing esbuild override from npm-style "overrides"
  to pnpm-style "pnpm.overrides" so it's actually applied by pnpm
- Regenerate cms/pnpm-lock.yaml with prettier@3.8.1 throughout

* fix: add root pnpm override to eliminate prettier@3.3.3 from lockfile

The root pnpm-lock.yaml manages cms workspace deps including
prettier-plugin-packagejson which pulls in prettier@3.3.3 as a
transitive peer dep. With pnpm hoisting, this can put prettier@3.3.3
in root node_modules/.bin on Linux, shadowing the intended @3.8.1
and causing the lint CI to fail.

Adding "pnpm.overrides.prettier = 3.8.1" in root package.json
forces the root lockfile to resolve all prettier references to 3.8.1,
eliminating the conflicting version entirely.

The root devDependency alone does not prevent prettier@3.3.3 from
appearing in the lockfile — the override is required for that.

* remove bun lockfiles

* ci: add debug step to show exact prettier diff on Linux

* cleanup

* fix locale lifecycle

* format

* refactor

* format, remove compiled file

* fix tsconfig

* fix previews and quote rendering

* format

* format

* review

* fix(scripts/README): update content type mappings to current dirs

* fix tests

* format
Infi-Knight added a commit that referenced this pull request Mar 2, 2026
* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* cohort: add "Ambassadors 2025"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2025"

* ambassador: add "Caroline Sinders"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2024"

* cohort: delete "Ambassadors 2024"

* cohort: add "Ambassadors 2025"

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: delete "test-ambassadors" (en)

* wip: ambassador and associated content

* cohort: add "alumni"

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* remove cohort

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: add "test-ambs" (en)

* page: delete "test-ambs" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* setup lifecycle and page to serialise and render ambassador

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* use ordering from strapi instead of sorting

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* fix page previews

* fix linter error

* lint and format

* format & lint

* ambassador: add "Jeremiah Lee"

* ambassador: add "Kokayi Issa"

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: delete "test-page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme with preview setup

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* wip: blockquote

* update readme

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* use non-rich text for quote src, styling fixes

* wip: callout text

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* remove @astrojs/tailwind, fixes npm i

* Component - blockquote (#11)

Add BlockQuote as a component

* fix paths

* remove unused page

* cleanup

* cleanup
JoblersTune added a commit that referenced this pull request Mar 23, 2026
…kflows (#133)

* docs: trivial change to readme

* chore: trivial experimental change

* ci: CMS changes to merge will now cause strapi rebuild (#47)

* ci: trivial change to trigger cms build (#48)

* ci: better reloadign of bashrc (#49)

* ci: changed pipeline structure (#50)

* ci: merged ci scripts and triggered rebuild (#51)

* ci: use pnpm to run sync script (#52)

* ci: trivial changes to test (#53)

* ci: trigger another test (#54)

* ci: trigger another test (#55)

* fix: merge detection issue (#56)

* ci: pipeline test (#57)

* fix: add packages field to cms workspace yaml (#58)

* test: workflow changes (#59)

* chore: update pnpm lockfile

* chore: revert test changes

* fix: add packages field to cms pnpm-workspace.yaml

* test: workflow changes

* fix: should be able to do mdx sync on staging as well (#60)

* chore: update pnpm lockfile

* chore: revert test changes

* fix: add packages field to cms pnpm-workspace.yaml

* test: workflow changes

* fix: allow sync-mdx to run from staging branch

* test: trigger sync-mdx job

* ci: test mdx change (#61)

* chore: update pnpm lockfile

* chore: revert test changes

* fix: add packages field to cms pnpm-workspace.yaml

* test: workflow changes

* fix: allow sync-mdx to run from staging branch

* test: trigger sync-mdx job

* ci: test mdx change

* fix: improve pr detection (#62)

* chore: update pnpm lockfile

* chore: revert test changes

* fix: add packages field to cms pnpm-workspace.yaml

* test: workflow changes

* fix: allow sync-mdx to run from staging branch

* test: trigger sync-mdx job

* ci: test mdx change

* fix: improve PR detection to prioritize API check

* ci: tweak to test

* ci: trigger (#63)

* chore: update pnpm lockfile

* chore: revert test changes

* fix: add packages field to cms pnpm-workspace.yaml

* test: workflow changes

* fix: allow sync-mdx to run from staging branch

* test: trigger sync-mdx job

* ci: test mdx change

* fix: improve PR detection to prioritize API check

* ci: tweak to test

* ci: trigger

* fix: restrict manual workflow dispatch to staging branch only (#64)

* ci: removed NODE_VERSION override for netlify (#65)

* ci: staging preview build (#66)

* ci: removed NODE_VERSION override for netlify

* fix: convining netlify to stay in its lane

* ci: added staging server to vite (#68)

* ci: removed NODE_VERSION override for netlify

* fix: convining netlify to stay in its lane

* vite server allows

* ci: netlify config for previews (#69)

* ci: removed NODE_VERSION override for netlify

* fix: convining netlify to stay in its lane

* vite server allows

* ci: deploy branches

* ci: fixed issue with deploy previews (#70)

* ci: removed NODE_VERSION override for netlify

* fix: convining netlify to stay in its lane

* vite server allows

* ci: deploy branches

* fix: remove dev

* fix: use frozen lock file

* ci: vite config issue

* ci: pnpm should filter for website only (#71)

* ci: removed NODE_VERSION override for netlify

* fix: convining netlify to stay in its lane

* vite server allows

* ci: deploy branches

* fix: remove dev

* fix: use frozen lock file

* ci: vite config issue

* ci: pnpm should filter for website only

* fix: preview for dev (#72)

* ci: removed NODE_VERSION override for netlify

* fix: convining netlify to stay in its lane

* vite server allows

* ci: deploy branches

* fix: remove dev

* fix: use frozen lock file

* ci: vite config issue

* ci: pnpm should filter for website only

* ci: tweaks

* merge

* fix: ci typo double build (#73)

* ci: removed NODE_VERSION override for netlify

* fix: convining netlify to stay in its lane

* vite server allows

* ci: deploy branches

* fix: remove dev

* fix: use frozen lock file

* ci: vite config issue

* ci: pnpm should filter for website only

* ci: tweaks

* merge

* fix: typo

* ci: preview build debugging (#74)

* ci: removed NODE_VERSION override for netlify

* fix: convining netlify to stay in its lane

* vite server allows

* ci: deploy branches

* fix: remove dev

* fix: use frozen lock file

* ci: vite config issue

* ci: pnpm should filter for website only

* ci: tweaks

* merge

* fix: typo

* different dev

* ci: cleanup (#75)

* ci: removed NODE_VERSION override for netlify

* fix: convining netlify to stay in its lane

* vite server allows

* ci: deploy branches

* fix: remove dev

* fix: use frozen lock file

* ci: vite config issue

* ci: pnpm should filter for website only

* ci: tweaks

* merge

* fix: typo

* different dev

* cleanup

* test: trivial change to trigger pipeline (#76)

* test: added trivial change to blog (#77)

* test: trivial change to trigger pipeline

* test: added trivial change to blog

* fix: corrected the linting issue caused during testing (#78)

* chore: remove unused bun files (#67)

* test(sync-mdx): add sync-mdx test coverage jon/intorg-399 (#41)

* test(cms): add sync-mdx tests

* fix(cms): resolve ESLint errors in sync-mdx tests

Replace require() imports with ES module imports and use @ts-expect-error
instead of `as any` for intentional type errors in tests.

* update pnpm lock

* test(cms): improve mock schema and add optional fields test

Update siteSchemas mock to use async import with a realistic schema
including sections and CTAs. Add test case covering optional frontmatter
fields (description, heroImage, sections).

* test(cms): add sync-mdx test utilities

* feat: add new collection types jon/intorg-284 (#36)

* refactor: standardize content types and layout hierarchy

Content type naming:
- Rename blog-post API to foundation-blog-post
- Move src/content/blog/ to src/content/foundation-blog-posts/
- Move src/content/summit/ to src/content/summit-pages/
- Move src/content/developers/blog/ to src/content/developers-blog-posts/

Layout hierarchy:
- BaseLayout: HTML shell with slots for header/footer
- FoundationPageLayout: extends BaseLayout with Foundation nav
- SummitPageLayout: extends BaseLayout with Summit nav and dark theme
- DevelopersBlogLayout/FoundationBlogLayout: extend FoundationPageLayout

Removes duplicate layouts (SummitLayout)

* feat(sync-mdx): add foundation-blog-posts import and improve schema - jm/sync-mdx-foundationblog (#79)

* refactor: standardize content types and layout hierarchy

Content type naming:
- Rename blog-post API to foundation-blog-post
- Move src/content/blog/ to src/content/foundation-blog-posts/
- Move src/content/summit/ to src/content/summit-pages/
- Move src/content/developers/blog/ to src/content/developers-blog-posts/

Layout hierarchy:
- BaseLayout: HTML shell with slots for header/footer
- FoundationPageLayout: extends BaseLayout with Foundation nav
- SummitPageLayout: extends BaseLayout with Summit nav and dark theme
- DevelopersBlogLayout/FoundationBlogLayout: extend FoundationPageLayout

Removes duplicate layouts (SummitLayout, LanderLayout) and
hackathon-2023 page.

* feat: add engineering blog collection and schema

* feat: add prerender flag to blog page routes

* stub out developer preview - not avail on strapi

* fix(ci): update content-change detection to match synced paths

* fix(pages): restore hackathon 2023 page

* Update src/schemas/content.ts

Co-authored-by: Anca Matei <98110730+Anca2022@users.noreply.github.com>

* refactor: engineering-blog should be developers blog

* restore lander header for hackathon 2023

* fix(lander): restore header and layout

* add ogImageUrl to og-summit.png

* fix(pages): update rendering

* format

* download og summit img in public folder

* feat(sync-mdx): add foundation-blog-posts import and improve schema

- Add foundation-blog-posts to config, validation, and mdxTransformer
- Extend foundationBlogFrontmatterSchema: z.coerce.date(), authors, tags default, localizes/locale
- MDX as single source of truth for content (no preserve-existing fallback)
- Scan supports .md files in addition to .mdx

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(sync-mdx): add --force flag to bypass branch check

Co-authored-by: Cursor <cursoragent@cursor.com>

* Update cms/scripts/sync-mdx/index.ts

Co-authored-by: Anca Matei <98110730+Anca2022@users.noreply.github.com>

---------

Co-authored-by: Anca Matei <98110730+Anca2022@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: rename frontmatter variable "lang" to "locale" (#82)

rename frontmatter variable "lang" to "locale"

* chore: Strapi Foundation blog post fields / frontmatter (#80)

* update Strapi fields for Foundation blog post

* update schema for foundationBlogFrontmatterSchema

* set user friendly labels for Strapi Foundation Blog Post fields

* docs: update README (#46)

* feat(seo): add shared SeoHead and crawl controls.  jm/SEO-Baseline-Handling (#86)

Key changes:
- Added sitemap generation and excluded /blog/preview from sitemap entries.
- Updated crawl controls: robots.txt allows normal crawling but disallows /blog/preview.
- Centralized metadata in shared SeoHead usage and improved tags
- Added structured data improvements: site-level Organization and WebSite JSON-LD
- Added canonical handling for paginated blog listing pages.

* feat: strapi and astro Ambassador components and page previews (#8)

* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* cohort: add "Ambassadors 2025"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2025"

* ambassador: add "Caroline Sinders"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2024"

* cohort: delete "Ambassadors 2024"

* cohort: add "Ambassadors 2025"

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: delete "test-ambassadors" (en)

* wip: ambassador and associated content

* cohort: add "alumni"

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* remove cohort

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: add "test-ambs" (en)

* page: delete "test-ambs" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* setup lifecycle and page to serialise and render ambassador

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* use ordering from strapi instead of sorting

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* fix page previews

* fix linter error

* lint and format

* format & lint

* ambassador: add "Jeremiah Lee"

* ambassador: add "Kokayi Issa"

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: delete "test-page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme with preview setup

* remove @astrojs/tailwind, fixes npm i

* Component - blockquote (#11)

Add BlockQuote as a component

* ambassador: add "Caroline Sinders"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* ambassador: unpublish "Caroline Sinders"

* ambassador: add "Caroline Sinders"

* DRY the code

* error handling in ambassador lifecycle

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* remove order from ambassador colection

* make photo mandatory for ambassador

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme, copy paths utils from main

* ambassador: add "test ambassador"

* ambassador: add "test ambassador 3"

* ambassador: unpublish "test ambassador 3"

* ambassador: add "test ambassador 3"

* ambassador: delete "test ambassador 3"

* ambassador: add "test mdx 4"

* switch to mdx for ambassadors and add import functionality

* ambassador: delete "Kokayi Issa"

* remove test data

* aria fixes

* cleanup

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* refactor

* cleanup

* ambassador: add "Stephanie Perrin"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* cleanup

* ambassador: add "Stephanie Perrin2"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* make heading jsx prop for ambassador grid

* page: add "About Us" (en)

* page: add "Grant for web" (en)

* page: add "Internet of Oppor­tunity" (en)

* page: add "Interledger 2026" (en)

* page: add "new page" (en)

* page: add "policy-and-advocacy" (en)

* update readme with future notes

* Post-merge: add ambassador/blockquote serializers + update @/ imports

- Create cms/src/serializers/blocks/ambassador.serializer.ts
- Create cms/src/serializers/blocks/ambassadors-grid.serializer.ts
- Create cms/src/serializers/blocks/blockquote.serializer.ts
- Register all three in cms/src/serializers/blocks/index.ts
- Update relative imports to @/ alias in ambassador/blockquote components
  and page-preview.astro (AmbassadorGrid, AmbassadorBlock, AmbassadorsGridBlock,
  BlockquoteBlock, Blockquote, page-preview)

* paths and autogenerated types

* lockfiles

* fix: lint — prettier format + eslint no-console in DynamicZone

* ambassador sync script with locale

* --force flag to allow sync from non main branches

* update readme, fix component inclusion in pages

* fix blockquote output

* format

* ci: use Node 20 and frozen lockfile in lint workflow

- Upgrade from EOL Node 18 to Node 20 to match local dev environment
  and avoid subtle runtime differences in Prettier's MDX formatting
- Switch to --frozen-lockfile to prevent pnpm from re-resolving
  dependencies on Linux, which could hoist the transitive prettier@3.3.3
  (from cms workspace) over the pinned root prettier@3.8.1

* fix: pin prettier@3.8.1 in cms workspace and fix pnpm override format

The cms workspace's lockfile had prettier@3.3.3 as a transitive
dependency (via prettier-plugin-packagejson). On Linux, pnpm can
hoist this into root node_modules/.bin, overriding the root
workspace's prettier@3.8.1 and causing the lint CI to fail with
formatting errors on MDX files that pass locally.

- Add pnpm.overrides.prettier = "3.8.1" to cms/package.json so the
  cms lockfile no longer resolves prettier@3.3.3
- Convert the pre-existing esbuild override from npm-style "overrides"
  to pnpm-style "pnpm.overrides" so it's actually applied by pnpm
- Regenerate cms/pnpm-lock.yaml with prettier@3.8.1 throughout

* fix: add root pnpm override to eliminate prettier@3.3.3 from lockfile

The root pnpm-lock.yaml manages cms workspace deps including
prettier-plugin-packagejson which pulls in prettier@3.3.3 as a
transitive peer dep. With pnpm hoisting, this can put prettier@3.3.3
in root node_modules/.bin on Linux, shadowing the intended @3.8.1
and causing the lint CI to fail.

Adding "pnpm.overrides.prettier = 3.8.1" in root package.json
forces the root lockfile to resolve all prettier references to 3.8.1,
eliminating the conflicting version entirely.

The root devDependency alone does not prevent prettier@3.3.3 from
appearing in the lockfile — the override is required for that.

* remove bun lockfiles

* ci: add debug step to show exact prettier diff on Linux

* cleanup

* fix locale lifecycle

* format

* refactor

* format, remove compiled file

* fix tsconfig

* fix previews and quote rendering

* format

* format

* review

* fix(scripts/README): update content type mappings to current dirs

* Update src/components/ambassadors/AmbassadorGrid.astro

Co-authored-by: Sarah Jones <sarah@interledger.org>

* rename client url to astro preview url

* fix cms types

* update preview prefix

* fix sync throwing error even on successful deletion of ambassador after sync

* remove redundant checks

* remove dead code

* cleanup

* format

---------

Co-authored-by: Sarah Jones <sarah@interledger.org>

* chore: Foundation articles id pages (#85)

This PR matches the styles and structure of the Foundation article ID pages in v5 with the current prod website:
- pillars for accent-color and feature-gradient: header, links, quotes
- creates the ArticleBio and ArticleTags components in Astro
- separates CommunityLinks component into CommunityLinksDevelopers and CommunityLinksFoundation
- adds article bio content (image + text - in frontmatter) to Foundation blog articles that have a bio on production website

* fix: update tests  (#81)

* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* cohort: add "Ambassadors 2025"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2025"

* ambassador: add "Caroline Sinders"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2024"

* cohort: delete "Ambassadors 2024"

* cohort: add "Ambassadors 2025"

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: delete "test-ambassadors" (en)

* wip: ambassador and associated content

* cohort: add "alumni"

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* remove cohort

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: add "test-ambs" (en)

* page: delete "test-ambs" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* setup lifecycle and page to serialise and render ambassador

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* use ordering from strapi instead of sorting

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* fix page previews

* fix linter error

* lint and format

* format & lint

* ambassador: add "Jeremiah Lee"

* ambassador: add "Kokayi Issa"

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: delete "test-page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme with preview setup

* remove @astrojs/tailwind, fixes npm i

* Component - blockquote (#11)

Add BlockQuote as a component

* ambassador: add "Caroline Sinders"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* ambassador: unpublish "Caroline Sinders"

* ambassador: add "Caroline Sinders"

* DRY the code

* error handling in ambassador lifecycle

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* remove order from ambassador colection

* make photo mandatory for ambassador

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme, copy paths utils from main

* ambassador: add "test ambassador"

* ambassador: add "test ambassador 3"

* ambassador: unpublish "test ambassador 3"

* ambassador: add "test ambassador 3"

* ambassador: delete "test ambassador 3"

* ambassador: add "test mdx 4"

* switch to mdx for ambassadors and add import functionality

* ambassador: delete "Kokayi Issa"

* remove test data

* aria fixes

* cleanup

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* refactor

* cleanup

* ambassador: add "Stephanie Perrin"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* cleanup

* ambassador: add "Stephanie Perrin2"

* page: unpublish "test page" (en)

* page: add "test page" (en)

* make heading jsx prop for ambassador grid

* page: add "About Us" (en)

* page: add "Grant for web" (en)

* page: add "Internet of Oppor­tunity" (en)

* page: add "Interledger 2026" (en)

* page: add "new page" (en)

* page: add "policy-and-advocacy" (en)

* update readme with future notes

* Post-merge: add ambassador/blockquote serializers + update @/ imports

- Create cms/src/serializers/blocks/ambassador.serializer.ts
- Create cms/src/serializers/blocks/ambassadors-grid.serializer.ts
- Create cms/src/serializers/blocks/blockquote.serializer.ts
- Register all three in cms/src/serializers/blocks/index.ts
- Update relative imports to @/ alias in ambassador/blockquote components
  and page-preview.astro (AmbassadorGrid, AmbassadorBlock, AmbassadorsGridBlock,
  BlockquoteBlock, Blockquote, page-preview)

* paths and autogenerated types

* lockfiles

* fix: lint — prettier format + eslint no-console in DynamicZone

* ambassador sync script with locale

* --force flag to allow sync from non main branches

* update readme, fix component inclusion in pages

* fix blockquote output

* format

* ci: use Node 20 and frozen lockfile in lint workflow

- Upgrade from EOL Node 18 to Node 20 to match local dev environment
  and avoid subtle runtime differences in Prettier's MDX formatting
- Switch to --frozen-lockfile to prevent pnpm from re-resolving
  dependencies on Linux, which could hoist the transitive prettier@3.3.3
  (from cms workspace) over the pinned root prettier@3.8.1

* fix: pin prettier@3.8.1 in cms workspace and fix pnpm override format

The cms workspace's lockfile had prettier@3.3.3 as a transitive
dependency (via prettier-plugin-packagejson). On Linux, pnpm can
hoist this into root node_modules/.bin, overriding the root
workspace's prettier@3.8.1 and causing the lint CI to fail with
formatting errors on MDX files that pass locally.

- Add pnpm.overrides.prettier = "3.8.1" to cms/package.json so the
  cms lockfile no longer resolves prettier@3.3.3
- Convert the pre-existing esbuild override from npm-style "overrides"
  to pnpm-style "pnpm.overrides" so it's actually applied by pnpm
- Regenerate cms/pnpm-lock.yaml with prettier@3.8.1 throughout

* fix: add root pnpm override to eliminate prettier@3.3.3 from lockfile

The root pnpm-lock.yaml manages cms workspace deps including
prettier-plugin-packagejson which pulls in prettier@3.3.3 as a
transitive peer dep. With pnpm hoisting, this can put prettier@3.3.3
in root node_modules/.bin on Linux, shadowing the intended @3.8.1
and causing the lint CI to fail.

Adding "pnpm.overrides.prettier = 3.8.1" in root package.json
forces the root lockfile to resolve all prettier references to 3.8.1,
eliminating the conflicting version entirely.

The root devDependency alone does not prevent prettier@3.3.3 from
appearing in the lockfile — the override is required for that.

* remove bun lockfiles

* ci: add debug step to show exact prettier diff on Linux

* cleanup

* fix locale lifecycle

* format

* refactor

* format, remove compiled file

* fix tsconfig

* fix previews and quote rendering

* format

* format

* review

* fix(scripts/README): update content type mappings to current dirs

* fix tests

* format

* feat: Callout Text component (#17)

* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* cohort: add "Ambassadors 2025"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2025"

* ambassador: add "Caroline Sinders"

* cohort: delete "Ambassadors 2025"

* cohort: add "Ambassadors 2024"

* cohort: delete "Ambassadors 2024"

* cohort: add "Ambassadors 2025"

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: unpublish "test-ambassadors" (en)

* page: add "test-ambassadors" (en)

* page: delete "test-ambassadors" (en)

* wip: ambassador and associated content

* cohort: add "alumni"

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* remove cohort

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: unpublish "ambassadors" (en)

* page: add "ambassadors" (en)

* page: add "test-ambs" (en)

* page: delete "test-ambs" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* ambassador: unpublish "Erica Hargreave"

* ambassador: add "Erica Hargreave"

* setup lifecycle and page to serialise and render ambassador

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* use ordering from strapi instead of sorting

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* fix page previews

* fix linter error

* lint and format

* format & lint

* ambassador: add "Jeremiah Lee"

* ambassador: add "Kokayi Issa"

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: unpublish "test-page" (en)

* page: add "test-page" (en)

* page: delete "test-page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* update readme with preview setup

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* wip: blockquote

* update readme

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* use non-rich text for quote src, styling fixes

* wip: callout text

* page: unpublish "test page" (en)

* page: add "test page" (en)

* page: unpublish "test page" (en)

* page: add "test page" (en)

* remove @astrojs/tailwind, fixes npm i

* Component - blockquote (#11)

Add BlockQuote as a component

* fix paths

* remove unused page

* cleanup

* cleanup

* chore(foundation-blog): add Strapi lifecycle file to create / update / delete mdx in Astro (#94)

* foundation blog lifecycle base

* type BlogEvent

* export article as mdx file

* refactor: group author bio data into articleBios object[] and update MDX frontmatter accordingly

* handle updating / deleting blog posts

* escape single quotes in frontematter values

* tweaks

* format

* update REDME

* remove async from createBlogLifecycle to export plain lifecycle object

* add additional .join('')

* tweaks

* feat: add MDX block parser foundation for JSX imports (#93)

* mdx parser and jsx extraction setup

* update lockfile

* refactor(sync-mdx): remove redundant JSX flow element cast

* refactor(sync-mdx): deduplicate parser error construction

* chore(sync-mdx): import ambassadors before other content types

* feat(sync-mdx): Ambassador + AmbassadorGrid E2E import pipeline (#95)

* mdx parser and jsx extraction setup

* update lockfile

* import ambassador and grid

* template and comments

* chore(sync-mdx): import ambassadors before other content types

* refactor(cms): simplify sync-mdx JSX attribute extraction

* Revert "refactor(cms): simplify sync-mdx JSX attribute extraction"

This reverts commit 9007139.

* refactor(sync-mdx): remove redundant JSX flow element cast

* update and link component template

* format

---------

Co-authored-by: Jonathan Matthey <mattheyj@gmail.com>

* feat(ambassadors): localize schema and export all locales to MDX Jm/intorg 453 (#96)

* feat(ambassadors): localize all schema fields, export all locales to MDX

* refactor(cms): adopt shared flat locale MDX lifecycle

* feat(sync-mdx): add Blockquote + CalloutText import pipeline (#99)

* mdx parser and jsx extraction setup

* update lockfile

* import ambassador and grid

* template and comments

* chore(sync-mdx): import ambassadors before other content types

* refactor(cms): simplify sync-mdx JSX attribute extraction

* Revert "refactor(cms): simplify sync-mdx JSX attribute extraction"

This reverts commit 9007139.

* refactor(sync-mdx): remove redundant JSX flow element cast

* update and link component template

* format

* add import pipeline for BlockQuote and Callout Text comps

Also added fix for an edge case where if the component's
opening and closing tags were on the same line they were not being
parsed properly due to the node getting wrapped in a paragraph node

* fix inline tag parsing in mdx files

* lockfile

* refactor

* Revert "refactor"

This reverts commit 406e20f.

* feat(sync-mdx): translations pass — tests, serializer fixes, round-trips

- Fix ambassador.serializer.ts: add showLinks prop, fix photoAlt source
- Add locale context tests for blockquote, calloutText, ambassador handlers
- Add locale integration tests for mdxTransformer
- Add export serializer tests (ambassador, blockquote, callout-text)
- Add round-trip tests (blockquote, calloutText)
- Add test:serializers script to cms/package.json
- Add translations-pass.md plan doc, update jsx-imports-implementation.md

* format

---------

Co-authored-by: Jonathan Matthey <mattheyj@gmail.com>

* fix: types in serializer test file (#103)

fix tests

* chore: add llm rules jon/intorg-335 (#39)

docs(rules): update cursor and claude guidance

* fix(cms): update git sync lifecycles (#100)

* refactor(git-sync): use git status inference and unified repo paths

* fix 2 bugs - quotes and extra line

* fix(git-sync): skip git sync when running sync:navigation script

* ambassador export - single quotes

* foundation-page: create page-for-ambassadors

* pnpm format

---------

Co-authored-by: Anca Matei <98110730+Anca2022@users.noreply.github.com>

* chore: add TagFilter to blog view pages (#90)

Add TagFilter to blog view pages (/blog and /developers/blog)

* ci: slack notification to frontend team (#109)

* ci: introduction of playground environment (#110)

* ci: introduced workflow for staging

* ci: introduced playground merge

* 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)

---------

Co-authored-by: Stephan Butler <stephan@interledger.foundation>
Co-authored-by: strapi <strapi@vm>
Co-authored-by: Jonathan Matthey <mattheyj@gmail.com>
Co-authored-by: Anca Matei <98110730+Anca2022@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Ravi Soni <soni.ravi829@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants