Skip to content

fix(#626): i18n (2/4): translation layer and German (Du) + English for the app shell and ev - #631

Merged
BeSovereign merged 1 commit into
mainfrom
fix/issue-626
Oct 20, 2026
Merged

BeSovereign merged 1 commit into
mainfrom
fix/issue-626

Conversation

@BeSovereign

Copy link
Copy Markdown
Contributor

Refs #626

Added a framework-free i18n layer (public/js/i18n.js, per-module catalogues in public/js/messages/, t() with plurals) with Deutsch (Du) and English for index.html, the app.js shell/settings/toasts and the event dialog; the language is the user's new preference, else navigator.languages, else Deutsch (Du) (fallback noted in CONCEPTS.md), and switching re-renders without reload. This round: the #166 reminder e2e test, which runs in an en-US browser and now gets English per CONCEPTS, pins the German setting to keep checking that a German screen shows the 24-hour clock, and the #626 spec resets the language preference after each test.

Driver gates (measured, not claimed)

  • Suites: lint: 1 passed, 0 failed | node: 2018 passed, 0 failed | python: 194 passed, 0 failed | e2e: 349 passed, 0 failed
  • Red/green check on declared tests: e2e/issue626_i18n.spec.js, e2e/calendar.spec.js, server/test/issue626_language_preference.test.js, server/test/issue108_search_kanban_empty_state.test.js, server/test/issue215_public_link_unsequenced_writers.test.js, server/test/issue220_unsequenced_calendar_navigation.test.js, server/test/issue226_failed_event_load_toolbar_sync.test.js, server/test/issue498_task_view_preference.test.js, server/test/issue509_secondary_timezone.test.js, server/test/issue517_week_numbers_preference.test.js, server/test/readonly_event_click_popover.test.js, server/test/status_bar_view_counts.test.js
red/green output
RED without the change:
───────────

  5 failed
    [chromium] › e2e/issue626_i18n.spec.js:52:1 › Issue #626 — switching the language re-renders the shell and the event dialog without reload 
    [chromium] › e2e/issue626_i18n.spec.js:100:3 › Issue #626 — an English browser › Issue #626 — without a setting an English browser gets English 
    [chromium] › e2e/issue626_i18n.spec.js:109:3 › Issue #626 — a browser in a language the app does not speak › Issue #626 — without a setting a French browser gets Deutsch (Du) 
    [chromium] › e2e/issue626_i18n.spec.js:114:3 › Issue #626 — a browser in a language the app does not speak › Issue #626 — the setting wins over the browser 
    [chromium] › e2e/issue626_i18n.spec.js:122:1 › Issue #626 — both catalogues hold the same keys, placeholders and plurals; t() fills them 


GREEN with the change:
s:52:1 › Issue #626 — switching the language re-renders the shell and the event dialog without reload (2.8s)
  ✓  2 [chromium] › e2e/issue626_i18n.spec.js:100:3 › Issue #626 — an English browser › Issue #626 — without a setting an English browser gets English (488ms)
  ✓  3 [chromium] › e2e/issue626_i18n.spec.js:109:3 › Issue #626 — a browser in a language the app does not speak › Issue #626 — without a setting a French browser gets Deutsch (Du) (455ms)
  ✓  4 [chromium] › e2e/issue626_i18n.spec.js:114:3 › Issue #626 — a browser in a language the app does not speak › Issue #626 — the setting wins over the browser (499ms)
  ✓  5 [chromium] › e2e/issue626_i18n.spec.js:122:1 › Issue #626 — both catalogues hold the same keys, placeholders and plurals; t() fills them (439ms)

  5 passed (7.6s)

🤖 Generated with Claude Code

Added a framework-free i18n layer (public/js/i18n.js, per-module catalogues in public/js/messages/, t() with plurals) with Deutsch (Du) and English for index.html, the app.js shell/settings/toasts and the event dialog; the language is the user's new preference, else navigator.languages, else Deutsch (Du) (fallback noted in CONCEPTS.md), and switching re-renders without reload. This round: the #166 reminder e2e test, which runs in an en-US browser and now gets English per CONCEPTS, pins the German setting to keep checking that a German screen shows the 24-hour clock, and the #626 spec resets the language preference after each test.

Refs #626

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@BeSovereign

Copy link
Copy Markdown
Contributor Author

Security review (claude-fable-5-1): no blocking finding. Language preference allow-listed on route and by DB CHECK, test has teeth (400 + unchanged state). All t() results with user params are escaped before innerHTML or set via textContent; catalogues hold no markup; translateDom only touches static data-i18n attributes. Suggest a test asserting catalogue strings contain no '<' to protect the escape-at-call-site convention.

@BeSovereign
BeSovereign merged commit a5d3c9d into main Oct 20, 2026
5 checks passed
@BeSovereign
BeSovereign deleted the fix/issue-626 branch October 20, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant