Skip to content

fix(registry): locale-correct JSON-LD + schema on all public pages#499

Draft
bntvllnt wants to merge 2 commits into
mainfrom
worktree-seo-schemas-fix
Draft

fix(registry): locale-correct JSON-LD + schema on all public pages#499
bntvllnt wants to merge 2 commits into
mainfrom
worktree-seo-schemas-fix

Conversation

@bntvllnt

@bntvllnt bntvllnt commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Closes #498

What

Two SEO/structured-data fixes across the registry app.

1. /fr JSON-LD URLs now track the page canonical

Page JSON-LD (BreadcrumbList, TechArticle, CollectionPage, SoftwareApplication, ItemList) built its self/breadcrumb URLs from ${SITE_URL}${pathname} with no locale segment, so every /fr/* page emitted the English URL — mismatching its own locale-prefixed canonical. Routed all page JSON-LD through canonical(path, locale) (the pattern /design already used). Removes the now-orphaned per-file SITE_URL consts. 12 pages (incl. build/[slug], which renders JSON-LD too).

2. Structured data added to 7 indexable pages

Previously carried only the global Organization+WebSite:

Page Added
/ home SoftwareApplication
/components index CollectionPage + BreadcrumbList
/vs index CollectionPage + BreadcrumbList
/vs/shadcn BreadcrumbList (siblings already had it)
/philosophy TechArticle + BreadcrumbList
/themes BreadcrumbList
/components/[slug]/playground BreadcrumbList

Redirect pages (/ai, /docs/changelog) and noindex pages (/embed, /report, /request-component) intentionally excluded.

Verification

  • tsc --noEmit: clean
  • next build: green — 2706 prerendered pages, all edited routes generated
  • ESLint (19 changed files): no issues
  • Built-HTML prove-it: /fr/docs breadcrumb → …com/fr + …com/fr/docs; /en/docs…com + …com/docs; new CollectionPage/SoftwareApplication/BreadcrumbList present on the gap pages.

Follow-up (code-review findings addressed)

Regression test and root-cause helper added in 9931e792:

  • lib/jsonld.ts — new breadcrumbTrailLd(locale, trail): a locale-aware breadcrumb constructor that resolves every crumb through canonical(path, locale) and prepends Home. All 17 breadcrumb pages migrated to it, so no page hand-builds absolute breadcrumb URLs — the locale-correct URL is the only path (closes the failure mode by construction, not just by fix).
  • lib/jsonld.test.ts — unit regression test: a non-default locale prefixes every crumb URL, the default locale prefixes none. Mutation-verified (the /fr assertions fail when the helper ignores locale).
  • e2e/jsonld-locale.spec.ts — page-level Playwright guard: /fr/families/form breadcrumb JSON-LD resolves to /fr URLs, /families/form to unprefixed. Catches a page that bypasses the helper.

Follow-up verification

  • vitest: 45/45 (incl. 3 new) · e2e: 2/2 against the dev server · tsc + next build green · eslint clean.

Page JSON-LD self/breadcrumb URLs were built from ${SITE_URL}${pathname} with
no locale segment, so every /fr/* page emitted English URLs that mismatched its
own canonical. Route all page JSON-LD through canonical(path, locale) — the
pattern /design already used — so structured-data URLs track each page's
canonical per locale.

Also add page-specific structured data to the seven indexable pages that
previously carried only the global Organization+WebSite:

- home: SoftwareApplication
- /components, /vs: CollectionPage + BreadcrumbList
- /vs/shadcn, /components/[slug]/playground: BreadcrumbList
- /philosophy: TechArticle + BreadcrumbList
- /themes: BreadcrumbList

12 pages fixed for the locale bug (incl. build/[slug]); 7 pages gain schema.
Verified in built HTML: /fr/docs breadcrumbs resolve to /fr/docs, /en to /docs.
@vllnt-pilot

vllnt-pilot Bot commented Jul 10, 2026

Copy link
Copy Markdown

ntk preview

App Status Preview
ui-registry Ready https://pr-499-ui-registry.preview.vllnt.ai
storybook Skipped (preview cell not configured)

Built from 9931e792 · public + no-index (ADR-082) · torn down on close

…ailLd

Close the root cause behind the /fr JSON-LD locale bug and lock it with tests.

- lib/jsonld.ts: add breadcrumbTrailLd(locale, trail) — a locale-aware
  breadcrumb constructor that resolves every crumb through canonical(path,
  locale) and prepends Home. Migrate all 17 breadcrumb pages to it so no page
  hand-builds absolute breadcrumb URLs; the locale-correct URL is now the only
  path, closing the failure mode by construction.
- lib/jsonld.test.ts: unit regression test — a non-default locale prefixes
  every crumb URL, the default locale prefixes none. Mutation-verified: the
  /fr assertions fail when the helper ignores locale.
- e2e/jsonld-locale.spec.ts: page-level guard — /fr/families/form breadcrumb
  JSON-LD resolves to /fr URLs, /families/form to unprefixed. Catches a page
  that bypasses the helper.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SEO: /fr JSON-LD URLs ignore locale + 7 public pages missing structured data

1 participant