Skip to content

Building Bilingual Sites Without Doubling Your Work

Practical patterns for BS/EN (and other bilingual) sites with Astro and Sanity — shared layouts, localized fields, and editor workflows that stay sane.

  • astro
  • sanity
  • i18n
  • cms
  • web development

Most bilingual sites start with good intentions and end as two half-maintained codebases. One language gets the polish; the other gets stale copy and broken links. After shipping several BS/EN sites for cultural and creative clients, I’ve settled on a few rules that keep the work proportional.

One site, two languages — not two sites

Treat locale as data, not as a fork of the project. Shared layouts, components, and routing conventions should be identical. Only content and a thin layer of locale-aware strings change.

With Astro, that usually means:

  • A single page tree with a [locale] segment (or a prefix strategy you stick to)
  • Shared UI components that accept translated props
  • Content collections or CMS documents keyed by locale, not duplicated folders of nearly identical Markdown

Put localization where editors live

If editors work in Sanity (or similar), localize fields there — not in the frontend repo. A typical pattern:

  • Document-level language field, or
  • Field-level localization for titles, body, SEO, and alt text
  • Shared assets (images, files) referenced once across languages

Editors then update both languages in one place. You avoid “English lives in Git, Bosnian lives in someone’s inbox.”

Don’t translate everything

Navigation labels, CTAs, and legal pages need both languages. Project metadata, image captions, and archive entries often do too. But you don’t need to localize:

  • Technical error messages that only developers see
  • Internal schema titles (unless editors work in both languages daily)
  • Every tag or taxonomy if one language is primary for discovery

Be explicit about what is required vs optional. Incomplete optional fields beat fake machine-translated filler.

Routing and SEO without drama

Decide early:

  1. URL strategy/en/... and /bs/... (or /ba/...) is clearer for clients than cookie-based switching.
  2. Default locale — pick one for / and be consistent with redirects.
  3. hreflang — emit alternate links so search engines understand the pair.
  4. Fallbacks — if a page exists in only one language, say so instead of silently showing the other.

What actually saves time

The wins aren’t clever i18n libraries. They’re:

  • One content model used twice
  • Components that never hard-code English
  • Preview links that open the correct locale
  • A short editor guide in the client’s primary language

Bilingual doesn’t have to mean double the budget. It means designing the content system so the second language is a first-class path through the same site — not a mirror you forget to dust.

Back to blog