next-intl Internationalization

Conventions for multi-language Next.js apps using next-intl, including translation patterns, locale detection, and common pitfalls.

CopilotCursorKilo
AuthorNeexoCore
Apply to**/*.{ts,tsx}, **/messages/**
Updated
i18nnextjsnext-intl

Overview

next-intl provides type-safe internationalization for Next.js App Router apps. Neexo marketing sites often ship multiple locales from a single codebase.

Setup

Translation files live in messages/ as JSON:

messages/
  en.json    # Primary locale (source of truth for keys)
  de.json    # Additional locales

Translation Pattern

"use client";

import { useTranslations } from "next-intl";

export default function HeroSection() {
  const t = useTranslations("hero");
  return (
    <section>
      <h1>{t("title")}</h1>
      <p>{t("description")}</p>
    </section>
  );
}

Rules

  • Pick one primary locale per project and write that catalog first, then translate to secondary locales
  • Use useTranslations() in client components — never inline user-facing strings in components
  • Namespace translations by feature or page: hero.title, contact.submit, nav.home
  • Keep translation keys in kebab-case or camelCase — be consistent within the project

Message File Structure

{
  "nav": {
    "home": "Home",
    "about": "About",
    "contact": "Contact"
  },
  "hero": {
    "title": "Industrial 3D visualization",
    "description": "We turn technical CAD data into visual experiences"
  }
}

Language Switching

For apps without locale in the URL (single-domain approach):

"use client";

import { useLocale } from "next-intl";

function LanguageSwitcher() {
  const locale = useLocale();
  // Switch by updating cookie or context
}

Locale Text Rules

  • Use correct characters for each locale (accented letters, umlauts, etc.) — never ASCII substitutes
  • Avoid em-dashes in UI copy when a comma or shorter sentence reads better
  • Avoid AI/corporate buzzwords in translations — write like a human native speaker
  • Keep tone consistent across locales (formal vs casual)

Common Pitfalls

  • Do not use useTranslations() in Server Components — use getTranslations() instead
  • Set defaultLocale to the project primary locale in the i18n config
  • Ensure every locale file has the same keys — missing keys cause runtime fallback warnings
  • Do not create inline translation objects — always use the message files

Raw content

Copy into your project — e.g. .instructions.md, .agent.md, or SKILL.md

## Overview

next-intl provides type-safe internationalization for Next.js App Router apps. Neexo marketing sites often ship multiple locales from a single codebase.

## Setup

Translation files live in `messages/` as JSON:

```
messages/
  en.json    # Primary locale (source of truth for keys)
  de.json    # Additional locales
```

## Translation Pattern

```tsx
"use client";

import { useTranslations } from "next-intl";

export default function HeroSection() {
  const t = useTranslations("hero");
  return (
    <section>
      <h1>{t("title")}</h1>
      <p>{t("description")}</p>
    </section>
  );
}
```

## Rules

- Pick one **primary locale** per project and write that catalog first, then translate to secondary locales
- Use `useTranslations()` in client components — never inline user-facing strings in components
- Namespace translations by feature or page: `hero.title`, `contact.submit`, `nav.home`
- Keep translation keys in kebab-case or camelCase — be consistent within the project

## Message File Structure

```json
{
  "nav": {
    "home": "Home",
    "about": "About",
    "contact": "Contact"
  },
  "hero": {
    "title": "Industrial 3D visualization",
    "description": "We turn technical CAD data into visual experiences"
  }
}
```

## Language Switching

For apps without locale in the URL (single-domain approach):

```tsx
"use client";

import { useLocale } from "next-intl";

function LanguageSwitcher() {
  const locale = useLocale();
  // Switch by updating cookie or context
}
```

## Locale Text Rules

- Use correct characters for each locale (accented letters, umlauts, etc.) — never ASCII substitutes
- Avoid em-dashes in UI copy when a comma or shorter sentence reads better
- Avoid AI/corporate buzzwords in translations — write like a human native speaker
- Keep tone consistent across locales (formal vs casual)

## Common Pitfalls

- Do not use `useTranslations()` in Server Components — use `getTranslations()` instead
- Set `defaultLocale` to the project primary locale in the i18n config
- Ensure every locale file has the same keys — missing keys cause runtime fallback warnings
- Do not create inline translation objects — always use the message files

Next steps

Matched by shared tags and category. Browse all instructions