Two routing strategies
| Strategy | URL pattern |
|---|---|
| Sub-path | /[locale]/page → /en/about, /ko/about |
| Domain-per-locale | en.example.com, ko.example.com |
Sub-path is simpler and SEO-friendly out of the box. Domain-per-locale is for separate marketing teams or geo-isolated infrastructure.
next-intl is the well-paved path
It handles message catalogs, locale negotiation, formatting (dates/numbers), and works in both Server and Client Components.
Make locale part of the route and load only the selected message catalog on the server. Define supported locales, a default, negotiation precedence, and a missing-key policy. Format dates, numbers, plural forms, and time zones with locale-aware APIs rather than concatenated strings. Do not collapse language and region into one value. A Korean-language user may still need another currency or date convention, so test precedence across the URL, cookie, and saved profile. Internationalization is not a dictionary lookup added at the end. Text expansion, reading direction, search indexing, canonical URLs, emails, validation messages, and user-selected locale persistence all affect the product boundary. Navigate directly to every supported locale, switch locale on a nested route, refresh, and inspect generated metadata. Test a missing key, long translation, plural count, time-zone boundary, and unsupported locale without silently falling back to mixed-language UI.