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.
Hieu Nguyen
Founder & lead engineer
Published on · 6 min read
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