Internationalization of Metadata & Route Handlers with the Next.js App Router
There are a few places in Next.js apps where you might need to apply internationalization outside of React components:
- Metadata API (opens in a new tab)
- Metadata files (opens in a new tab)
- Route Handlers (opens in a new tab)
next-intl/server
provides a set of awaitable functions that can be used in these cases.
Metadata API
To internationalize metadata like the page title, you can use functionality from next-intl
in the generateMetadata
(opens in a new tab) function that can be exported from pages and layouts.
import {getTranslations} from 'next-intl/server';
export async function generateMetadata({params: {locale}}) {
const t = await getTranslations({locale, namespace: 'Metadata'});
return {
title: t('title')
};
}
By passing an explicit locale
to the awaitable functions from next-intl
,
you can make the metadata handler eligible for static
rendering if you're using
i18n routing.
Metadata files
If you need to internationalize content within metadata files (opens in a new tab), such as an Open Graph image, you can call APIs from next-intl
in the exported function.
import {ImageResponse} from 'next/og';
import {getTranslations} from 'next-intl/server';
export default async function OpenGraphImage({params: {locale}}) {
const t = await getTranslations({locale, namespace: 'OpenGraphImage'});
return new ImageResponse(<div style={{fontSize: 128}}>{t('title')}</div>);
}
Route Handlers
You can use next-intl
in Route Handlers (opens in a new tab) too. The locale
can either be received from a search param, a layout segment or by parsing the accept-language
header of the request.
import {NextResponse} from 'next/server';
import {getTranslations} from 'next-intl/server';
export async function GET(request) {
// Example: Receive the `locale` via a search param
const {searchParams} = new URL(request.url);
const locale = searchParams.get('locale');
const t = await getTranslations({locale, namespace: 'Hello'});
return NextResponse.json({title: t('title')});
}