>_EXECUTIVE SUMMARY
zpwr-i18n is the shared internationalization runtime of the MenkeTechnologies GUI stack — one portable, host-agnostic vanilla-JS file. The appFmt formatter and the applyUiI18n DOM appliers were lifted verbatim from the Audio-Haxor front end (ipc.js + i18n-ui.js); the only change is the loader, which fetches plain JSON catalogs instead of Audio-Haxor's SQLite-backed Tauri command.
Because the loader is just fetch + Object.assign, the same runtime works in Tauri apps (Audio-Haxor, traderview, ztranslator) and JUCE WebViews (synth, fx, midi-fx, daw). It has no build step and no dependencies — it attaches its API to window and never throws on a missing catalog: appFmt falls back to the key so an untranslated UI still reads.
~ARCHITECTURE
One file, two layers: a verbatim format/apply layer from Audio-Haxor, plus a portable JSON loader. State lives in window.__appStr (aliased window.__toastStr for legacy call sites). Everything else attaches to window.
| Layer | Implementation |
|---|---|
| Format | appFmt(key, vars) reads __appStr[key] and interpolates {name} via a single String.replace; missing/empty returns the key. Exposed as appFmt, toastFmt, and t |
| Apply | applyUiI18n() walks [data-i18n] / [data-i18n-title] / [data-i18n-placeholder] (+ -regex) elements; placeholder values decode / to newlines |
| Load | loadLocale calls fetchCatalog (fetch, cache: 'no-store') for the app catalog, merges each extraBases fragment on top with Object.assign, replaces __appStr, persists, then applies. fetchCatalog returns {} on any error — never throws |
| Detect | detectLocale: saved choice → exact navigator.languages match → language-only match → en. normalizeUiLocale validates against the frozen SUPPORTED_UI_LOCALES |
| Persist | persistLocale / savedLocale use the shared window.prefs store when present, else localStorage, under key uiLocale |
| Boot | bootI18n(locale?) = loadLocale(locale || detectLocale()); called once after the DOM exists |
&WINDOW API SURFACE
12 public symbols on window (plus internal state __appStr / __toastStr and optional config __i18nBase / __i18nExtraBases). No exports, no modules — a classic <script> that populates globals.
| Symbol | Role |
|---|---|
appFmt / toastFmt / t | look up + interpolate a key; three aliases of the same function |
applyUiI18n | apply the catalog to all data-i18n* elements |
applyI18nPlaceholders | apply only the placeholder pass (regex-toggle aware) |
loadLocale | fetch + merge + apply + persist a locale |
bootI18n | boot convenience: detect then load |
mergeI18nCatalog | merge a shared-component fragment on top of __appStr |
detectLocale / savedLocale | best initial locale; the persisted choice |
normalizeUiLocale | validate a code against the supported set (else null) |
SUPPORTED_UI_LOCALES | frozen array of the 27 shipped locale codes |
/LOCALES & CATALOGS
The runtime ships 27 supported locale codes in the frozen SUPPORTED_UI_LOCALES array: cs da de el en es es-419 fi fr hi hu id it ja ko nb nl pl pt pt-BR ro ru sv tr uk vi zh. Catalogs are flat { "namespace.key": "string with {vars}" }, one JSON per locale at <base><locale>.json (default base i18n/). Hyphenated codes map to underscores in the filename via localeFile (es-419 → es_419.json, pt-BR → pt_BR.json). The locale JSON files are shipped by each host application (and by shared components such as zpwr-file-browser, merged via extraBases) — this repo carries the runtime, not the catalogs.
+MARKUP CONTRACT
| Attribute | Effect |
|---|---|
data-i18n | sets textContent |
data-i18n-title | sets the title attribute |
data-i18n-placeholder | sets an input placeholder (decodes / ) |
data-i18n-placeholder-regex | alternate placeholder when the enclosing .search-box has an active .btn-regex |
$CI GATES
zpwr-i18n is a non-Rust shared component, so it skips the Cargo polish gates. The umbrella MenkeTechnologiesMeta repo pins its docs through the house docs-conformance suite:
| Gate | Pins |
|---|---|
| HTML structure | <!DOCTYPE html>, charset, html lang="en", viewport + description meta, at least one <h1> |
| Link hygiene | all external href/src are https://; no placeholder hrefs; target="_blank" carries rel="noopener noreferrer" |
| No inline JS | no inline event handlers; behavior lives in hud-theme.js |
| Brand consistency | <title> mentions zpwr-i18n; breadcrumb GitHub URLs point at the owning repo |
| Cross-links | index.html and report.html link each other; referenced CSS/JS exist in docs/ |
#PROJECT METADATA
| Item | Value |
|---|---|
| Runtime | vanilla JS (no build step, no bundler) |
| Source | webui/i18n.js — one file, 153 lines, zero dependencies |
| API | 12 public symbols on window |
| Locales | 27 (SUPPORTED_UI_LOCALES) |
| Hosts | Tauri WebViews + JUCE WebViews |
| Origin | extracted verbatim from the Audio-Haxor front end; JSON loader swapped in |
| Author | MenkeTechnologies |
| Repository | github.com/MenkeTechnologies/zpwr-i18n |
| Meta umbrella | MenkeTechnologiesMeta |