Skip to content
Docs
Environments
Metadata & Route Handlers

Internationalization of Metadata & Route Handlers in Next.js 13

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)

For these cases, you can either use:

  1. The core library from next-intl, if you're using the latest stable version
  2. A set of new APIs that automatically pick up your request configuration, if you're using the Server Components beta version
import {createTranslator, createFormatter} from 'next-intl';
 
// The `locale` is received from Next.js via `params`
const locale = params.locale;
 
// You can use the core (non-React) APIs when you
// have to use next-intl outside of components.
const t = createTranslator({locale, messages});
const format = createFormatter({locale: 'en'});

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 {createTranslator} from 'next-intl';
 
export async function generateMetadata({params: {locale}}) {
  const messages = (await import(`../../../messages/${locale}.json`)).default;
  const t = createTranslator({locale, messages});
 
  return {
    title: t('LocaleLayout.title')
  };
}

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/server';
import {createTranslator} from 'next-intl';
 
export default async function Image({params: {locale}}) {
  const messages = (await import(`../../../messages/${locale}.json`)).default;
  const t = createTranslator({locale, messages, namespace: 'OpenGraph'});
 
  return new ImageResponse(<div style={{fontSize: 128}}>{t('title')}</div>);
}

Route Handlers

If you put Route Handlers (opens in a new tab) in your [locale] folder, you can use functionality from next-intl to localize the response based on the locale. Note however that you should make sure that the route is matched by your middleware config.

app/[locale]/hello/route.tsx
import {NextResponse} from 'next/server';
import {createTranslator} from 'next-intl';
 
export async function GET(request, {params: {locale}}) {
  const messages = (await import(`../../../messages/${locale}.json`)).default;
  const t = createTranslator({locale, messages, namespace: 'Hello'});
  return NextResponse.json({title: t('title')});
}