Nettsideoversettelse

Next.js internasjonalisering for App Router og Pages Router

Next.js internasjonalisering for App Router og Pages Router
Rayne Aguilar
Skrevet av
Rayne Aguilar
Elizabeth Pokorny
Gjennomgått av
Elizabeth Pokorny
Oppdatert
12. juni 2026

Next.js har to offisielle i18n-dokumentasjonssider som beskriver helt forskjellige systemer, uten kryssreferanser mellom dem.

Den ene dekker Pages Router . Den andre dekker App Router . Ingen av dem forklarer hvordan de to forholder seg, hvilke biblioteker som skal brukes, eller hvordan man håndterer hreflang for flerspråklig SEO.

Vi skal bygge bro mellom begge ruterne. Vi skal gå gjennom rutingsstrategier, valg av bibliotek, oppsett av mellomprogramvare, oversettelser av serverkomponenter og flerspråklig SEO.

Målet vårt er å lage en nyttig ressurs for utviklere som har blitt bedt om å legge til språkstøtte i en Next.js-app og trenger et klart bilde før de bestemmer seg for en strategi. La oss komme i gang!

Hva Next.js tilbyr for internasjonalisering

Internasjonalisering har tre lag:

  • Ruting , som gir hver språkenhet sin egen URL.
  • Oversettelse , som laster inn de riktige strengene.
  • Formatering for datoer, tall og valutaer.

Next.js hjelper bare med ruting.

Pages Router har hatt innebygd i18n-ruting siden v10.0.0. En konfigurasjonsblokk med tre felt i next.config.js håndterer lokalitetsdeteksjon, URL-prefiksering og omdirigeringer automatisk.

App-ruteren er annerledes. Dokumentasjonssiden for i18n dokumenterer et mønster du setter sammen selv ved hjelp av mellomvare, en [lokal] dynamisk segment og et bibliotek.

Når det gjelder oversettelser og formatering, er du overlatt til deg selv, uavhengig av hvilken ruter du bruker. App Router-dokumentasjonen viser alle kompatible biblioteker, men gir ingen veiledning om hvilket du skal velge. Ingen av dokumentasjonssidene dekker hreflang-tagger eller flerspråklige nettstedskart.

Hvordan i18n er forskjellig mellom Pages-ruteren og appruteren

Pages Router-tilnærmingen er en konfigurasjonsendring. Legg til en i18n-blokk i next.config.js med tre felt:

// next.config.js
module.exports = {  
  i18n: {    
    locales: ['en', 'fr', 'de'],    
    defaultLocale: 'en',  
  },
}

Det er det.

Next.js oppdager automatisk språkinnstillinger fra Godta språk overskrift, respekterer en NESTE_LOKALE overstyring av informasjonskapsler, og eksponerer den aktive språkinnstillingen via brukRouter().lokalDu trenger ikke mellomvare eller omstrukturering av kataloger.

App-ruteren har ingen tilsvarende konfigurasjon. Du bygger rutingen selv fra tre deler:

  • proxy.ts, tidligere kalt mellomvare.ts, håndterer lokaliseringsdeteksjon og omdirigeringer. Den bruker @formatjs/intl-localematcher og forhandler å analysere Godta språk overskrifter. De offisielle dokumentene lar den faktiske deteksjonslogikken stå som en ellipse: funksjon getLocale(forespørsel) { ... }Vi fyller ut det i neste avsnitt.
  • [lokal] dynamisk segment omslutter hele app/ katalog. Hver rute blir språktilpasset gjennom mappestrukturen.
  • genererStatiskeParamer forhåndsgjengir hver språkvariant under bygging.

Av de tre delene er generateStaticParams den som erstatter det Pages Router håndterte automatisk under byggetid.

export function generateStaticParams() {  
	return [{ locale: 'en' }, { locale: 'fr' }, { locale: 'de' }]
}

🚨 Pages Routers innebygde i18n fungerer ikke med utdata: 'eksport'Hvis du trenger en fullstendig statisk eksport, trenger du manuell mappebasert ruting i stedet. Denne begrensningen gjelder kun for den innebygde konfigurasjonen. Begge ruterne støtter statisk eksport med manuelt oppsett.

Understi-ruting, domene-ruting og i18n uten URL-endringer

Før du velger et bibliotek, velg en rutingsstrategi. Det påvirker SEO, DNS-oppsett og hvor mye mellomvare du skal skrive:

  • Underveisruting plasserer språkinnstillingen i URL-banen, som /fr/products eller /de/products . Det er standardinnstillingen for offentlige nettsteder. Søkemotorer indekserer hver språkinnstilling som en separat side, og det er det du ønsker for flerspråklig SEO.
  • Domeneruting tilordner språkinnstillinger til separate domener eller underdomener, som example.fr eller de.example.com . Den sender sterkere geografiske målrettingssignaler via ccTLD-er, men legger til DNS-konfigurasjon og kompliserer lokal utvikling.
  • Uten ruting holder alle språkinnstillinger på samme URL og bestemmer språkinnstillinger fra en informasjonskapsel eller brukerpreferanse lagret i en profil. Søkemotorer ser én URL og kan ikke indeksere språkvarianter separat. Dette er et legitimt mønster for autentiserte SaaS-apper og interne verktøy der SEO ikke er et krav. neste-intl støtter det som et førsteklasses alternativ.

For offentlige nettsteder der SEO er viktig, er underveisruting riktig standard. Domeneruting er verdt kompleksiteten bare hvis sterke geografiske målrettingssignaler er et spesifikt krav.

Hvis du heller ikke vil administrere URL-strukturen manuelt, håndterer Weglot omvendte proxy ruting av underkataloger og underdomener automatisk, inkludert hreflang-injeksjon og oversatte URL-er.

next-intl vs. react-i18next vs. Lingui

Som vi nevnte tidligere, lister de offisielle dokumentene opp biblioteker uten å anbefale noen. Slik sammenligner du hovedalternativene:

Funksjon neste-intl react-i18next Lingui
RSC-støtte Innfødt Via asynkron init Via makroer
SEO/snarvei Manuell via Metadata API Manuell via Metadata API Manuell via Metadata API
Ruting Integrert Via next-i18n-ruteren Håndbok
TypeScript Strengt skrevet Via programtillegg Via ekstraksjon
Formatering Pakker internasjonale API-er via useFormatter Delegater til FormatJS Håndbok

next-intl er de facto-standarden for App Router. RSC-støtte er innebygd, ruting er integrert, og TypeScript-autofullføring fungerer uten ekstra konfigurasjon.

react-i18next passer bedre hvis du er på Pages Router eller allerede bruker i18next andre steder i stacken din. Støtte for App Router fungerer, men krever mer manuell oppsett.

Lingui passer for team med eksisterende .po -filkanaler. Oversettelser hentes ut under bygging, slik at ubrukte meldinger aldri sendes.

💡 Paraglide JS er ikke akkurat blant de store aktørene, men det er verdt å merke seg som et kompilatorbasert alternativ med mindre buntutdata. Hvis du er interessert, må du imidlertid være oppmerksom på at økosystemet deres er yngre enn de andre.

For dato- og tallformatering pakker next-intl de innebygde Intl API-ene via useFormatter. De andre delegerer til FormatJS , eller lar det være opp til deg å kalle Intl.DateTimeFormat og Intl.NumberFormat direkte.

💡 Disse bibliotekene håndterer gjengivelse. Noen må fortsatt produsere oversettelsene og holde dem synkroniserte etter hvert som innholdet endres. Weglot opererer på et helt annet lag, og administrerer oversettelsesinnhold via omvendt proxy utenfor kodebasen. Ikke tenk på det som en erstatning for et bibliotek.

Konfigurering av mellomvare, lokaliseringsdeteksjon og oversettelse av serverkomponenter

Next.js 16 omdøpte middleware.ts til proxy.ts . Dette ble gjort fordi «middleware» var misvisende og antydet generisk logikk i appen. I virkeligheten kjører filen ved nettverksgrensen, og fanger opp og endrer forespørsler som en proxy før de når applikasjonen.

Her er en komplett implementering av lokalitetsdeteksjon og omdirigering som fyller den nevnte ellipsen i den offisielle dokumentasjonen:

// proxy.ts
import { match } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
import { NextRequest, NextResponse } from 'next/server'

const locales = ['en', 'fr', 'de']
const defaultLocale = 'en'

function getLocale(request: NextRequest): string {
  const cookie = request.cookies.get('NEXT_LOCALE')?.value
  if (cookie && locales.includes(cookie)) return cookie

  const headers = { 'accept-language': request.headers.get('accept-language') ?? '' }
  const languages = new Negotiator({ headers }).languages()
  return match(languages, locales, defaultLocale)
}

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl
  const hasLocale = locales.some(l => pathname.startsWith(`/${l}/`) || pathname === `/${l}`)
  if (hasLocale) return

  const locale = getLocale(request)
  request.nextUrl.pathname = `/${locale}${pathname}`
  return NextResponse.redirect(request.nextUrl)
}

Filer nestet under app/[språk]/, med en ordbøker/ mappen ved siden av layoutene og sidene dine. Rotlayouten mottar språk som en parameter og setter den på html tagg:

export default async function RootLayout({ children, params }) {
  const { locale } = await params

  return (
    <html lang={locale}>
      <body>{children}</body>
    </html>
  )
}

For oversettelser viser de offisielle dokumentene et rått ordboksmønster som ikke krever noe bibliotek:

const dictionaries = {
  en: () => import('./dictionaries/en.json').then(m => m.default),
  fr: () => import('./dictionaries/fr.json').then(m => m.default),
}

export const getDictionary = async (locale: string) => dictionaries[locale]()

Dette fungerer, men har ingen støtte for pluralisering eller interpolasjon. neste-intl dekker begge via getTranslations() og brukOversettelser() i Serverkomponenter og klientkomponenter henholdsvis.

Uansett behandles oversettelsesfiler på serveren, og bare den resulterende HTML-koden når nettleseren, så meldingsfilstørrelsen har ingen innvirkning på klientbuntstørrelsen.

For klientkomponenter, send oversatte strenger som props fra en overordnet serverkomponent der det er mulig. NextIntlClientProvider med et begrenset meldingsdelsett bare når en klientkomponent trenger å håndtere oversettelser direkte.

For en språkveksler gjengir en serverkomponent språketikettene mens en klientkomponent håndterer brukRuter() ringe:

// LocaleSwitcher.tsx (Server Component)
import LocaleSwitcherClient from './LocaleSwitcherClient'

export default function LocaleSwitcher({ locale }) {
  return <LocaleSwitcherClient locale={locale} labels={{ en: 'English', fr: 'Français' }} />
}

Klienten lytter halvveis etter endringer i valget og sender den nye lokale ruten:

// LocaleSwitcherClient.tsx
'use client'
import { useRouter } from 'next/navigation'

export default function LocaleSwitcherClient({ locale, labels }) {
  const router = useRouter()
  return (
    <select value={locale} onChange={e => router.push(`/${e.target.value}`)}>
      {Object.entries(labels).map(([value, label]) => (
        <option key={value} value={value}>{label}</option>
      ))}
    </select>
  )
}

Hvis du bruker Weglot , ingenting av dette gjelder. Weglot inkluderer en innebygd språkbytterwidget og krever ingen proxy-konfigurasjon eller mellomvare.

Flerspråklig SEO med Hreflang, nettstedskart og metadata

Ingen av ruterne håndterer flerspråklig SEO automatisk:

  • Pages Router-settene html-språk riktig, men dokumentasjonen sier at implementeringen av hreflang er «opp til deg».
  • App-ruteren nevner ikke hreflang i det hele tatt.

Med App Router bringer Metadata API deg nærmest automatisering. Definer lokale URL-er i genererMetadata via alternative språk objekt og Next.js automatiske injiseringer lenke rel="alternativ" hreflang="..." tagger:

export async function generateMetadata({ params: { locale } }) {
  return {
    alternates: {
      languages: {
        'en': 'https://example.com/en',
        'fr': 'https://example.com/fr',
        'de': 'https://example.com/de',
      },
    },
  }
}

Den manuelle delen handler om å samle inn riktig URL for hver språkvariant per side. Den logikken er din oppgave.

To andre ting krever manuell implementering uavhengig av hvilken ruter du bruker. Kanoniske URL-er må angis per språk for å unngå duplikatinnholdssignaler. Din sitemap.ts behov xhtml:lenke oppføringer for hver språkvariant på hver side.

hreflang verdien i seg selv, bruk hreflang="en-US" når man målretter seg mot en bestemt region, og hreflang="en" når man retter seg mot alle engelsktalende. Å blande disse opp sender motstridende signaler til søkemotorer.

neste-intl legger til én delvis automatisering: proxyen injiserer automatisk hreflang Lenke svarhoder når du bruker lokalisert stinavnruting. Andre rutingskonfigurasjoner krever fortsatt manuell implementering.

Det er en betydelig mengde kontinuerlig vedlikehold etter hvert som nettstedet ditt vokser. Heldigvis, Weglot s reverse proxy håndterer alt automatisk på serveren, slik at oversatte sider er fullt indekserbare uten tilleggskode.

Weglot s tilnærming til flerspråklig SEO

Faktisk, Weglot s reverse proxy håndterer alt som er dekket i forrige avsnitt automatisk: hreflang-tagger , oversatte URL-er, kanoniske tagger og generering av nettstedskart. Oversatte sider serveres på serversiden, slik at de er fullt indekserbare av søkemotorer.

⚠️ Weglot JavaScript-koden snippet Integrasjon gir ikke SEO-fordeler. Klientsideoversettelse kan ikke gjennomsøkes. Hvis SEO er viktig, kreves det oppsett av omvendt proxy .

En sekundær fordel er byggetid. Weglot serverer oversatte sider fra sitt eget CDN i stedet for å generere dem under bygging. Legger til 10 språk til en Weglot -drevet nettsted har ingen effekt på hvor lenge neste bygg tar.

Velge riktig tilnærming for Next.js-prosjektet ditt

Det riktige valget avhenger av hva du optimaliserer for.

Hvis du bygger på App Router og starter på nytt, neste-intl er standardvalget. Den dekker ruting, oversettelser, TypeScript-autofullføring og RSC-støtte i én pakke.

Hvis du er på Pages Router eller allerede har i18next i stacken din, react-i18next er minste motstands vei.

Hvis flerspråklig SEO og kontinuerlig oversettelseshåndtering er prioriteten, løser ingen av bibliotekene hele problemet. Du må fortsatt implementere hreflang, nettstedskart og en arbeidsflyt for å holde oversettelser oppdaterte etter hvert som innholdet endres. Weglot s reverse proxy håndterer alt dette automatisk.

Weglot og et bibliotek på komponentnivå utelukker ikke hverandre. Weglot opererer på HTML- og proxy-laget, slik at det kan sameksistere med hvilket som helst bibliotek komponentene dine bruker.

Hvis den tilnærmingen passer din situasjon, kan du sjekke ut Weglot JavaScript-integrasjonsside som et utgangspunkt og prøve vår 14-dagers gratis prøveperiode !

retnings-ikon
Oppdag Weglot

Gode ​​ting kommer til de som venter. Det gjør ikke internasjonal trafikk.

Vi sørger for at morsmålene dine blir tilgjengelige. Du bestemmer hvor langt du vil gå. Prøv. Weglot gratis i dag.

I denne artikkelen tar vi en titt på:
Rakettikon

Klar til å komme i gang?

Den beste måten å forstå kraften i Weglot er å se det selv. Test det gratis og uten forpliktelser.

En demo-nettside er tilgjengelig i dashbordet ditt hvis du ikke er klar til å koble til nettstedet ditt ennå.

Les artikler du kanskje også liker

FAQ-ikon

Ofte stilte spørsmål

Ingen treff.

Blå pil

Blå pil

Blå pil