Skip to content

next-intl + Locize

Modern Next.js App Router localization with ICU MessageFormat, paired with Locize for cloud translation management, AI translation, and CDN delivery.

next-intl is an internationalization library built specifically for Next.js. It supports both the App Router (the modern Server-Components-based routing paradigm) and the Pages Router. It uses ICU MessageFormat for plurals, selects, and interpolation, provides built-in locale-based routing middleware, and has a small runtime footprint (~2 KB). It is widely adopted as the App-Router-native alternative to next-i18next and is actively maintained at v4.x as of 2026.

Locize natively supports ICU MessageFormat at the platform level: translators see ICU syntax directly in the editor, plurals and selects render as next-intl expects, and no format conversion is needed. The integration loads messages from the Locize CDN inside next-intl's getRequestConfig, returning them as the messages field that next-intl uses to render translations.

Key facts
  • Library: next-intl (App Router native; also works on Pages Router)
  • Current version: v4.x
  • Format: ICU MessageFormat (handled by Locize's format-messageformat package)
  • Server Components: First-class, designed around RSC + Next.js App Router
  • Runtime size: ~2 KB
  • Example repo: locize-next-intl-example
  • Best for: Next.js App Router projects that want ICU MessageFormat + Server Components-friendly i18n

How next-intl works in your code

The useTranslations hook is the most common API: namespaced, type-safe, works in both Server and Client Components.

import { useTranslations } from 'next-intl'

export default function HomePage () {
  const t = useTranslations('HomePage')
  return <h1>{t('title')}</h1>
}

Translations are configured via a i18n/request.ts file in your project root or src directory. next-intl reads it via getRequestConfig.

Connecting next-intl to Locize

Two pieces: a small locize-helper module that loads messages from Locize, and the standard i18n/request.ts file that next-intl reads at request time.

1. The Locize helper

// src/locize-helper.ts (simplified)
import locizer from 'locizer'

locizer.init({
  projectId: process.env.NEXT_PUBLIC_LOCIZE_PROJECTID,
  cdnType: 'standard' // or 'pro'
})

const NAMESPACES = ['common', 'HomePage'] // your namespaces

export async function loadMessages (locale: string) {
  const tree: Record<string, unknown> = {}

  for (const ns of NAMESPACES) {
    tree[ns] = await new Promise((resolve, reject) => {
      locizer.load(ns, (err, messages, _lng) => {
        if (err) return reject(err)
        resolve(messages)
      })
    })
  }

  return tree
}

2. The next-intl request config

// src/i18n/request.ts
import { hasLocale } from 'next-intl'
import { getRequestConfig } from 'next-intl/server'
import { loadMessages } from '../locize-helper'
import { routing } from './routing'

export default getRequestConfig(async ({ requestLocale }) => {
  const requested = await requestLocale
  const locale = hasLocale(routing.locales, requested)
    ? requested
    : routing.defaultLocale

  return {
    locale,
    messages: await loadMessages(locale)
  }
})

That's it. Translations now load from the Locize CDN at request time, with full Server Components support, locale-based routing, and the option to layer in-context editing on top (the example repo wraps loaded values with i18next-subliminal in development for the in-context editor).

Full working example at locize-next-intl-example. For context on choosing between next-intl and next-i18next, see next-intl vs next-i18next.

Frequently asked questions

What is next-intl?

next-intl is an internationalization library built specifically for Next.js, supporting both the App Router (the modern routing paradigm) and the Pages Router. It uses ICU MessageFormat for translation strings, provides built-in locale-based routing middleware, supports React Server Components natively, and has a small runtime footprint (~2 KB). It is widely adopted as the App Router-native alternative to next-i18next and is actively maintained at v4.x as of 2026.

Does Locize support next-intl?

Yes. next-intl uses ICU MessageFormat (which Locize supports natively at the platform level), and the integration is straightforward: in your `i18n/request.ts` file, the `getRequestConfig` function loads messages from Locize via the locizer client and returns them to next-intl as `messages`. The example repo locize-next-intl-example demonstrates the complete setup including App Router routing, locale switching, and optional in-context editing via i18next-subliminal.

How do I integrate next-intl with Locize?

Three steps: (1) install locizer and configure it with your Locize project id and cdnType; (2) write a small `loadMessages(locale)` helper that calls locizer to fetch every namespace and assembles the result into a single message tree; (3) call that helper from `getRequestConfig` inside `i18n/request.ts` and return the result as the `messages` field. Translations now load from the Locize CDN at request time, with full server-component support. The full pattern lives in the locize-next-intl-example repo.

How does next-intl compare to next-i18next for use with Locize?

next-i18next wraps i18next for Next.js and has the deepest Locize integration via i18next-locize-backend: saveMissing, in-context editing via subliminal markers, and direct CDN delivery are all first-class. next-intl is App Router-first (Server Components, getRequestConfig pattern), has a smaller runtime, and uses ICU MessageFormat directly. For new Next.js App Router projects, next-intl is increasingly the default choice; for projects that want maximum Locize integration depth, next-i18next still has the edge. Both work well with Locize.

Does next-intl work with Next.js 16 and React Server Components?

Yes. next-intl is App Router-native and built around React Server Components. It supports Next.js 16, the App Router's request-scoped configuration via getRequestConfig, server-side translation rendering, and client-side hydration. The locize-next-intl-example repo uses Next.js 16 with next-intl v4.11+.

Can I use in-context editing with next-intl?

Yes. The locize-next-intl-example repo demonstrates the pattern: in development, wrap loaded message values with i18next-subliminal, which embeds invisible Unicode markers into every rendered translation. The Locize in-context editor (activated via ?incontext=true on the URL) reads those markers to map clicks on the live page back to translation keys, the same in-context editing experience i18next users get, applied to next-intl.