Статичний vs динамічний рендеринг з i18n у Next.js
Проблема з next-intl
Що відбувається? Коли ви використовуєте
useTranslations,getTranslations, або будь-який хелпер next-intl всередині Server Component в застосунку з i18n-маршрутизацією (/en/…,/fr/…), Next.js позначає весь маршрут як dynamic. ([Next Intl][1])Чому? next-intl визначає поточну локаль з заголовка, доступного лише в запиті (
x-next-intl-locale) черезheaders(). Оскількиheaders(), це динамічний API, будь-який компонент, який до нього звертається, втрачає статичну оптимізацію. ([Next Intl][1], [Next.js][2])Офіційне рішення (boilerplate)
- Експортуйте
generateStaticParamsдля кожної підтримуваної локалі. - Викликайте
setRequestLocale(locale)у кожному layout/page перед тим, як викликатиuseTranslations. ([Next Intl][1]) Це усуває залежність від заголовка, але додає додатковий код для підтримки та використовує нестабільний API у продакшені.
- Експортуйте
Як intlayer обходить проблему
Дизайн-рішення
- Тільки параметр маршруту (route-param only) – локаль береться з сегмента URL
[locale], який Next.js вже передає кожній сторінці. - Бандли на етапі компіляції – Переклади імпортуються як звичайні ES-модулі, тож вони піддаються tree-shaking і вбудовуються під час збірки.
- Без динамічних API –
useT()читає з React context, а не зheaders()абоcookies(). - Жодної додаткової конфігурації – Як тільки ваші сторінки розміщені під
app/[locale]/, Next.js автоматично генерує по одному HTML‑файлу на кожну локаль.