sveltejs / sveltejs/kit

Public API for building and selecting client variants

Open
#16,500 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

vite
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.