Skip to content

Latest commit

 

History

History

README.md

Examples

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.

Routing

multi-page — the common case · run it

  • several routes, no locale in the URL
  • preferredLocale reads a lang cookie; Accept-Language comes next
  • one namespace per route, and a translated error page
  • Arabic as a right-to-left locale: dir follows the locale
  • @sveltejs/adapter-node

locale-param — the locale in the query string · run it

  • /about?lang=cs: preferredLocale reads 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: preferredLocale reads the path
  • entries() 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

  • /about is English, /cs/about is Czech, whatever the browser asks for
  • a 404.html fallback shell, so the error page is yours and arrives translated on the first hit
  • the routing the documentation site itself uses
  • @sveltejs/adapter-static

Component-scoped translations

component-scoped-csr · run it

  • 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

component-scoped-ssr · run it

  • the same component, loaded by the page and handed down as a snapshot({ records: true }) its instance applies with hydrate()
  • complete on the first render, still reactive afterwards

Content

mdsvex · run it

  • a .svx route: t() in Markdown, route-scoped loading, prerendered per locale

Extensions

stores — the $t store surface · run it

  • @sveltekit-i18n/extension-stores in the config handed to defineI18n(): use() and get() hand out $t, $l, $locale and $loading
  • a language switcher bound to $locale, the way v2 wrote it
  • one page, @sveltejs/adapter-node

How to use an example

Copy the directory out of this repository and install:

npm install          # or pnpm install, yarn, …
npm run dev -- --open

Inside 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.

In CI

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.