Bilingual metadata that fails loudly

Updated:

Also available in: فارسی

Bilingual sites fail quietly. An English page ships without a Persian alternate. A lang attribute lies. A feed mixes languages. Search indexes conflate scripts. Users adapt; SEO does not.

This site models language explicitly:

translation_key

Every post and page carries a translation_key shared across languages. English and Persian versions of the same essay use the same key. The build groups by key and requires exactly one entry per supported language for published content.

Missing translations are not warnings in production — they are build failures.

URL structure

/en/... and /fa/.... No query-parameter language switching. No cookie-guessed locale for public content. The root / is a minimal selector with hreflang alternates.

Metadata

Every rendered page includes:

  • lang and dir on <html>
  • Canonical URL
  • link rel="alternate" hreflang=... for each translation
  • Separate Atom and RSS feeds per language
  • sitemap.xml entries with alternates

Search

Per-language JSON indices at /static/search-en.json and /static/search-fa.json. Client-side normalisation unifies Persian character variants so typing is forgiving without mixing corpora.

UI strings

Navigation, form labels, and chrome strings live in a typed i18n catalogue — not scattered literals. The build checks that every key exists in both languages.

Explicit modeling costs author time. It saves the kind of embarrassment that only shows up in Search Console six months later.