Skip to main content

SvelteKit i18n: Oppsettsguide for internasjonalisering

Fra null til flerspråklig: sett opp svelte-i18n i SvelteKit-appen din med ICU-meldingsformat, språkbasert ruting og smarte fallback-kjeder.

1

Installer svelte-i18n

svelte-i18n er standardbiblioteket for internasjonalisering i Svelte og SvelteKit. Det tilbyr reaktive stores, støtte for ICU MessageFormat og lat innlasting av språk uten ekstra oppsett.

svelte-i18n bruker ICU MessageFormat for flertallsformer og variabler — den samme standarden som brukes av FormatJS/react-intl. Kommer du fra React, vil meldingssyntaksen være kjent.
Terminal
npm install svelte-i18n
2

Konfigurer svelte-i18n

Opprett en i18n-konfigurasjonsfil som registrerer språkene dine med lat-innlastede importfunksjoner. svelte-i18n henter kun meldingene til et språk når det språket aktiveres.

src/lib/i18n.ts
// src/lib/i18n.ts
import { register, init, getLocaleFromNavigator } from 'svelte-i18n';

// Register locale loaders (lazy-loaded)
register('en', () => import('../locales/en.json'));
register('de', () => import('../locales/de.json'));
register('ja', () => import('../locales/ja.json'));
register('es', () => import('../locales/es.json'));

init({
  fallbackLocale: 'en',
  initialLocale: getLocaleFromNavigator(),  // Auto-detect browser language
});
Du må importere i18n-konfigurasjonsfilen din i +layout.svelte før noen komponent gjengis. Hvis oversettelser viser rå nøkler som «nav.home», ble konfigurasjonen ikke importert tidlig nok.

Integrasjon med SvelteKit-layout

Importer i18n-konfigurasjonen din i rotlayouten, og styr gjengivelsen med $isLoading-storen. Dette forhindrer et blink av uoversatte nøkler mens språkdata lastes asynkront.

src/routes/+layout.svelte
<!-- src/routes/+layout.svelte -->
<script>
  // Import i18n config — must run before any component renders
  import '../lib/i18n';
  import { isLoading } from 'svelte-i18n';
</script>

{#if $isLoading}
  <p>Loading translations...</p>
{:else}
  <slot />
{/if}

Språkbasert ruting i SvelteKit

For SEO-vennlige URL-er som /en/about og /de/about, bruk en [lang]-ruteparameter. Sett svelte-i18n-språket i layoutens load-funksjon basert på URL-parameteren.

SvelteKit locale routing
// src/routes/[lang]/+layout.ts
import { locale } from 'svelte-i18n';

export function load({ params }) {
  // Set the active locale from the URL parameter
  locale.set(params.lang);
  return {};
}

// src/routes/[lang]/+layout.svelte
<script>
  import '../../lib/i18n';
  import { isLoading } from 'svelte-i18n';
</script>

{#if $isLoading}
  <p>Loading...</p>
{:else}
  <slot />
{/if}

Format for oversettelsesfiler

Opprett én JSON-fil per språk. svelte-i18n støtter nøstede nøkler og ICU MessageFormat-syntaks for flertallsformer, variabler og select-uttrykk.

Translation files
// src/locales/en.json
{
  "nav": {
    "home": "Home",
    "about": "About",
    "settings": "Settings"
  },
  "greeting": "Hello, {name}!",
  "cart": {
    "itemCount": "{count, plural, one {# item} other {# items}}"
  }
}

// src/locales/de.json
{
  "nav": {
    "home": "Startseite",
    "about": "Uber uns",
    "settings": "Einstellungen"
  },
  "greeting": "Hallo, {name}!",
  "cart": {
    "itemCount": "{count, plural, one {# Artikel} other {# Artikel}}"
  }
}
Navngi nøkler etter hva de beskriver, ikke hvor de vises: «cart.itemCount» er bedre enn «homepageCartLabel». Nøkler bør overleve redesign av brukergrensesnittet.
3

Bruk oversettelser i komponenter

Importer $_-storen (eller $format) fra svelte-i18n og bruk den i Svelte-malene dine. Storen er reaktiv — når språket endres, oppdateres alle oversatte strenger automatisk.

Component.svelte
<script>
  import { _ } from 'svelte-i18n';
</script>

<h1>{$_('greeting', { values: { name: 'World' } })}</h1>

<nav>
  <a href="/">{$_('nav.home')}</a>
  <a href="/about">{$_('nav.about')}</a>
</nav>
Formatting helpers
<script>
  import { _, date, number, time } from 'svelte-i18n';
</script>

<!-- Simple string -->
<p>{$_('greeting', { values: { name: userName } })}</p>

<!-- ICU plurals — handled automatically -->
<p>{$_('cart.itemCount', { values: { count: 3 } })}</p>

<!-- Date formatting -->
<p>{$date(new Date(), { format: 'long' })}</p>

<!-- Number formatting -->
<p>{$number(1999.99, { style: 'currency', currency: 'USD' })}</p>
$_ er en Svelte-store — du må bruke $-prefikset i maler. Skriver du _('key') uten dollartegnet, returneres storeobjektet, ikke den oversatte strengen.

Språkbytte

Bygg en språkvelger som er bundet til $locale-storen. Når verdien endres, laster svelte-i18n meldingene for det nye språket og oppdaterer alle oversatte strenger reaktivt.

LanguageSwitcher.svelte
<script>
  import { locale, locales } from 'svelte-i18n';

  const LANGUAGE_NAMES = {
    en: 'English',
    de: 'Deutsch',
    ja: '日本語',
    es: 'Espanol',
  };
</script>

<select bind:value={$locale}>
  {#each $locales as loc}
    <option value={loc}>{LANGUAGE_NAMES[loc] ?? loc}</option>
  {/each}
</select>
4

Håndter flertallsformer med ICU MessageFormat

svelte-i18n bruker ICU MessageFormat for flertallsformer — den internasjonale standarden som håndterer alle CLDR-flertallskategorier. Arabisk har 6 former, russisk har 4, japansk har 1. Definer formene målspråkene dine trenger, så velger svelte-i18n riktig form automatisk.

ICU plural forms by language
// svelte-i18n uses ICU MessageFormat for plurals
// English:
{
  "items": "{count, plural, one {# item} other {# items}}"
}

// Arabic (6 forms):
{
  "items": "{count, plural, zero {no items} one {item} two {two items} few {# items} many {# items} other {# items}}"
}

// Japanese (1 form):
{
  "items": "{count, plural, other {#個のアイテム}}"
}
Hardkod aldri logikk for entall og flertall i komponentene dine. Språk som fransk behandler 0 som entall. Arabisk, russisk og polsk har flertallsformer som engelsk ikke har. La ICU-flertallssyntaksen håndtere det.

Smarte reservekjeder for språkvarianter med svelte-i18n-locale-chain

svelte-i18n faller rett tilbake til fallbackLocale når en nøkkel mangler — det finnes ingen mellomliggende reserve. En pt-BR-bruker ser engelsk i stedet for helt gode pt-PT-oversettelser. svelte-i18n-locale-chain løser dette med smarte reservekjeder som slår sammen meldinger fra regionale varianter.

Terminal
npm install svelte-i18n-locale-chain svelte-i18n
src/lib/i18n.ts
// src/lib/i18n.ts
import { initLocaleChain, setLocale } from 'svelte-i18n-locale-chain';

// Replace svelte-i18n's init + register with initLocaleChain
await initLocaleChain({
  loadMessages: (locale) =>
    import(`../locales/${locale}.json`).then(m => m.default),
  defaultLocale: 'en',
  initialLocale: 'pt-BR',
});

// Later, to change locale:
await setLocale('fr-CA');
// fr-CA user sees: fr-CA messages -> fr messages -> en messages
// No missing keys — deep-merged automatically
svelte-i18n-locale-chain håndterer all meldingsinnlasting internt. Ikke bruk svelte-i18ns register()-funksjon sammen med den — initLocaleChain håndterer registrering, innlasting og sammenslåing.

Automatiser oversettelser

Når i18n-oppsettet er fullført, kan du oversette språkfilene dine ved hjelp av AI. I IDE-en din kan du be AI-assistenten om å oversette kildefilen, eller bruke i18n Agent-CLI-en i CI/CD-pipelinen din.

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

✓ de.json created (1.2s)
✓ ja.json created (1.5s)
✓ es.json created (1.1s)

# Or use the CLI in CI/CD:
npx i18n-agent translate src/locales/en.json --lang de,ja,es
Oversett trinnvis — når du legger til nye nøkler i kildefilen, bør du kun oversette diffen i stedet for å regenerere alle filene. Dette bevarer eventuelle manuelt gjennomgåtte oversettelser.

Automatiser oversettelseskvalitet

Fang opp manglende nøkler og ødelagte plassholdere før de driftsettes, med i18n-validate. Test brukergrensesnittet med pseudo-oversettelser ved hjelp av i18n-pseudo før de virkelige oversettelsene er klare.

Vanlige fallgruver

SSR-språklekkasje i SvelteKit

svelte-i18n-stores er singletons. I SvelteKit SSR deler samtidige forespørsler den samme storen — én brukers språk kan lekke inn i en annen brukers respons. Løsning: kall locale.set() i handle-hooken eller layoutens load-funksjon, slik at hver forespørsel får riktig språkkontekst.

Bruk av register() sammen med svelte-i18n-locale-chain

Ikke bruk svelte-i18ns register()-funksjon hvis du bruker svelte-i18n-locale-chain. initLocaleChain håndterer all meldingsinnlasting internt. Å blande begge fører til duplisert eller motstridende meldingsinnlasting.

ICU-syntaksfeil feiler stille

En klammeparentes uten motstykke eller en manglende flertallskategori i ICU MessageFormat-strenger forårsaker stille feil — den rå meldingsstrengen vises i stedet for det formaterte resultatet. Valider ICU-syntaksen i CI-pipelinen din.

Blink av uoversatt innhold

Hvis du rendrer komponenter før oversettelsene er ferdig lastet, ser brukerne rå nøkler. Beskytt layouten din med {#if $isLoading}...{:else}...{/if} for å vise en lastetilstand til meldingene er klare.

Anbefalt filstruktur

Project Structure
my-sveltekit-app/
├── src/
│   ├── lib/
│   │   └── i18n.ts              # i18n configuration
│   ├── locales/
│   │   ├── en.json              # Source language
│   │   ├── de.json              # German
│   │   ├── ja.json              # Japanese
│   │   └── es.json              # Spanish
│   └── routes/
│       ├── +layout.svelte       # Import i18n, guard isLoading
│       ├── +page.svelte
│       └── [lang]/              # Optional: locale-based routing
│           ├── +layout.ts       # Set locale from URL param
│           ├── +layout.svelte
│           └── +page.svelte
├── svelte.config.js
└── package.json

Prøv i18n Agent nå

Slipp oversettelsesfilen din her

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

eller klikk for å bla gjennom

Målspråk

Ingen registrering krevesUmiddelbart estimat

Språkfallback med svelte-i18n-locale-chain

Når en oversettelsesnøkkel mangler i et regionalt språk som pt-BR, hopper svelte-i18n rett til standardspråket i stedet for først å sjekke det overordnede språket pt.

Terminal
npm install svelte-i18n-locale-chain
Configuration
import { initLocaleChain } from 'svelte-i18n-locale-chain';

initLocaleChain({
  fallbacks: {
    'pt-BR': ['pt', 'en'],
    'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
  },
  defaultLocale: 'en',
});

Se guiden vår for språkfallback for den fullstendige listen over støttede rammeverk og 75 innebygde kjeder. Learn more →

Ofte stilte spørsmål