Locale in der URL
Standardmäßig steckt die Locale in einem Cookie, und die URL ändert sich nie. Mit routing: true bekommt stattdessen jede Locale außer der Standard-Locale ein eigenes Pfadpräfix.
Das Präfix #
Es wird genauso geschrieben wie die Locale selbst: locales: ['en-US', 'de-DE'] ergibt /en-US/some/url. Willst du lieber /de/, nenne die Locale de — eine zweite Zuordnung, die synchron bleiben müsste, gibt es nicht.
Drei Teile zum Einbinden #
handle aus der Einrichtung bleibt unverändert: Es liest das URL-Präfix bereits, sobald Routing aktiv ist. reroute kommt in eine eigene, universelle src/hooks.ts (nicht hooks.server.ts) — es entfernt das Präfix, bevor SvelteKit die Routen abgleicht, daher brauchen deine Route-Dateien kein [locale]-Verzeichnis.
export const { t, handle, reroute, localizeHref, localizedEntries } = createDialect({
// …messages as in Setup
locales: ['en-US', 'de-DE'],
defaultLocale: 'de-DE',
routing: true
});import type { Reroute } from '@sveltejs/kit/hooks';
import { reroute as dialect } from '#lib/i18n.js';
export const reroute: Reroute = dialect;Hinweis
reroute entscheidet nur, welche Route eine Anfrage trifft; die URL selbst behält ihr Präfix. event.url, die url einer Load-Funktion und page.url lauten deshalb /de-DE/about, genau wie in der Adresszeile. Zum Vergleich mit einer Route nimm route.id (/about) – darin steht nie eine Locale. Das gilt erst recht für Zugriffsprüfungen in Hooks: /de-DE/admin rendert dieselbe Route wie /admin, ein Guard auf event.url.pathname lässt es also durch.
Auslieferung aus einem Unterverzeichnis #
Setze paths.base wie gewohnt: svelte-dialect/kit liest es selbstständig aus, und das Locale-Präfix wird nach dem Basispfad gesucht, nicht anstelle davon.
sveltekit({ paths: { base: '/docs' } });Verlinken #
Nutze localizeHref für interne Links — ein nacktes href würde die Locale bei der Navigation verlieren. Es stellt die aktuelle Locale voran, und die Standard-Locale bekommt immer den Pfad ohne Präfix. Das ist gewöhnliche Navigation innerhalb einer Locale und braucht nie ein vollständiges Neuladen der Seite.
<a href={localizeHref('/about')}>About</a>Locale wechseln #
setLocale weiß bereits, ob Routing aktiv ist: Ist es das, führt der Wechsel auf dieselbe Seite unter dem neuen Präfix — bewusst eine vollständige Navigation, damit das ausgelieferte Dokument, die URL und die Laufzeit übereinstimmen.
Probier es aus #
Diese Seite in jeder Locale:
Prerendering der Adressen mit Präfix #
Ein statischer Build rendert nur, was der Crawler erreichen kann, und von den Seiten der Standard-Locale, bei denen er startet, verlinkt nichts auf /ru/.... localizedEntries vervielfacht deine Einstiegspfade über alle Locales für prerender.entries — ein funktionierendes Beispiel findest du in der vite.config.ts der Demo.
import { localizedEntries } from 'svelte-dialect/entries';
localizedEntries(['/', '/about'], { locales: ['en', 'ru'], defaultLocale: 'en' });
// → ['/', '/ru', '/about', '/ru/about']Was die URL bedeutet #
Das Präfix hat Vorrang vor Cookie und Accept-Language: Eine URL ist die ausdrückliche Anforderung einer bestimmten Version der Seite. Die Standard-Locale hat genau eine Adresse — /de-DE/some/url antwortet mit 308 auf /some/url, wenn de-DE die Standard-Locale ist. Mit detectOnBarePath: true antwortet ein Dokumentaufruf von /about, dessen Cookie oder Accept-Language ru nennt, stattdessen mit 307 auf /ru/about — standardmäßig aus. Ohne diese Option behält der Pfad ohne Präfix seine Adresse und zeigt die Locale, die Cookie oder Accept-Language gewählt haben (auf einer statischen Seite die Browsersprache), und die Standard-Locale nur, wenn keiner davon eine angebotene nennt.