Repository navigation
feat(docs): split the docs site into per-locale wasm bundles - #309
Merged
Merged
Conversation
All locales used to compile into a single wasm bundle (2.24 MB), so every visitor downloaded every language and the shell tracked locale state at runtime. The build now pins one locale per bundle and the CLI builds one bundle per locale, mirroring the directory layout static i18n sites already use: the default locale at the output root, every other locale in its own directory (en/, ja/, ko/, …). build.rs gains the pin: EUV_DOCS_LOCALE selects the locale by prefix, directory, or label (unset → the default '/' locale), alias entries are resolved to their canonical directory, pages of other locales are dropped, and the pinned prefix is stripped from every route and internal link so in-bundle routes are prefix-free. Non-default bundles also rebase relative asset URLs (./img/… → ../img/…) because assets are copied only by the default build and hosted once at the site root. The generated code emits SITE_LANGUAGES (switcher entries, one per unique content directory), SITE_LOCALE_DIR (this bundle's directory), and SITE_REDIRECTS (foreign prefix → owning directory) next to SITE, and writes .deploy/locales.tsv so the CLI discovers the remaining locales without a second YAML parser. Runtime: the shell keeps rendering from SITE unchanged (it now contains exactly one locale); the language switcher reads SITE_LANGUAGES and switches via cross-directory navigation (Location::assign), which the old code already approximated with a full-page reload. A boot-time redirect before mount maps legacy single-bundle links (<root>/#/en/…) and alias prefixes (#/zh/…) onto the right bundle, so old links keep working. CLI: --locale <name> builds a single bundle for fast iteration; the default invocation builds the default locale, reads the manifest, then builds every remaining locale into its own sub-directory. The redundant CLI-side public/ copy is gone (build.rs owns assets now). Verified locally on the 632-page, 4-locale docs site: zh 984 KB, en 1.02 MB, ja 1.06 MB, ko 1.04 MB (down from 2.24 MB, -54~57% per visitor); each bundle renders only its own sidebar; the switcher preserves the current route across directories; legacy #/en/… links redirect to /en/#/…; the /zh/ alias rewrites in place; images load in every bundle; the TOC scroll spy still tracks.
vshengbro
added a commit
that referenced
this pull request
Oct 10, 2026
…cale refactor Resolve two semantic conflicts the auto-merge could not: - Cargo.toml version: keep 0.28.24. #309 set the workspace to 0.28.23, which is already published, so the bump has to land past it. - DocsLocale.label: #309 dropped the field from the generated locale and moved every label into the cross-bundle language switcher. locale_label_for now resolves a route's label out of SITE_LANGUAGES by prefix instead of reading the removed field. Also fix three §audits that #309 itself introduced: move LocaleManifestEntry out of bin/docs/fn.rs into struct.rs (a struct in a keyword file fails the purity rule), and give the retained resolve_locale_roots binding a name and type so the explicit-annotation rule passes. The call stays — it is what fails the build when a declared locale has no directory or no markdown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
All locales used to compile into a single wasm bundle (2.24 MB): every visitor
downloaded every language, and the shell resolved locale state at runtime. This
PR splits the build into one bundle per locale, mirroring the directory layout
static i18n sites already use — the default locale at the output root, every
other locale in its own directory (
en/,ja/,ko/, …).build.rs gains the pin:
EUV_DOCS_LOCALEselects the locale by prefix,directory, or label (unset → the default
/locale). Alias entries resolve totheir canonical directory; pages of other locales are dropped; the pinned prefix
is stripped from every route and internal link, so in-bundle routes are
prefix-free. Non-default bundles rebase relative asset URLs (
./img/…→../img/…) because assets are copied only by the default build and hosted onceat the site root. The generated code emits
SITE_LANGUAGES(switcher entries),SITE_LOCALE_DIR, andSITE_REDIRECTSnext toSITE, and writes.deploy/locales.tsvso the CLI discovers the remaining locales without asecond YAML parser.
Runtime: the shell keeps rendering from
SITEunchanged (it now containsexactly one locale); the language switcher reads
SITE_LANGUAGESand switchesvia cross-directory navigation (
Location::assign), which the old code alreadyapproximated with a full-page reload. A boot-time redirect before mount maps
legacy single-bundle links (
<root>/#/en/…) and alias prefixes (#/zh/…) ontothe right bundle, so old links keep working.
CLI:
--locale <name>builds a single bundle for fast iteration; the defaultinvocation builds the default locale, reads the manifest, then builds every
remaining locale into its own sub-directory. The redundant CLI-side
public/copy is gone (build.rs owns assets now).
Verification
Local build of the 632-page, 4-locale docs site (zh/en/ja/ko):
Per-visitor download drops 54–57%. Assets are hosted once at the site root
(total site ~59 MB; naive per-locale asset copies would have been ~214 MB).
Browser-verified on the built output:
are the known untranslated LICENSE page titles, a content gap tracked
separately, not a routing bug)
(
/#/ltpp/version.html→/en/#/ltpp/version.html)/#/en/ltpp/version.htmlredirect to the enbundle; the
#/zh/…legacy alias rewrites in place to#/…../markdown-images/…,11/11 natural-width OK; zh unchanged, 11/11 OK)
--locale enproduces a single-bundle build with no locale subdirectoriescargo fmt --check clean, clippy --workspace --all-targets 0 warnings, full
workspace test suite passing. Version 0.28.23, workspace pins realigned.
Deploy notes
No workflow change needed in docs-pages/docs: the deploy installs the euv-docs
CLI from master and runs
euv-docs docs --out www, which now emits theper-locale layout (
www/en/, …) thatcp -r www/*pushes as-is.