Skip to content

Translate the interface into nine languages with a language picker - #8

Merged
pythonicode merged 3 commits into
feat/responsive-layoutfrom
feat/i18n
Oct 16, 2026
Merged

pythonicode merged 3 commits into
feat/responsive-layoutfrom
feat/i18n

Conversation

@pythonicode

Copy link
Copy Markdown
Owner

Summary

Adds the interface in nine languages: English, Svenska, Norsk bokmål, Suomi, Dansk, Español, Français, Português (Brasil) and Português (Portugal). Chinese and Japanese are not included.

  • Dictionary. src/locales/en.json is the source. Each other language is a JSON file with the same keys and placeholders. src/i18n/ holds the core: t(), useT(), language detection, and switching.
  • Language picker. In the status bar on desktop and compact layouts, and in the touch Style sheet. Switching takes effect immediately and is remembered.
  • Detection. The saved choice first, then the browser's languages (for example sv-SE → Svenska, nn → Bokmål, pt → Brazilian Portuguese), then English. The language loads before the first render.
  • Coverage. Toolbars, menus, dialogs, tooltips, status bar, annotations, GPX dialogs, project library, error messages, the exported sidebar heading, and <html lang>.
  • Legal text stays in English, with a note in each language that the English version is binding.
  • Offline. Language packs are excluded from the service worker precache and cached when first used, so installing the app does not download every language.
  • Layout. Text wrapping breaks words wider than a column (long Finnish compounds). The tool palette is wider so the longest labels fit.

Translations are my own first drafts. They are not reviewed by a native speaker or by the national orienteering federations, so please have someone check them, especially orienteering terms.

Not in this PR

  • Exported PNGs use the system font stack, which covers the accented Latin letters these languages need. Embedded fonts are only needed for Chinese and Japanese, which are dropped.
  • Pace stays in /km for every language. Decimal separators in distances follow the app language.

Testing

  • bun run test (65 pass). The new tests check that every language has exactly the English keys and placeholders, that no translation is empty, that browser language tags map to the right language, and that long words wrap.
  • bun run lint, bun run build pass.
  • In the browser: Finnish and European Portuguese, switched at runtime and after reload, checked on the phone layout (Style sheet picker, bottom toolbar and labels) and the desktop layout. No text clipped or off-screen in the automated check.
  • Not checked on a real device, or with every language at every width.

Stacked on feat/responsive-layout, which carries the pinch-zoom fix that is still waiting to merge into main (#7).

🤖 Generated with Claude Code

pythonicode and others added 2 commits October 16, 2026 14:47
A small typed dictionary: English is the source, and each language is a JSON
file that must have the same keys and placeholders (checked by tests). Plurals
use Intl.PluralRules, and numbers and dates use the app language. Languages
load on demand; the saved choice is read before the first render.

Languages: English, Svenska, Norsk bokmål, Suomi, Dansk, Español, Français,
Português (Brasil), Português (Portugal). Legal text stays in English.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Moves user-facing text out of components and utilities into the dictionary:
toolbars, menus, dialogs, tooltips, error messages, the exported sidebar
heading and the project library. The language picker sits in the status bar
and in the touch Style sheet. Language packs are excluded from the service
worker precache and cached on first use. Exported PNGs keep the system font
stack, which covers the accented Latin letters these languages use.

Also: text wrapping breaks words wider than a column (long Finnish compounds),
the tool palette is wide enough for the longest labels, and the touch Style
sheet keeps the comment text size label clear of its slider.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
analysis Ready Ready Preview Oct 16, 2026 2:15pm UTC

The palette grew to fit translated labels (for example "Opacitet"),
overflowing its 56px grid column so the canvas sat under it. The palette now
has a fixed width shared with the grid column, and long labels are truncated
with an ellipsis; the full text is in each tool's tooltip.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
@pythonicode
pythonicode merged commit fa08b26 into feat/responsive-layout Oct 16, 2026
3 of 4 checks passed

This branch was successfully deployed

1 active deployment
Preview — 0cf3d1e8 Deployed Oct 16, 2026 by vercel[bot]
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