Skip to content

Add de-AT locale and fix hardcoded English text in the unsubscribe confirmation notice - #1393

Open
caichat wants to merge 1 commit into
Mailtrain-org:v2from
caichat:feature/de-at-locale
Open

Add de-AT locale and fix hardcoded English text in the unsubscribe confirmation notice#1393
caichat wants to merge 1 commit into
Mailtrain-org:v2from
caichat:feature/de-at-locale

Conversation

@caichat

@caichat caichat commented Aug 6, 2026

Copy link
Copy Markdown

Title: Add de-AT locale and fix hardcoded English text in the unsubscribe confirmation notice

Summary

  • Adds de-AT (German - Austria) as a new supported locale: registered in shared/langs.js, loaded in server/lib/translate.js, enabled by default in config/default.yaml, and provided as a full translation file locales/de-AT/common.json (currently a copy of de-DE).
  • Fixes server/views/subscription/web-confirm-unsubscription-notice.mjml.hbs, where the heading and body text were hardcoded in English instead of going through {{#translate}}. This affected every language, not just the new one — even a visitor with an exact de-DE match would have seen this page half in English.

Motivation

We run Mailtrain for German-speaking (Austrian) recipients and want the public subscription/unsubscribe pages to be in German. In practice they kept rendering in English. Digging into it (see #<ISSUE_NUMBER_HERE>) turned up two separate causes:

  1. getLangCodeFromExpressLocale() only matches a locale if it's an exact string match against enabledLanguages. Austrian browsers commonly send de-AT as their top Accept-Language preference, which never matches de-DE, so the request silently falls back to defaultLanguage. Registering de-AT as its own locale (rather than trying to normalize region variants down to a base language, which would be a bigger change) was the more surgical fix given the current architecture.
  2. While testing, we found that web-confirm-unsubscription-notice.mjml.hbs never used {{#translate}} for its main text in the first place — it was plain English baked into the template. No locale, including the already-supported de-DE, would have translated it. Only the button label (returnToOurWebsite) was wired through the translation system. This PR wraps the two missing strings in {{#translate}} and adds the corresponding almostFinished / weNeedToConfirmYourEmailAddressToUnsubscribe keys.

What's intentionally not in this PR

  • A general region-fallback (de-ATde-DE, en-GBen-US, etc.) instead of hardcoding individual region variants. Registering languages one at a time doesn't scale, but felt like a separate, larger change to the locale-resolution logic. Filed as a follow-up in #<ISSUE_NUMBER_HERE> together with a proposal for a www.publicIgnoreBrowserLocale option (public pages always use defaultLanguage, ignoring the visitor's browser, independent of the trusted/admin interface).
  • Other "notice" templates (web-subscribed-notice, web-updated-notice, web-unsubscribed-notice, web-manual-unsubscribe-notice, web-confirm-subscription-notice, web-privacy-policy-notice, ...) likely have the same hardcoded-text pattern. We only touched the one we hit in testing; happy to do a pass over the rest in a follow-up PR if that's welcome.
  • locales/de-AT/common.json is a straight copy of locales/de-DE/common.json plus the two new keys — i.e. machine/human-identical German, not a distinct Austrian-German translation. Treat it as "unblocks de-AT users" rather than "adds Austrian-specific wording."

Testing

  • Verified locally that a request with Accept-Language: de-AT now resolves to the de-AT resource bundle instead of falling back to en-US.
  • Verified web-confirm-unsubscription-notice.mjml.hbs now renders fully in the resolved language (previously only the button was translated).
  • Confirmed the app still starts and serves de-DE, en-US, and the other existing languages unchanged.

…nslate hardcoded strings in web-confirm-unsubscription-notice
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