Skip to content

feat(THU-824): localize transactional email and let users pick a language - #1255

Merged
raivieiraadriano92 merged 9 commits into
mainfrom
raivieiraadriano92/thu-824-localize-transactional-email-from-userlocale
Sep 3, 2026
Merged

feat(THU-824): localize transactional email and let users pick a language#1255
raivieiraadriano92 merged 9 commits into
mainfrom
raivieiraadriano92/thu-824-localize-transactional-email-from-userlocale

Conversation

@raivieiraadriano92

@raivieiraadriano92 raivieiraadriano92 commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Localizes the four transactional emails (magic-link, waitlist-joined, waitlist-not-ready, waitlist-reminder) and adds a language picker to the waitlist screen so users can choose before they ever have an account.

Locale comes from X-App-Language, not a persisted column. The ticket asked for user.locale, but no such column exists and no async send path does either — every email goes out inside a request from the recipient's own client. Three of the four go to people with no user row at all, so a column would be NULL for exactly those recipients. The header is already sent by every client, and shared/i18n/locales.ts was written in anticipation of the backend reading it.

No Lingui macros on the backend. Bun has no Babel pass, so a macro import resolves to Lingui's stub and throws when called — and shouldSkipEmail() hides that in dev and test, so it would surface first in production on the sign-in path. Backend copy uses the plain i18n._({ id }) runtime instead, which extracts identically, and a lint rule bans the macro specifiers.

Catalogs. backend/lingui.config.ts owns a second, small .po catalog compiled to committed .ts (Bun has no .po loader). Same gettext format and same locale set as the frontend, so translators see one pipeline. All 14 strings are translated in de/fr/es/pt-BR/ja.

Testing

bun run test:backend · bun run test · bun run i18n:check. Emails were sent end-to-end through Resend in every locale.

To see a localized email: send X-App-Language: <tag> to POST /v1/waitlist/join. Note the pseudo-locale is deliberately refused over the wire — it's reachable only via getEmailI18n('en-XA') in the preview and tests.

Notes for review

  • The translations are mine, not a native speaker's. Worth an l10n review of the German and Japanese paragraphs before this reaches users, and Pontoon (THU-827) will see them as existing strings to refine rather than blanks to fill.
  • Not fixed here: the 429 in waitlist/routes.ts sends English message text that the client renders verbatim, so a German user can still get a German email and an English toast from one click. The clean fix is a frontend mapping for code_already_sent, not localizing backend prose.

@raivieiraadriano92 raivieiraadriano92 self-assigned this Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

Semgrep Security Scan

No security issues found.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

PR Metrics

Metric Value
Lines changed (prod code) +1045 / -88
JS bundle size (gzipped) 🟢 638.2 KB → 638.9 KB (+732 B, +0.1%)
Test coverage 🟢 81.81% → 81.78% (+-0.0%)
Performance (preview) Preview not ready — Render deploy may have timed out
Accessibility
Best Practices
SEO

Updated Wed, 02 Sep 2026 17:33:56 GMT · run #2890

@raivieiraadriano92 raivieiraadriano92 changed the title Raivieiraadriano92/thu 824 localize transactional email from userlocale feat(THU-824): localize transactional email and let users pick a language Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

Preview environment destroyed 🧹

Stack preview-pr-1255 and its Cloudflare subdomain have been cleaned up.

@raivieiraadriano92
raivieiraadriano92 marked this pull request as ready for review September 2, 2026 17:36

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔭 thunder-deep-review (advisory)

Complements the other bots — surfaces only what they did not flag. Never approves, never requests changes, never gates merge.
head: a8b21984dc53 · mode: deep · deferred 0 item(s) already reported by other bots (best-effort dedup)

Comment thread backend/lingui.config.ts
@raivieiraadriano92
raivieiraadriano92 merged commit bd00644 into main Sep 3, 2026
45 of 46 checks passed
@raivieiraadriano92
raivieiraadriano92 deleted the raivieiraadriano92/thu-824-localize-transactional-email-from-userlocale branch September 3, 2026 18:09
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