Tilbake til bloggen
Terminal output showing a translation script writing de.json and fr.json, alongside a folder tree and a browser rendering the German locale route.

Hvordan oversette en Next.js-app med PolyLingo på under 30 minutter

By Robert

Hvordan oversette en Next.js-app med PolyLingo på under 30 minutter

Innen slutten av denne veiledningen vil du ha et fungerende flerspråklig Next.js App Router-prosjekt: strenger hentet ut til messages/en.json, oversatte locale-filer for hvert språk du trenger, next-intl som serverer riktig fil per rute, og et enkelt Node-skript du kan kjøre på nytt når innholdet ditt endres.

Ingen oversettelsesplattform å registrere seg for. Ingen faste avgifter per språk. Ett API-kall håndterer alle målspråk samtidig.

Det du trenger:

  • Et Next.js-prosjekt som bruker App Router (Next.js 14 eller 15)
  • Node.js 18 eller nyere
  • En gratis PolyLingo-konto og API-nøkkel

Steg 1: Skaff din PolyLingo API-nøkkel (5 minutter)

Opprett en gratis konto på usepolylingo.com. Gratisnivået inkluderer 100 000 tokens per måned, noe som er nok til å oversette en middels stor locale-fil til 10+ språk flere ganger.

Når du er inne, gå til API keys i dashbordet og opprett en nøkkel. Du vil bare se hele verdien én gang, så kopier den umiddelbart.

Legg den til prosjektet ditt som en miljøvariabel. Aldri sjekk den inn i versjonskontroll og aldri eksponer den i klientkode:

# .env.local
POLYLINGO_API_KEY="pl_your_key_here"

Bekreft at API-en er tilgjengelig før du går videre:

curl -sS "https://api.usepolylingo.com/v1/health"

Du bør få tilbake en liten JSON-payload med "status": "ok".


Steg 2: Installer next-intl og sett opp routing (10 minutter)

Installer biblioteket:

npm install next-intl

Lag en i18n.ts-fil i prosjektets rotmappe. Denne forteller next-intl hvilke locales du støtter og hvordan du laster riktig meldingsfil for hver forespørsel:

// i18n.ts
import { getRequestConfig } from 'next-intl/server'

export const locales = ['en', 'de', 'fr'] as const
export type Locale = (typeof locales)[number]
export const defaultLocale: Locale = 'en'

export default getRequestConfig(async ({ requestLocale }) => {
  let locale = await requestLocale
  if (!locale || !locales.includes(locale as Locale)) {
    locale = defaultLocale
  }
  return {
    locale,
    messages: (await import(`./messages/${locale}.json`)).default,
  }
})

Legg til middleware for å prefikse ruter med locale:

// middleware.ts
import createMiddleware from 'next-intl/middleware'
import { locales, defaultLocale } from './i18n'

export default createMiddleware({
  locales: [...locales],
  defaultLocale,
  localePrefix: 'as-needed',
})

export const config = {
  matcher: ['/((?!api|_next|.*\..*).*)'],
}

Flytt sidefilene dine under app/[locale]/. Oppdater rotlayouten din til å motta locale-parametere og pakk inn barn med NextIntlClientProvider:

// app/[locale]/layout.tsx
import { NextIntlClientProvider } from 'next-intl'
import { getMessages } from 'next-intl/server'

export default async function LocaleLayout({
  children,
  params,
}: {
  children: React.ReactNode
  params: Promise<{ locale: string }>
}) {
  const { locale } = await params
  const messages = await getMessages()
  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider messages={messages}>
          {children}
        </NextIntlClientProvider>
      </body>
    </html>
  )
}

Steg 3: Ekstraher strengene dine til en JSON-meldingsfil (10 minutter)

Lag en messages/-mappe i prosjektets rotmappe. Legg til en en.json-fil med kildestrengene dine. next-intl bruker en nestet nøkkelstruktur:

{
  "Home": {
    "title": "Welcome",
    "cta": "Get started"
  }
}

Oppdater sidene dine til å bruke useTranslations i stedet for hardkodede strenger:

// app/[locale]/page.tsx
import { useTranslations } from 'next-intl'

export default function HomePage() {
  const t = useTranslations('Home')
  return (
    <main>
      <h1>{t('title')}</h1>
      <button type="button">{t('cta')}</button>
    </main>
  )
}

Skriv nå oversettelsesskriptet. Dette leser messages/en.json, sender det til PolyLingo API med format: "json", og skriver én utdatafil per mål-locale. format: "json"-flagget forteller API-en å bevare nøkkelstrukturen og bare oversette strengverdier — nestede nøkler, arrays og ikke-streng-typer kommer tilbake uendret.

// scripts/translate-messages.mjs
// Run with: node scripts/translate-messages.mjs

import fs from 'node:fs'
import path from 'node:path'

const API_KEY = process.env.POLYLINGO_API_KEY
const API_URL = (process.env.POLYLINGO_API_URL || 'https://api.usepolylingo.com/v1').replace(/\/$/, '')
const TARGETS = ['de', 'fr'] // extend this array to add more locales

const enPath = path.join('messages', 'en.json')
const en = JSON.parse(fs.readFileSync(enPath, 'utf8'))

const res = await fetch(`${API_URL}/translate`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    content: JSON.stringify(en),
    format: 'json',
    targets: TARGETS,
    model: 'standard',
  }),
})

if (!res.ok) {
  const err = await res.text()
  throw new Error(`PolyLingo ${res.status}: ${err}`)
}

const { translations } = await res.json()

for (const locale of TARGETS) {
  const out = path.join('messages', `${locale}.json`)
  fs.writeFileSync(out, JSON.stringify(JSON.parse(translations[locale]), null, 2) + '\n')
  console.log('Wrote', out)
}

Kjør det:

node scripts/translate-messages.mjs

Du bør se output som:

Wrote messages/de.json
Wrote messages/fr.json

Åpne disse filene og sjekk dem. Nøklene dine vil være identiske med en.json. Bare strengverdiene vil ha endret seg.


Steg 4: Rask test av rutene (5 minutter)

Start utviklingsserveren din:

npm run dev

Besøk http://localhost:3000 og http://localhost:3000/de. Overskriften og knappen skal vises på henholdsvis engelsk og tysk. Legg til flere locales ved å utvide TARGETS-arrayen i skriptet og locales-arrayen i i18n.ts, og kjør skriptet på nytt.

Sjekk token-bruken din i PolyLingo-dashbordet under Usage. For en liten locale-fil oversatt til to språk har du brukt noen hundre tokens av din månedlige kvote.


Hvor går du herfra

Legg til flere locales. Skriptet sender én forespørsel uansett hvor mange oppføringer som er i TARGETS. Å legge til japansk, spansk og arabisk koster én API-kall, ikke tre.

Koble det til CI. Legg til POLYLINGO_API_KEY som et repository secret i GitHub Actions og kjør skriptet som en del av byggeprosessen. Locale-filene dine holdes automatisk synkronisert når en.json endres.

Oversett andre formater. Samme skriptmønster fungerer for Markdown-dokumentasjonssider (format: "markdown") og HTML-e-postmaler (format: "html"). API-en bevarer strukturen i alle tilfeller.

Bruk batch-endepunktet for større prosjekter. Hvis du har flere separate JSON-filer (én per funksjonsområde, for eksempel), aksepterer POST /translate/batch opptil 100 elementer i én enkelt forespørsel, hver med sin egen id og format.


Prøv det gratis

PolyLingos gratisnivå inkluderer 100 000 tokens per måned. Ingen kredittkort kreves.

curl -sS -X POST "https://api.usepolylingo.com/v1/translate" \
  -H "Authorization: Bearer $POLYLINGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "{\"Home\":{\"title\":\"Welcome\",\"cta\":\"Get started\"}}",
    "format": "json",
    "targets": ["de", "fr", "es", "ja"]
  }'

Hent din API-nøkkel