Internationalization for Next.js that gets out of your way.

Support multiple languages, with your app code becoming simpler instead of more complex.

📣 Support for Next.js 13 and the App Router is coming →
import {useTranslations, useFormatter} from 'next-intl'; function UserDetails({user}) {  const t = useTranslations('UserDetails');  const format = useFormatter();   return (    <section>      <h2>{t('title')}</h2>      <p>{t('followers', {count: user.followers.length})}</p>      <p>{t('lastSeen', {time: format.relativeTime(user.lastSeen)})</p>      <Image alt={t('portrait', {username: user.name})} src={user.portrait} />    </section>  );}

Minimalistic, yet complete

Internationalization (i18n) is an essential part of the user experience, therefore next‑intl gives you everything you need to get language subtleties right and has always got your back whenever you need to fine-tune a translation.
{  "UserDetails": {    "title": "User details",    "followers": "{count, plural,                    =0 {No followers yet}                    =1 {One follower}                    other {# followers}                  }",

ICU message syntax

Localize your messages with interpolation, plurals, ordinal pluralization, enum-based label selection and rich text.

// "Feb 28, 2023"format.dateTime(lastSeen, 'medium'); // "2 hours ago"format.relativeTime(lastSeen); // "$1,499.90"format.number(1499.9, {style: 'currency', currency: 'USD'});

Dates, times & numbers

Use global formats for a consistent look & feel of your app and apply fine-tuning as necessary.

Found 1 error in UserDetails.tsx:13   <h1>{t('titel')}</h1>         ~~~~~~~ Argument of type "titel" is not assignableto parameter of type "title" | "description".

Type-safe

Speed up development with autocompletion for message keys and catch typos early with compile-time checks.

const t = useTranslations('UserDetails'); t('followers', {count: user.followers.length}); // stringt.rich('bio', {b: (chunks) => <b>{chunks}</b>}); // ReactNode const format = useFormatter();const timeZone = useTimeZone();const locale = useLocale();const now = useNow();

Hooks-only API

Learn a single API that can be used across your code base to turn translations into plain strings or rich text.

$ next build Route           Size     First load JS┌ ● /           637 B    90.1 kB├ ● /about      512 B    92.5 kB└ ● /contact    931 B    91.2 kB ● (SSG) automatically generated as static HTML + JSON

Static & dynamic rendering

Get the best performance from your app by supporting internationalization on both static and dynamic pages.

Intl.LocaleIntl.DateTimeFormatIntl.NumberFormatIntl.PluralRulesIntl.RelativeTimeFormat IntlMessageformat

Standards-based

Use the best parts of built-in JavaScript APIs and the battle-tested ICU parser from Format.JS.