Public API for building and selecting client variants
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 20.8k
- Forks
- 2.3k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 156
Description
Describe the problem
This feature request was drafted by Codex (GPT-5.6) and reviewed by @samuelstroschein.
Plugins sometimes need multiple specialized versions of a SvelteKit client build.
Paraglide JS's experimentalPerLocaleBuild, for example, builds one client graph per locale. Each graph receives a compile-time locale value, allowing Vite/Rolldown to tree-shake translations for every other locale.
The Vite-native implementation is available in opral/paraglide-js#728. It generates independent locale environments without rewriting emitted chunks.
SvelteKit currently owns its client entries, build orchestration, manifest processing, and render-time asset injection. Paraglide therefore cannot compose with SvelteKit without depending on private build output or renderer internals.
Describe the proposed solution
We need two public extension points. The API names below are illustrative.
Register client variants
kit.registerClientVariants({
namespace: 'paraglide',
variants: [
{ id: 'en', environment: { define: { STATIC_LOCALE: '"en"' } } },
{ id: 'de', environment: { define: { STATIC_LOCALE: '"de"' } } }
]
});
SvelteKit would build each variant using its normal generated client inputs and Vite/Rolldown pipeline. SvelteKit would retain ownership of output directories, manifests, adapters, and rendering. Plugins would never inspect or rewrite emitted chunks.
Select a variant during rendering
Extend ResolveOptions:
return resolve(event, {
clientVariant: { namespace: 'paraglide', id: locale }
});
The selection should apply atomically to entry scripts, imported chunks, stylesheets, fonts, module preloads, client routing metadata, and inline client code. The same selection should be honored during prerendering, allowing /en/about and /de/about to reference different client graphs.
Alternatives considered
The previous Paraglide experiment specialized completed bundles and integrated with private SvelteKit renderer/output shapes. That works as a prototype, but it couples plugins to internal build sequencing and generated artifacts.
Post-processing also creates avoidable restrictions around minification and source maps. The implementation in opral/paraglide-js#728 therefore makes a hard cut to native Vite environments and fails early when a framework owns build orchestration without exposing client-variant hooks.
Importance
nice to have
Additional Information
Bundle-size impact
Without per-locale builds, imported messages can include translations for every locale:
bundle = application + runtime + English + German + French + …
With per-locale builds, each visitor receives one specialized graph:
English graph = application + runtime + English
German graph = application + runtime + German
For similarly sized catalogs, the translation portion approaches 1 / numberOfLocales of the unsplit translation payload. The tradeoff is increased build time and deployment storage because shared application code may be emitted once per locale. The optimization targets bytes transferred to each visitor.
The prototype verifies that other locales' translations are absent from executable JavaScript and source maps. Native tree-shaking, minification, source maps, CSS, dynamic imports, custom asset paths, and renderBuiltUrl continue to work. Switching variants may use a full document reload, and SPA fallback support can initially fail with a clear error.
The same API could support white-label builds, regional configuration, and build-time product editions.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing SvelteKit’s client entries, build orchestration, manifest processing, render-time asset injection, and the ResolveOptions entry point described in the issue; compare the approach with the linked Paraglide implementation. Done means public registration and render-time selection atomically choose the variant’s scripts, chunks, styles, fonts, preloads, routing metadata, and inline client code during normal builds and prerendering.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, vite
- Domain
- build-system, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100