Internationalization & Localization 🌍
Shipping worldwide means adapting language, layout, and data formats while keeping cache keys organized.
Locale Routing 🛣️
- Domain per locale:
en.example.com,fr.example.com. - Subpath:
/en,/frusing route groups or middleware. - Detect locale via
Accept-Language, cookies, or user profile. - In App Router, use
[locale]/page.tsxplus middleware to rewrite.
Translation Frameworks 📚
next-intl,next-i18next,react-intl,linguiprovide ICU message formatting.- For server components, preload dictionaries (
import locale from './messages/en.json').
Server Component Patterns 🧠
- Fetch translations in layout:
const messages = await getDictionary(locale);and pass via context. - Keep dictionaries cached/tagged by locale.
Formatting 🗓️
- Use
Intl.DateTimeFormat,Intl.NumberFormatfor currency/dates.
new Intl.NumberFormat(locale, { style: 'currency', currency }).format(value);- Centralize formatting utilities to avoid duplication.
RTL Support ↔️
- Add
dir="rtl"on<html>for Arabic/Hebrew. - Ensure CSS handles logical properties (
margin-inline-start). - Test mirrored layouts.
Locale-aware Caching 🧊
- Include locale in cache keys/tags:
fetch(url, { next: { tags: ['products', locale] } }). - CDN cache keys should vary by locale to avoid mixing languages.
Analogy: i18n is hosting a world expo—each pavilion (locale) needs signage, currency exchange, and traffic flow tuned to its visitors.
Last updated on