Add a Locale

GuideLocalizationLocale-first routing

The app uses next-intl with locale-prefixed routes under src/app/[locale].

This guide shows where locale configuration lives, how to add a new message file, and what to verify so the new language works across public and authenticated routes.

Before adding a locale

Review Project Structure and First Customization first so you know where localized labels and config-driven copy already live in the project.

What this guide covers

Routing setup

How new locale codes join the existing next-intl routing system.

Message files

How to create and keep translation keys aligned with the current supported locales.

Route verification

How to confirm public and protected pages still resolve correctly under the new locale.

Main files and folders

FilePropósito
src/i18n/routing.tsSupported locales and route-level i18n configuration.
src/i18n/request.tsRequest-time locale message loading.
src/middleware.tsLocale-aware routing entry behavior.
messages/en.jsonEnglish translation base.
messages/es.jsonSpanish translation file.
messages/cn.jsonChinese translation file.
Locale setup

Use this order when adding a new language.

1

Register the locale code

Add the new locale to the routing config so the app can recognize locale-prefixed URLs for that language.

2

Create the message file

Add a new locale JSON file and mirror the same keys used by the existing translations.

3

Translate config-driven content

Review marketing, auth, dashboard, pricing, and footer keys so the new locale is not partially translated.

4

Verify routing and rendering

Test the main public and protected routes under the new locale before considering the work finished.

Steps

1. Add the locale code

Add the new locale to the locales array in src/i18n/routing.ts.

2. Create the message file

Add a messages/<locale>/ directory with the same JSON files used by the existing languages (system.json, navbar.json, dashboard.json, auth.json).

3. Translate config-driven content

Review keys referenced by:

  • dashboard labels
  • auth forms
  • marketing sections
  • footer content
  • pricing and FAQ

4. Verify route behavior

Because the app is locale-first, every user-facing route should continue to resolve correctly under the new locale.

Test:

  • home
  • sign-in
  • sign-up
  • forgot password
  • dashboard
  • payment result pages

Translation completeness matters

A locale can be technically registered and still feel broken if config-driven labels or message keys are missing in one part of the app.

Important note

The middleware matcher is locale-agnostic, so new locales added through src/i18n/routing.ts automatically participate in the routing system without needing a separate matcher update.