Skip to content
next-intl 3.0 is out! (announcement)
Docs
Environments
Metadata & Route Handlers

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:

  1. Metadata API (opens in a new tab)
  2. Metadata files (opens in a new tab)
  3. 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.

app/[locale]/layout.tsx
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 eligable for static rendering.

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.

app/[locale]/opengraph-image.tsx
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.

app/api/hello/route.tsx
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')});
}