Skip to main content

Den kompletta guiden till internationalisering i Next.js

Konfigurera next-intl med App Router, ställ in språkbaserad routning och automatisera översättningar med AI.

1

Installera next-intl

next-intl är ett enda paket som hanterar språkbaserad routning, inläsning av meddelanden och översättningshooks för Next.js App Router.

Terminal
npm install next-intl
Varför välja next-intl framför next-i18next? next-intl är byggt för App Router och serverkomponenter. next-i18next utformades för Pages Router och har begränsat stöd för App Router.
2

Skapa i18n-konfigurationen för begäranden

Skapa två filer: src/i18n/request.ts för inläsning av meddelanden och src/i18n/routing.ts för definitioner av språkvarianter. De styr hur next-intl läser in meddelanden och hanterar routning.

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 (standardpaketeraren i Next.js 15) kräver experimental.turbo.resolveAlias i next.config.js. Utan den får du felet "Couldn't find next-intl config file".
3

Konfigurera middleware

Lägg till middleware.ts för att hantera språkidentifiering, omskrivning av URL:er och omdirigeringar. Middleware fångar upp varje begäran och ser till att rätt språkvariant används.

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 MÅSTE ligga i projektets rotkatalog, inte i src/. Det är det vanligaste konfigurationsfelet med next-intl.
4

Konfigurera mappstrukturen [locale]

Flytta appens rutter till app/[locale]/. Lägg till generateStaticParams för att skapa sidor för varje språkvariant vid byggning. Det ger URL-strukturen /en/about, /de/about och så vidare.

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

export function generateStaticParams() {
  return routing.locales.map((locale) => ({ locale }));
}
Du MÅSTE anropa setRequestLocale(locale) i varje page.tsx och layout.tsx som använder översättningar. Annars går Next.js över till dynamisk rendering och byggprestandan försämras avsevärt.
5

Uppdatera rotlayouten

Läs in meddelanden med getMessages() och skicka dem till NextIntlClientProvider i rotlayouten för språkvarianten. Ange html-attributet lang utifrån parametern för språkvarianten.

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 uttrycklig locale-prop. Om den utelämnas uppstår svårupptäckta fel i klientkomponenter.
6

Använd översättningar i komponenter

Serverkomponenter använder getTranslations (asynkront, await). Klientkomponenter använder useTranslations (hook). Välj utifrån var komponenten renderas – serverkomponenter håller översättningarna helt borta från JavaScript-paketet.

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')} />;
}
Välj serverkomponenter för översatt innehåll. De håller översättningssträngarna borta från klientens JavaScript-paket och minskar användarnas inläsningstid.
7

Lägg till SEO: metadata och hreflang

Använd generateMetadata för att skapa språkspecifika sidtitlar och beskrivningar. Lägg till alternates.languages för hreflang-taggar så att sökmotorer hittar alla språkversioner av varje sida.

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 byggen skapa localhost som kanonisk URL om metadataBase inte har angetts. Ange alltid metadataBase som din produktionsdomän i rotlayouten.
8

Hantera felsidor och sidor som inte hittas

error.tsx och not-found.tsx kräver särskild hantering eftersom de kan renderas utanför den vanliga språkvariantlayouten. Rotfilen not-found.tsx behöver en egen i18n-providerkonfiguration för att visa lokaliserade felmeddelanden.

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 renderar endast din lokaliserade 404-sida när notFound() uttryckligen anropas i koden. Okända rutter utan en matchande sida visar standardsidan för 404 i Next.js, inte din lokaliserade version.
9

Automatisera översättningar

När din i18n-konfiguration är klar kan du översätta meddelandefilerna med AI direkt från din IDE eller använda i18n Agent CLI i din CI/CD-pipeline för automatisk översättning vid varje driftsättning.

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)
Använd next-intl-localechain för smarta reservspråk. En användare med pt-BR ser då översättningar för pt-PT i stället för engelska när brasiliansk portugisiska inte är tillgänglig.

Automatisera översättningskvaliteten

Upptäck saknade nycklar och trasiga platshållare före lansering med i18n-validate. Testa gränssnittet med testöversättningar via i18n-pseudo innan de riktiga översättningarna är klara.

Verktyg med öppen källkod för Next.js i18n

Dessa paket med öppen källkod löser vanliga problem i arbetsflöden för internationalisering i Next.js.

next-intl-localechain

Standardversionen av next-intl går direkt över till din standardspråkvariant när en översättning saknas. En användare med brasiliansk portugisiska ser engelska i stället för fullt användbara översättningar för pt-PT. next-intl-localechain lägger till smarta reservkedjor – paketet djupsammanfogar översättningar från närliggande språkvarianter så att regionala användare alltid ser den närmast tillgängliga översättningen.

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'
}));
Djupsammanfogar automatiskt översättningar längs reservkedjor
Inbyggda kedjor för portugisiska, spanska, franska, tyska med flera
Hoppar smidigt över saknade meddelandefiler utan fel
Konfiguration på en rad – omsluter din befintliga getRequestConfig
Visa på GitHub

@i18n-agent/cli

Ett kommandoradsverktyg för att översätta meddelandefiler i Next.js utan att lämna terminalen. Översätt filer direkt, kontrollera jobbstatus och hämta resultat. Fungerar i CI/CD-pipelines med autentisering via API-nyckel för helt automatiserade lokaliseringsflöden.

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
Översätt JSON, YAML, PO och andra i18n-filformat från terminalen
Redo för CI/CD – autentisera via en miljövariabel för automatiserade pipelines
Följ jobbstatus, återuppta misslyckade jobb och hämta resultat
Maskinläsbara JSON-utdata för skript och automatisering
Visa på GitHub

Vanliga fallgropar

"Unable to find next-intl locale"

Middleware matchade inte begäran. Kontrollera: ligger middleware.ts i projektroten? Utesluter matcher-mönstret statiska filer korrekt? Ingår språkvarianten i din routningskonfiguration?

Oväntad dynamisk rendering

setRequestLocale(locale) saknas på en sida eller i en layout. Utan den använder next-intl rubriker/cookies för att identifiera språkvarianten, vilket tvingar fram dynamisk rendering och förhindrar statisk generering.

Parallella rutter fungerar inte med i18n

Parallella rutter (@modal) och uppfångande rutter ((.)photo) har kända kompatibilitetsproblem med det dynamiska segmentet [locale]. Använd middleware-baserad routning som en alternativ lösning för dessa avancerade routningsmönster.

Språkbyte tappar den aktuella rutten

När du byter språkvariant bevarar du den aktuella sökvägen med usePathname() och ersätter endast språksegmentet. Var försiktig med dynamiska ruttparametrar – de måste lösas på nytt för den nya språkvarianten.

Rekommenderad 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

Prova i18n Agent nu

Släpp din översättningsfil här

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

eller klicka för att välja en fil

Målspråk

Ingen registrering krävsPrisuppskattning direkt

Reservspråk med next-intl-localechain

När en översättningsnyckel saknas i en regional språkvariant som pt-BR går next-intl direkt över till standardspråkvarianten i stället för att först kontrollera det överordnade språket 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 vår guide till reservspråk för en fullständig lista över ramverk som stöds och 75 inbyggda kedjor. Learn more →

Vanliga frågor