Skip to content

Next.js App Router internationalization (i18n)

Source URL: https://next-intl.dev/docs/getting-started/app-router

DocsGetting startedApp Router

Next.js App Router internationalization (i18n)

Section titled “Next.js App Router internationalization (i18n)”

Prefer to watch a video?

Set up next-intl

If you haven’t done so already, create a Next.js app that uses the App Router and run:

npm install next-intl

Now, we’re going to create the following file structure:

├── messages
│ ├── en.json
│ └── ...
├── next.config.ts
└── src
├── i18n
│ └── request.ts
└── app
├── layout.tsx
└── page.tsx

Let’s set up the files:

Messages represent the translations that are available per language and can be provided either locally or loaded from a remote data source.

The simplest option is to add JSON files in your local project folder:

messages/en.json

{
"HomePage": {
"title": "Hello world!"
}
}

next-intl creates a request-scoped configuration object, which you can use to provide messages and other options based on the user’s locale to Server Components.

src/i18n/request.ts

import {getRequestConfig} from 'next-intl/server';
export default getRequestConfig(async () => {
// Static for now, we'll change this later
const locale = 'en';
return {
locale,
messages: (await import(`../../messages/${locale}.json`)).default
};
});

Can I move this file somewhere else?

This file is supported out-of-the-box as ./i18n/request.ts both in the src folder as well as in the project root with the extensions .ts, .tsx, .js and .jsx.

If you prefer to move this file somewhere else, you can optionally provide a path to the plugin:

next.config.ts

const withNextIntl = createNextIntlPlugin(
// Specify a custom path here
'./somewhere/else/request.ts'
);

Now, set up the plugin which links your i18n/request.ts file to next-intl.

next.config.tsnext.config.js

next.config.ts

import {NextConfig} from 'next';
import createNextIntlPlugin from 'next-intl/plugin';
const nextConfig: NextConfig = {};
const withNextIntl = createNextIntlPlugin();
export default withNextIntl(nextConfig);

next.config.js

const createNextIntlPlugin = require('next-intl/plugin');
const withNextIntl = createNextIntlPlugin();
/** @type {import('next').NextConfig} */
const nextConfig = {};
module.exports = withNextIntl(nextConfig);

To make your request configuration available to Client Components, you can wrap the children in your root layout with NextIntlClientProvider.

app/layout.tsx

import {NextIntlClientProvider} from 'next-intl';
type Props = {
children: React.ReactNode;
};
export default async function RootLayout({children}: Props) {
return (
<html>
<body>
</body>
</html>
);
}

Use translations in your page components or anywhere else!

app/page.tsx

import {useTranslations} from 'next-intl';
export default function HomePage() {
const t = useTranslations('HomePage');
return <h1>{t('title')}</h1>;
}

In case of async components, you can use the awaitable getTranslations function instead:

app/page.tsx

import {getTranslations} from 'next-intl/server';
export default async function HomePage() {
const t = await getTranslations('HomePage');
return <h1>{t('title')}</h1>;
}

If you’d like to use unique pathnames for every language that your app supports (e.g. /en/about or example.de/über-uns), you can continue to set up a top-level [locale] segment for your app.

Set up locale-based routing→

If your app doesn’t require unique pathnames per locale, you can provide a locale to next-intl based on user preferences or other application logic.

The simplest option is to use a cookie:

src/i18n/request.ts

import {cookies} from 'next/headers';
import {getRequestConfig} from 'next-intl/server';
export default getRequestConfig(async () => {
const store = await cookies();
const locale = store.get('locale')?.value || 'en';
return {
locale
// ...
};
});

Internationalization isn’t just translating words

Section titled “Internationalization isn’t just translating words”

next-intl provides the essential foundation for internationalization in Next.js apps. It handles aspects like translations, date and number formatting, as well as internationalized routing.

However, building for a global audience spans a wider range of topics:

  • Choosing the right architecture and routing strategy for your app
  • Integrating with backend services or a CMS
  • Leveraging generative AI for content localization
  • Streamlining your development workflow with TypeScript and IDE tooling
  • Collaborating with your team using a translation management system
  • Understanding all the pieces that contribute to a truly localized experience
  • Mastering SEO for multilingual apps to reach global audiences

Video preview

Build international Next.js apps with confidence

Section titled “Build international Next.js apps with confidence”

Learn how to build delightful, multilingual apps with Next.js—from the basics to advanced patterns, all through a real-world project.

Get started→