Ask your question and get a summary of the document by referencing this page and the AI provider of your choice
If you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Translate your Next.js 15 using next-i18next website using Intlayer | Internationalization (i18n)
Who this guide is for
- Junior: Follow the exact steps and copy the code blocks. You’ll get a working multilingual app.
- Mid-level: Use the checklists and best-practice callouts to avoid common pitfalls.
- Senior: Skim the high-level structure, SEO, and automation sections; you’ll find sensible defaults and extension points.
What you’ll build
- App Router project with localized routes (e.g.,
/,/fr/...) - i18n config with locales, default locale, RTL support
- Server-side i18n initialization and a client provider
- Namespaced translations loaded on-demand
- SEO with
hreflang, localizedsitemap,robots - Middleware for locale routing
- Intlayer integration to automate translation workflows (tests, AI fill, JSON sync)
Note: next-i18next is built on top of i18next. This guide uses the i18next primitives compatible with next-i18next in the App Router, while keeping the architecture simple and production-ready. For a broader comparison, see next-i18next vs next-intl vs Intlayer.
1) Project structure
Install the next-i18next dependencies:
Start with a clear structure. Keep messages split by locale and namespace.
Checklist (mid/senior):
- Keep one JSON per namespace per locale
- Do not over-centralize messages; use small, page/feature-scoped namespaces
- Avoid importing all locales at once; load only what you need
2) Install dependencies
If you plan to use next-i18next APIs or config interop, also:
3) Core i18n config
Define locales, default locale, RTL, and helpers for localized paths/URLs.
Senior note: If you use next-i18next.config.js, keep it aligned with i18n.config.ts to avoid drift.
4) Server-side i18n initialization
Initialize i18next on the server with a dynamic backend that imports only the required locale/namespace JSON.
Mid note: Keep the namespace list short per page to limit payload. Avoid global “catch-all” bundles.
5) Client provider for React components
Wrap client components with a provider that mirrors the server config and loads only the requested namespaces.
Junior tip: You don’t need to pass all messages to the client. Start with the page’s namespaces only.
6) Localized layout and routes
Set language and direction, and pre-generate routes per locale to favor static rendering.
7) Example page with server + client usage
Translations (one JSON per namespace under src/locales/...):
Client component (loads only the required namespace):
Ensure the page/provider includes only the namespaces you need (e.g.,
about). If you use React < 19, memoize heavy formatters likeIntl.NumberFormat.
Synchronous server component embedded under a client boundary:
8) SEO: Metadata, Hreflang, Sitemap, Robots
Translating content is a means to improve reach. Wire up multilingual SEO thoroughly.
Best practices:
- Set
langanddirat the root - Add
alternates.languagesfor each locale (+x-default) - List translated URLs in
sitemap.xmland usehreflang - Exclude localized private areas (e.g.,
/fr/admin) inrobots.txt
9) Middleware for locale routing
Detect locale and redirect to a localized route if missing.
10) Performance and DX best practices
- Set html
langanddir: Done insrc/app/[locale]/layout.tsx. - Split messages by namespace: Keep bundles small (
common.json,about.json, etc.). - Minimize client payload: On pages, pass only required namespaces to the provider.
- Prefer static pages: Use
export const dynamic = 'force-static'andgenerateStaticParamsper locale. - Sync server components: Pass precomputed strings/formatting instead of async calls at render time.
- Memoize heavy operations: Especially in client code for older React versions.
- Cache and headers: Prefer static or
revalidateover dynamic rendering when feasible.
11) Testing and CI
- Add unit tests for components using
tto ensure keys exist. - Validate that each namespace has the same keys across locales.
- Surface missing keys during CI before deploy.
Intlayer will automate much of this (see next section).
12) Add Intlayer on top (automation)
Intlayer helps you keep JSON translations in sync, test for missing keys, and fill with AI when desired.
Install the intlayer dependencies:
Add package scripts:
Common flows:
pnpm i18n:testin CI to fail builds on missing keyspnpm i18n:filllocally to propose AI translations for newly added keys
You can provide CLI arguments; see the Intlayer CLI docs.
13) Troubleshooting
- Keys not found: Ensure the page/provider lists the correct namespaces and the JSON file exists under
src/locales/<locale>/<namespace>.json. - Wrong language/flash of English: Double-check locale detection in
middleware.tsand providerlng. - RTL layout issues: Verify
diris derived fromisRtl(locale)and that your CSS respects[dir="rtl"]. - SEO alternates missing: Confirm
alternates.languagesincludes all locales andx-default. - Bundles too large: Split namespaces further and avoid importing entire
localestrees on the client.
14) What’s next
- Add more locales and namespaces as features grow
- Localize error pages, emails, and API-driven content
- Extend Intlayer workflows to auto-open PRs for translation updates
If you prefer a starter, try the template: https://github.com/aymericzip/intlayer-next-i18next-template.