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.