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-intl website using Intlayer | Internationalization (i18n)
This guide walks you through next-intl best practices in a Next.js 15 (App Router) app, and shows how to layer Intlayer on top for robust translation management and automation.
See the comparison in next-i18next vs next-intl vs Intlayer.
- For juniors: follow step-by-step sections to get a working multilingual app.
- For mid-level devs: pay attention to payload optimization and server/client separation.
- For seniors: note static generation, middleware, SEO integration, and automation hooks.
What we’ll cover:
- Setup and file structure
- Optimizing how messages are loaded
- Client and server component usage
- Metadata, sitemap, robots for SEO
- Middleware for locale routing
- Adding Intlayer on top (CLI and automation)
Set up your application using next-intl
Install the next-intl dependencies:
Copy the code to the clipboard
Copy the code to the clipboard
Setup and Loading Content
Load only the namespaces your routes need and validate locales early. Keep server components synchronous when possible and push only the required messages to the client.
Copy the code to the clipboard
Copy the code to the clipboard
Copy the code to the clipboard
Usage in a client component
Let's take an example of a client component rendering a counter.
Translations (shape reused; load them into next-intl messages as you prefer)
Copy the code to the clipboard
Copy the code to the clipboard
Client component
Copy the code to the clipboard
Don't forget to add "about" message on the page client message (only include the namespaces your client actually needs).
Usage in a server component
This UI component is a server component and can be rendered under a client component (page → client → server). Keep it synchronous by passing precomputed strings.
Copy the code to the clipboard
Notes:
- Compute
formattedCountserver-side (e.g.,const initialFormattedCount = format.number(0)). - Avoid passing functions or non-serializable objects into server components.
Copy the code to the clipboard
Copy the code to the clipboard
Copy the code to the clipboard
Middleware for locale routing
Add a middleware to handle locale detection and routing:
Copy the code to the clipboard
Best practices
- Set html
langanddir: Insrc/app/[locale]/layout.tsx, computedirviagetLocaleDirection(locale)and set<html lang={locale} dir={dir}>. - Split messages by namespace: Organize JSON per locale and namespace (e.g.,
common.json,about.json). - Minimize client payload: On pages, send only required namespaces to
NextIntlClientProvider(e.g.,pick(messages, ['common', 'about'])). - Prefer static pages: Export
export const dynamic = 'force-static'and generate static params for alllocales. - Synchronous server components: Pass precomputed strings (translated labels, formatted numbers) rather than async calls or non-serializable functions.
Implement Intlayer on top of next-intl
Install the intlayer dependencies:
Copy the code to the clipboard
Create the intlayer configuration file:
Copy the code to the clipboard
Add package.json scripts:
Copy the code to the clipboard
Notes:
intlayer fill: uses your AI provider to fill missing translations based on your configured locales.intlayer test: checks for missing/invalid translations (use it in CI).
You can configure arguments and providers; see Intlayer CLI.