i18n: InviteAcceptPage and buildInviteEmail() bypass the locale system (still English when site locale is non-English) #1758
khoinguyenpham04
announced in
Roadmap
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
This Roadmap discussion mirrors #915: i18n: InviteAcceptPage and buildInviteEmail() bypass the locale system (still English when site locale is non-English).
Use this discussion to upvote the roadmap item and discuss priority, use cases, and product feedback. Keep implementation tracking, reproduction details, and PR-specific feedback on the source issue.
roadmap/1.0,roadmap/data-safetyOriginal Issue
Summary
With
emdash:locale = "ja"set on a site that has otherwise switched to Japanese, the invite acceptance page and invite email template remain in English. Both surfaces bypass the lingui i18n machinery used elsewhere in the admin and auth packages.Repro
emdash:locale = "ja"in theoptionstable./_emdash/admin/...(settings, content list, etc.) renders in Japanese — locale is being picked up correctly.Send invite. The recipient gets an English email:You've been invited to <siteName>You've been invited to join <siteName>. Click this link to create your account: <url>/admin/invite/accept?token=.... The page renders the following English strings:You've been invited!You'll be joining as <ROLE>Email(label)Your name (optional)(label)Create your passkey(heading)Passkeys are a secure, passwordless way to sign in using your device's biometrics, PIN, or security key.Create Account(button)Why
Two distinct hard-coded surfaces:
1.
@emdash-cms/admin—InviteAcceptPage.tsxLooking at the bundled
dist/index.js(v0.9.0), theInviteAcceptPageRegisterStepcomponent places the strings directly inside JSXchildrenrather than wrapping them with the<Trans>macro / lingui catalog. The strings have no message id inlocales/ja/messages.mjs(verified by greping forjoining,invited,Your name, etc. — no matches for these specific phrases, while sibling passkey strings are translated).2.
@emdash-cms/auth—buildInviteEmail()insrc/invite.tsThe function returns a hard-coded English subject + text + HTML body. It receives
siteNameonly — no locale parameter — and therefore no way to render localized copy without a fork.Additionally, the email pipeline's
EmailPipeline.sendInner()skipsemail:beforeSendforsource === "system"to protect auth tokens, so plugins cannot rewrite invite/magic-link bodies via hooks. This makesbuildInviteEmailthe only place where localization can happen.Expected
InviteAcceptPagestrings flow through the same<Trans>/ lingui catalog that the rest of the admin uses, with corresponding entries inlocales/<lang>/messages.mjs.buildInviteEmail()(and any other system-email builders — magic-link, password recovery) accepts alocaleargument or reads the active site locale and selects a template per language.Workaround
None inside an EmDash project: plugin hooks can't rewrite system emails, and the admin SPA strings are baked into the published bundle. Sites either tolerate the mixed-language UX or fall back to the "copy invite link and share manually" flow.
Environment
emdash@0.9.0@emdash-cms/admin@0.9.0@emdash-cms/auth@0.9.0@emdash-cms/cloudflare@0.9.0All reactions