Skip to content
ThemeStack

Why every product we ship is bilingual from day one

Retrofitting i18n touches every component you own. Building it in from the start costs one afternoon.

HN

Hieu Nguyen

Founder & lead engineer

Published on · 6 min read

Why every product we ship is bilingual from day one

Adding a second language to a finished product is one of the most expensive refactors in front-end work, because every hardcoded string is a separate edit and every layout assumption breaks somewhere.

The cost is not translation

It is the plumbing. Locale-prefixed routes. A dictionary loader that doesn't ship both languages to the browser. hreflang pairs that stay reciprocal. Date, number and currency formatting per locale. Text that grows 30% and breaks a button. None of that gets cheaper by waiting.

What we do instead

Every product starts with a [lang] segment above the root layout. In Next.js 16 that segment becomes a root parameter, so any server component can read the current locale through next/root-params without prop drilling — including deep utilities and cached functions.

Dictionaries are typed TypeScript objects, not JSON. English defines the shape; every other language is typed against it. A missing key is a build error, not a blank space a customer finds first.

Design for the longest language

Vietnamese runs longer than English for the same sentence, and German longer still. Buttons wrap. Nav items collide. Designing at the longest string means you never rebuild the header for a translation.

The SEO half

One canonical URL per locale, a reciprocal alternates.languages map, x-default, and both locales in the sitemap. Done correctly, the second language is not a duplicate-content risk — it is a second set of keywords with almost no additional work.

  • i18n
  • internationalization
  • hreflang
  • nextjs i18n
  • root params
Back to blog

Keep reading