Each directory is a standalone SvelteKit application on sveltekit-i18n 3.x.
They cover the application-shaped decisions — an adapter, a
svelte.config.js, a hooks.server.ts, a route tree — the things that are hard
to get right from a snippet. Every one of them wires SvelteKit through
sveltekit-i18n/kit; what sets them apart is mostly where preferredLocale
reads the locale from.
They are written in TypeScript, and each generates its schema with
@sveltekit-i18n/typegen, so a
key that is not in the catalogue is a type error — see
multi-page.
Everything that is really three lines of configuration lives on the
playground instead, where a real
instance answers as you change it: message formats (parser-curly,
parser-icu, parser-mf2, parser-i18next), config.preprocess,
config.loaders matching and freshness, and config.fallbackLocale.
Each run it below opens that directory in
StackBlitz, which boots Node and the dev server inside
the browser tab and lands on the example's config. Nothing is installed, and
nothing is deployed that could drift from what is in this repository.
The @rolldown/binding-wasm32-wasi entry in each example's
optionalDependencies is what lets that work. Vite 8 builds with rolldown,
which loads a native binding no browser sandbox can execute; rolldown ships a
WebAssembly fallback but stopped declaring it in 1.2.2, so nothing installs it
on its own. Drop the entry once rolldown declares it again.
multi-page — the common case · run it
- several routes, no locale in the URL
preferredLocalereads alangcookie;Accept-Languagecomes next- one namespace per route, and a translated error page
- Arabic as a right-to-left locale:
dirfollows the locale @sveltejs/adapter-node
locale-param — the locale in the query string · run it
/about?lang=cs:preferredLocalereads the query, on the server before rendering- internal links carry the locale; the default locale keeps the bare URL
- not the SEO option — a query parameter is the same page to a crawler
@sveltejs/adapter-node
locale-router — the locale in the path, prerendered · run it
/en/about,/cs/about,/de/about:preferredLocalereads the pathentries()for what the crawler cannot discover on its own@sveltejs/adapter-node, everything prerendered
locale-router-static — the same, with no server · run it
- one HTML file per page per locale
- an unknown URL is the host's 404, not the app's
@sveltejs/adapter-static
locale-router-advanced — the default locale has no prefix · run it
/aboutis English,/cs/aboutis Czech, whatever the browser asks for- a
404.htmlfallback shell, so the error page is yours and arrives translated on the first hit - the routing the documentation site itself uses
@sveltejs/adapter-static
- a component with its own instance and its own lexicon, loaded in the browser
- not in the server-rendered HTML — the trade-off, shown deliberately
- the same component, loaded by the page and handed down as a
snapshot({ records: true })its instance applies withhydrate() - complete on the first render, still reactive afterwards
- a
.svxroute:t()in Markdown, route-scoped loading, prerendered per locale
stores — the $t store surface · run it
@sveltekit-i18n/extension-storesin the config handed todefineI18n():use()andget()hand out$t,$l,$localeand$loading- a language switcher bound to
$locale, the way v2 wrote it - one page,
@sveltejs/adapter-node
Copy the directory out of this repository and install:
npm install # or pnpm install, yarn, …
npm run dev -- --openInside this repository the examples resolve sveltekit-i18n through the
workspace, so they always build against the current source. On their own they
resolve the published package.
Every example is built on each change under examples/**, and the build output
is checked for a known translated string. An exit code proves nothing here: once
handleError returns a well-formed error, a prerender writes an error page for
every route and still succeeds.