Skip to content

feat: translated metadata, hreflang and a sitemap for every language - #102

Merged
sapatmohit merged 1 commit into
mainfrom
feat/i18n-seo
Nov 1, 2026
Merged

sapatmohit merged 1 commit into
mainfrom
feat/i18n-seo

Conversation

@sapatmohit

Copy link
Copy Markdown
Member

Part of #96: translated metadata and a locale-aware sitemap.

Fixes an existing SEO bug

The landing page's canonical was hard-coded to `/`, so `/es`, `/ja` and `/ar` all declared themselves duplicates of the English page, and search engines would drop them. Each page now uses its own language's URL as its canonical.

What changed

  • Translated metadata. Title, description and Open Graph/Twitter text come from new `meta.*` keys in the locale files. `og:locale` (`ja_JP` and so on) and `og:locale:alternate` are set per language. The keys are in the Babelize lockfile as manual, so a `babelize translate` dry run changes nothing.
  • hreflang. `alternates.languages` plus `x-default` on the landing page and on every docs page. A docs page lists only the languages it's translated into (`page.locale`).
  • `og:url` per page. Docs pages were inheriting the home page's URL, so a shared docs link previewed as the home page.
  • Sitemap. Every page in every language: 4 landing URLs + 52 docs pages × 4 languages = 212 URLs, each with `xhtml:link` alternates. The home page is written without a trailing slash, matching its canonical.
  • `pathInLocale` moves to `src/lib/locale-path.ts`, shared by the language switcher and the metadata, with tests for it and `languageAlternates`.

Verified (`next start`)

Page canonical / og:url og:title og:locale
`/` `https://elements.babelize.co\` Babelize Elements - Open Source Localization UI Components en_US
`/es` `…/es` Babelize Elements: componentes de UI de localización… es_ES
`/ar/docs/getting-started/install` `…/ar/docs/getting-started/install` التثبيت ar_AR
`/docs/components` `…/docs/components` Components en_US

Every page has `` for en, es, ja, ar and x-default.

Lint, `format:check`, typecheck, tests, `build`, `build:lib` and `test:pack` all pass.

- Title, description and Open Graph/Twitter text come from the locale files
  (meta.*), with og:locale and og:locale:alternate per language.
- Each page's canonical is its own language's URL. The landing page's was
  hard-coded to "/", so /es, /ja and /ar declared themselves duplicates of
  the English page.
- hreflang alternates (and x-default) on the landing page and every docs
  page; docs list only the languages a page is translated into.
- og:url per page: docs pages were inheriting the home page's.
- The sitemap lists every page in every language (212 URLs) with alternates.
- pathInLocale moves to src/lib/locale-path.ts, shared by the switcher and
  the metadata.
@coderabbitai

coderabbitai Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 43 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1e85e149-bc30-4e28-b2ec-3699e85ab21c
Commits

Reviewing files that changed from the base of the PR and between 77d8993 and 6f6e766.

Files selected for processing: 12
  • .babelize/local/babelize-lock.json
  • public/locales/ar.json
  • public/locales/en.json
  • public/locales/es.json
  • public/locales/ja.json
  • src/app/docs/[[...slug]]/page.tsx
  • src/app/layout.tsx
  • src/app/page.tsx
  • src/app/sitemap.ts
  • src/components/site-language-switcher.tsx
  • src/lib/locale-path.ts
  • test/locale-path.test.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@sapatmohit
sapatmohit merged commit 290b751 into main Nov 1, 2026
2 checks passed
@sapatmohit
sapatmohit deleted the feat/i18n-seo branch November 1, 2026 20:20
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.

1 participant