Bilingual Internationalization in Next.js with Correct hreflang
Localized routes, message dictionaries, RTL/LTR, and SEO signals for Persian–English sites without confusing duplicate content.
Ali Mortazavi
Founder, Paradise Code
Language is not only translation; it is URL and content contract
For Persian and English, decide early: subpath (`/fa`, `/en`), subdomain, or separate domain. For most content products, subpaths are simplest to operate and give a strong unified signal. Each URL should have one primary language—not a hidden mix.
Do not mix untranslated content with a translated chrome; either translate, or provide a clear redirect/fallback to an available language.
App Router and message dictionaries
Keep messages in a versionable dictionary and name keys by meaning (`cta.getStarted`), not chopped English sentences. Avoid raw string concatenation for complex phrases; word order changes across languages.
Localize dates, numbers, and currency with `Intl`. The assumption that “everyone reads like English” breaks quickly in Persian.
RTL, typography, and components
Set direction at the document/`dir` level and write spacing logically (`margin-inline`) so mirroring does not break. Audit directional icons for RTL. Your design system should see both directions in stories.
Budget Persian and Latin fonts separately; a heavy bilingual font stack hurts LCP if not subset/preloaded correctly.
Bilingual hreflang and canonicals
For each page pair, emit bidirectional self-referencing hreflang links and define `x-default` for your chosen default. Each page’s canonical should point to itself in the same language—not to its translation.
Orphan pages without a translation pair should either be noindexed or kept out of the hreflang cluster with a clear reason.
Content SEO across two languages
Raw machine translation without editing damages quality signals. Persian and English search intent are not identical; research keywords locally instead of only translating. Optimize titles and meta separately.
Keep internal links inside the same language; random language jumps confuse users and make bots unsure which version is primary.
Testing and launch
Launch checklist: routes, alternate links, RTL on forms, and bilingual screenshots in preview. Cover both versions in Search Console and treat hreflang errors like production bugs.
Good i18n is invisible—until bad i18n burns brand trust in the second market.
Frequently asked questions
How should language fallback work?
If a translation is missing, either go to the default language with a clear notice or show a “not translated yet” page—do not mix half-languages.
Is automatic translation enough for SEO?
Rarely. Money pages need human editing and intent adaptation.
Store language in a cookie or only in the URL?
For SEO, the URL must be the source of truth. Cookies/headers are fine for initial suggestions, not for hiding language from bots.
Insights
Need these ideas implemented in your product?
Paradise Code supports you from consult to full delivery.