Add i18n: per-instance participant language + admin UI language toggle #3
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
The app currently has hardcoded mixed locales:
/,/login,/admin/feedback*): English/f/<slug>): German (chrome strings: "Senden", "Absenden", "Fragebogen", "Live-Feedback", "Dein Name (optional)", etc.)m: "i18n is what we need." We want proper internationalization — the language of any given screen should be controlled, not hardcoded in either tongue.
Scope
A. Participant page — language is per-instance
The author who creates an instance picks its participant-facing language at create-time. The participant page renders chrome strings in that language. Question labels stay author-supplied (already free-form in
form_definition).feedback_instances.locale TEXT NOT NULL DEFAULT 'de'(or'en'— m to confirm default; current production has German participant chrome, so'de'keeps existing behaviour).de,en. Easy to extend tofr,nl,eslater./admin/feedback/newand the Edit tab on detail page: a small select dropdown labelled "Participant language" / "Teilnehmer-Sprache"./f/<slug>readsinstance.localeand renders all chrome strings in that locale.B. Admin UI — language is per-admin (cookie-stored preference)
Admin can switch their UI language (English ↔ German) and the choice persists across sessions.
fdbck-admin-locale=en|de(httpOnly NOT needed — client-readable is fine).+layout.server.tsreads the cookie and exposeslocalein$page.data/locals./admin/feedback): a<select>or two icon buttons (🇬🇧 🇩🇪).en.C. String table
A simple JSON-based string table — no i18n library dependency for v1. Two files:
src/lib/i18n/admin.tsexporting{ en: {...}, de: {...} }keyed by string IDsrc/lib/i18n/participant.tslikewiseA tiny helper:
t(locale, key)that falls back to the source locale (enfor admin,defor participant) if a key is missing.If the table grows past ~200 keys we can swap in
svelte-i18norparaglidelater — stay lib-free for v1.D. Code-side audit
Scan every
.sveltefile insrc/routes/for hardcoded chrome strings and replace witht('key')calls. Big buckets:src/routes/+page.svelte— landingsrc/routes/login/+page.sveltesrc/routes/admin/feedback/+page.svelte— list + new-CTAsrc/routes/admin/feedback/new/+page.svelte— create formsrc/routes/admin/feedback/[id]/+page.svelte— detail (tabs, share, edit)src/lib/components/FormBuilder.svelte— admin-sidesrc/lib/components/Results.svelte— admin-side aggregate displaysrc/routes/f/[slug]/+page.svelte— participant chrome (the German strings)Out of scope
label_de+label_en).Acceptance
/admin/feedback/newcan pick German or English for the participant page..sveltefiles.How to work
Single branch, multi-commit (string table → admin switcher → participant switcher → audit-and-replace). After merge, smoke all 6 routes in both locales. Probably a half-day's work.