Skip to main content

Den komplette guide til internationalisering i Next.js

Konfigurer next-intl med App Router, opsæt routing efter landestandard og automatiser oversættelser med AI.

1

Installer next-intl

next-intl er en enkelt pakke, der håndterer routing efter landestandard, indlæsning af meddelelser og oversættelseshooks til Next.js App Router.

Terminal
npm install next-intl
Hvorfor vælge next-intl frem for next-i18next? next-intl er udviklet til App Router og serverkomponenter. next-i18next blev udviklet til Pages Router og har begrænset understøttelse af App Router.
2

Opret i18n-anmodningskonfigurationen

Opret to filer: src/i18n/request.ts til indlæsning af meddelelser og src/i18n/routing.ts til definitioner af landestandarder. De konfigurerer, hvordan next-intl finder meddelelser og ruter.

src/i18n/routing.ts
// src/i18n/routing.ts
import { defineRouting } from 'next-intl/routing';
import { createNavigation } from 'next-intl/navigation';

export const routing = defineRouting({
  locales: ['en', 'de', 'ja', 'es'],
  defaultLocale: 'en',
  localePrefix: 'as-needed',  // /about for en, /de/about for de
});

export const { Link, redirect, usePathname, useRouter } =
  createNavigation(routing);
Turbopack (standardmodulpakkeren i Next.js 15) kræver experimental.turbo.resolveAlias i din next.config.js. Uden den får du fejlen "Kunne ikke finde konfigurationsfilen til next-intl".
3

Konfigurer middleware

Tilføj middleware.ts for at håndtere registrering af landestandard, omskrivning af URL'er og omdirigeringer. Middlewaren opfanger hver anmodning og sikrer, at den korrekte landestandard anvendes.

middleware.ts
// middleware.ts  <- Must be in project ROOT, not src/
import createMiddleware from 'next-intl/middleware';
import { routing } from './src/i18n/routing';

export default createMiddleware(routing);

export const config = {
  matcher: ['/((?!api|_next|.*\\..*).*)'],
};
middleware.ts SKAL ligge i projektets rodmappe, ikke i src/. Det er den mest almindelige konfigurationsfejl med next-intl.
4

Konfigurer mappestrukturen [locale]

Flyt dine appruter ind i app/[locale]/. Tilføj generateStaticParams for at generere sider for hver landestandard under buildprocessen. Det opretter URL-strukturen /en/about, /de/about osv.

app/[locale]/layout.tsx
// app/[locale]/layout.tsx
import { routing } from '@/i18n/routing';

export function generateStaticParams() {
  return routing.locales.map((locale) => ({ locale }));
}
Du SKAL kalde setRequestLocale(locale) i alle page.tsx- og layout.tsx-filer, der bruger oversættelser. Uden kaldet bruger Next.js dynamisk gengivelse som reserve og buildydelsen forringes markant.
5

Opdater dit rodlayout

Indlæs meddelelser med getMessages() og send dem til NextIntlClientProvider i dit rodlayout for landestandarder. Angiv html-attributten lang ud fra parameteren locale.

app/[locale]/layout.tsx
// app/[locale]/layout.tsx
import { NextIntlClientProvider } from 'next-intl';
import { getMessages, setRequestLocale } from 'next-intl/server';
import { routing } from '@/i18n/routing';
import { notFound } from 'next/navigation';

export function generateStaticParams() {
  return routing.locales.map((locale) => ({ locale }));
}

export default async function LocaleLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { locale: string };
}) {
  const { locale } = await params;
  if (!routing.locales.includes(locale as any)) notFound();

  setRequestLocale(locale);
  const messages = await getMessages();

  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider locale={locale} messages={messages}>
          {children}
        </NextIntlClientProvider>
      </body>
    </html>
  );
}
NextIntlClientProvider kræver en eksplicit locale-prop. Hvis den udelades, medfører det diskrete fejl i klientkomponenter, som er svære at finde.
6

Brug oversættelser i komponenter

Serverkomponenter bruger getTranslations (async, await). Klientkomponenter bruger useTranslations (hook). Vælg ud fra, hvor din komponent gengives — serverkomponenter holder oversættelser helt ude af JavaScript-pakken.

app/[locale]/page.tsx
// Server Component (default)
import { getTranslations, setRequestLocale } from 'next-intl/server';

export default async function AboutPage({
  params,
}: { params: { locale: string } }) {
  const { locale } = await params;
  setRequestLocale(locale);
  const t = await getTranslations('AboutPage');

  return <h1>{t('title')}</h1>;
}

// Client Component ('use client')
'use client';
import { useTranslations } from 'next-intl';

export default function SearchBar() {
  const t = useTranslations('SearchBar');
  return <input placeholder={t('placeholder')} />;
}
Brug helst serverkomponenter til oversat indhold. De holder oversættelsestekster ude af din JavaScript-klientpakke og reducerer brugernes indlæsningstid.
7

Tilføj SEO: Metadata og hreflang

Brug generateMetadata til at oprette sidespecifikke titler og beskrivelser for hver landestandard. Tilføj alternates.languages til hreflang-tags, så søgemaskiner kan finde alle sprogversioner af hver side.

app/[locale]/layout.tsx
// app/[locale]/layout.tsx or any page.tsx
import { getTranslations } from 'next-intl/server';
import { routing } from '@/i18n/routing';

export async function generateMetadata({
  params,
}: { params: { locale: string } }) {
  const { locale } = await params;
  const t = await getTranslations({ locale, namespace: 'Metadata' });

  return {
    title: t('title'),
    description: t('description'),
    alternates: {
      languages: Object.fromEntries(
        routing.locales.map((l) => [l, `/${l}`])
      ),
    },
  };
}
På Vercel kan builds generere localhost som den kanoniske URL, hvis metadataBase ikke er angivet. Angiv altid metadataBase som dit produktionsdomæne i rodlayoutet.
8

Håndter fejl- og ikke fundet-sider

error.tsx og not-found.tsx kræver særlig håndtering, fordi de kan gengives uden for det normale layout for landestandarder. not-found.tsx ved roden kræver sin egen opsætning af en i18n-provider for at vise lokaliserede fejlmeddelelser.

app/[locale]/error.tsx
// app/[locale]/error.tsx
'use client';
import { useTranslations } from 'next-intl';

export default function Error() {
  const t = useTranslations('Error');
  return (
    <div>
      <h1>{t('title')}</h1>
      <p>{t('description')}</p>
    </div>
  );
}

// app/not-found.tsx (root level -- needs own provider)
import { routing } from '@/i18n/routing';

export default async function GlobalNotFound() {
  return (
    <html lang={routing.defaultLocale}>
      <body>
        <h1>404 - Page Not Found</h1>
      </body>
    </html>
  );
}
Next.js gengiver kun din lokaliserede 404-side, når notFound() kaldes eksplicit i din kode. Ukendte ruter uden en matchende side viser Next.js' standard-404-side, ikke din lokaliserede version.
9

Automatiser oversættelser

Når din i18n-opsætning er færdig, kan du oversætte dine meddelelsesfiler med AI direkte fra dit IDE eller bruge i18n Agent CLI i din CI/CD-pipeline til automatisk oversættelse ved hver udrulning.

Terminal
# In your IDE, ask your AI assistant:
> Translate messages/en.json to German, Japanese, and Spanish

✓ messages/de.json created (1.1s)
✓ messages/ja.json created (1.4s)
✓ messages/es.json created (1.0s)
Brug next-intl-localechain til intelligente reserver for landestandarder — en bruger med pt-BR ser pt-PT-oversættelser i stedet for engelsk, når brasiliansk portugisisk ikke er tilgængeligt.

Automatiser oversættelseskvaliteten

Find manglende nøgler og ødelagte pladsholdere med i18n-validate, før de udgives. Test din brugergrænseflade med simulerede oversættelser via i18n-pseudo, før de rigtige oversættelser er klar.

Open source-værktøjer til Next.js i18n

Disse open source-pakker løser almindelige problemer i arbejdsgange til internationalisering i Next.js.

next-intl-localechain

Som standard går next-intl direkte videre til din standardlandestandard, når en oversættelse mangler. En bruger med brasiliansk portugisisk ser engelsk i stedet for velfungerende pt-PT-oversættelser. next-intl-localechain tilføjer intelligente reservekæder — pakken fletter automatisk oversættelser fra beslægtede landestandarder i dybden, så regionale brugere altid ser den nærmeste tilgængelige oversættelse.

src/i18n/request.ts
import { getRequestConfig } from 'next-intl/server';
import { withLocaleChain } from 'next-intl-localechain';

export default getRequestConfig(withLocaleChain({
  loadMessages: (locale) =>
    import(`../../messages/${locale}.json`).then(m => m.default),
  defaultLocale: 'en'
}));
Fletter automatisk oversættelser i dybden på tværs af landestandardkæder
Indbyggede kæder til portugisisk, spansk, fransk, tysk og flere andre sprog
Springer problemfrit manglende meddelelsesfiler over uden fejl
Opsætning med én linje — ombryder din eksisterende getRequestConfig
Se på GitHub

@i18n-agent/cli

Et kommandolinjeværktøj til at oversætte dine Next.js-meddelelsesfiler uden at forlade terminalen. Oversæt filer direkte, kontrollér jobstatus og download resultater. Fungerer i CI/CD-pipelines med godkendelse via API-nøgle til fuldautomatisk lokalisering.

Terminal
# Install the CLI
npm install -g @i18n-agent/cli

# Authenticate
i18nagent login

# Translate your message files
i18nagent translate ./messages/en.json --lang de,ja,es

# Or use in CI/CD with an API key
export I18N_AGENT_API_KEY=your-key-here
i18nagent translate ./messages/en.json --lang de,ja,es
Oversæt JSON, YAML, PO og andre i18n-filformater fra terminalen
Klar til CI/CD — godkend via en miljøvariabel til automatiserede pipelines
Følg jobstatus, genoptag mislykkede jobs og download resultater
Maskinlæsbar JSON-output til scripts og automatisering
Se på GitHub

Almindelige faldgruber

"Kan ikke finde landestandard for next-intl"

Middlewaren matchede ikke anmodningen. Kontrollér: Ligger middleware.ts i projektets rod? Udelukker matcher-mønsteret statiske filer korrekt? Er landestandarden medtaget i din routingkonfiguration?

Uventet dynamisk gengivelse

setRequestLocale(locale) mangler på en side eller i et layout. Uden kaldet bruger next-intl headers/cookies til at registrere landestandarden, hvilket gennemtvinger dynamisk gengivelse og forhindrer statisk generering.

Parallelle ruter fungerer ikke med i18n

Parallelle ruter (@modal) og opfangende ruter ((.)photo) har kendte kompatibilitetsproblemer med det dynamiske segment [locale]. Brug middlewarebaseret routing som en midlertidig løsning til disse avancerede routingmønstre.

Sprogskift mister den aktuelle rute

Når du skifter landestandard, skal du bevare det aktuelle stinavn med usePathname() og kun erstatte segmentet med landestandarden. Vær forsigtig med dynamiske ruteparametre — de skal findes igen for den nye landestandard.

Anbefalet filstruktur

Project Structure
my-nextjs-app/
├── middleware.ts              # Locale routing (project root!)
├── next.config.mjs
├── messages/
│   ├── en.json                # Source messages
│   ├── de.json
│   └── ja.json
├── src/
│   ├── i18n/
│   │   ├── request.ts         # Message loading config
│   │   └── routing.ts         # Locale definitions
│   └── app/
│       └── [locale]/
│           ├── layout.tsx     # Root locale layout
│           ├── page.tsx       # Home page
│           ├── error.tsx      # Localized error page
│           ├── not-found.tsx  # Localized 404
│           └── about/
│               └── page.tsx
└── package.json

Prøv i18n Agent nu

Slip din oversættelsesfil her

JSON, YAML, PO, XML, CSV, Markdown, Properties

eller klik for at vælge en fil

Målsprog

Kræver ingen tilmeldingEstimat med det samme

Reserve for landestandard med next-intl-localechain

Når en oversættelsesnøgle mangler i en regional landestandard som pt-BR, går next-intl direkte videre til standardlandestandarden i stedet for først at kontrollere den overordnede landestandard pt.

Terminal
npm install next-intl-localechain
Configuration
import { withLocaleChain } from 'next-intl-localechain';

export default withLocaleChain({
  fallbacks: {
    'pt-BR': ['pt', 'en'],
    'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
  },
  defaultLocale: 'en',
  loadMessages: (locale) => import(`./messages/${locale}.json`),
});

Se vores guide til reserver for landestandarder for at få den komplette liste over understøttede frameworks og 75 indbyggede kæder. Learn more →

Ofte stillede spørgsmål