ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Nhost 多语言邮件模板生成指南:基于 React Email 为 Auth 服务添加新 locale

Nhost 多语言邮件模板生成指南:基于 React Email 为 Auth 服务添加新 locale Nhost 多语言邮件模板生成指南基于 React Email 为 Auth 服务添加新 locale【免费下载链接】nhostThe Open Source Firebase Alternative with GraphQL.项目地址: https://gitcode.com/GitHub_Trending/nh/nhostNhost 的 Auth 服务内置了一套基于 React Email 为主线完整讲解如何用pnpm dev:email实时预览模板、用pnpm generate:emails locale为一个新语言环境批量生成邮件模板并深入render-emails.ts、Go 端模板渲染器与测试用例说明这套本地化流水线的底层工作原理。读完本文你将能独立为 Nhost Auth 新增任意 locale 的邮件模板并理解占位符变量与回退机制。一、背景Nhost Auth 的多语言邮件模板体系在 Nhost 仓库中Auth 服务的邮件模板集中存放在 services/auth/email-templates 目录下目前内置了以下 localeservices/auth/email-templates/ ├── bg/ # 保加利亚语 ├── cs/ # 捷克语 ├── en/ # 英语默认 ├── es/ # 西班牙语 ├── fr/ # 法语 ├── generator/ # React Email 源码与渲染脚本 ├── embed.go # Go embed 打包 └── test/每个 locale 目录下的结构完全一致以 en 目录 为例en/ ├── email-confirm-change/ │ ├── body.html │ └── subject.txt ├── email-verify/ │ ├── body.html │ └── subject.txt ├── password-reset/ │ ├── body.html │ └── subject.txt ├── signin-otp/ │ ├── body.html │ └── subject.txt ├── signin-passwordless/ │ ├── body.html │ └── subject.txt └── signin-passwordless-sms/ └── body.txt # 无密码登录的短信模板仅纯文本即五类邮件模板各包含 HTML 正文body.html与邮件主题subject.txt两个文件外加一个纯文本的短信模板。这套目录约定被 Go 端的模板加载器严格依赖在 templates.go 中NewTemplatesFromFilesystem会递归遍历模板目录只收录文件名恰好为body.html、body.txt或subject.txt的文件并按locale/template-name/file的相对路径存入模板表。此外embed.go 通过//go:embed all:bg all:cs all:en all:es all:fr将这些模板编译进二进制使得 CLI 等消费方无需在运行时远程拉取模板即可直接使用默认邮件模板。二、生成器工作流预览与批量生成生成器的说明文档即 README.md给出两条核心命令均在仓库根目录下运行1. 本地实时预览pnpm dev:emailpnpm dev:email邮件模板由 React Email 编写dev:email会启动一个本地开发服务器让你在浏览器中实时编辑和预览模板效果包括不同邮件客户端下的渲染表现改完即所见即所得适合在翻译或调整样式时反复迭代。2. 为新 locale 批量生成pnpm generate:emails localepnpm generate:emails locale脚本执行完成后会在email-templates目录下新建一个以该 locale 命名的新文件夹里面是所有模板的 HTML 与主题文件骨架。之后你只需要把模板文案逐字翻译成对应语言即可。文档给出的德语示例pnpm generate:emails de运行后即会生成email-templates/de/目录结构与上面的en/完全一致。三、生成脚本源码解析render-emails.ts生成命令的核心逻辑位于 examples/docker-compose/nhost/emails/generator/render-emails.tsservices/auth/email-templates/generator 下还有一份相同的副本。整个流程可以拆成三步1. 定义五类邮件模板脚本将五类模板统一登记在一个数组中每个条目包含模板名、渲染出的 HTML 正文和主题const emails [ { name: email-confirm-change, body: prettier.format(render(EmailConfirmChange()), { parser: html, printWidth: 500, }), subject: subject, }, { name: email-verify, body: prettier.format(render(EmailVerify()), { parser: html, printWidth: 500 }), subject: subject, }, { name: password-reset, body: prettier.format(render(PasswordReset()), { parser: html, printWidth: 500 }), subject: subject, }, { name: signin-passwordless, body: prettier.format(render(SignInPasswordless()), { parser: html, printWidth: 500 }), subject: subject, }, { name: signin-otp, body: prettier.format(render(SignInOTP()), { parser: html, printWidth: 500 }), subject: subject, }, ];这里render()来自react-email/components负责把 TSX 组件渲染成 HTML 字符串prettier.format(..., { parser: html, printWidth: 500 })则对输出 HTML 做格式化保证生成的body.html整齐可读。注意生成器产出的subject.txt内容统一是字面量subject占位符翻译时务必替换成对应语言的主题文案。2. 计算目标目录const targetFolder path.resolve(./email-templates/${targetLocale}); if (!fs.existsSync(targetFolder)) { fs.mkdirSync(targetFolder); }脚本在仓库根目录下解析出./email-templates/locale作为目标目录不存在则先创建。这正好解释了 README 中在 email-templates 目录下新建 locale 文件夹的行为。3. 逐个写出模板文件emails.forEach((email) { if (!fs.existsSync(${targetFolder}/${email.name})) { fs.mkdirSync(${targetFolder}/${email.name}, { recursive: true }); } fs.writeFileSync(${targetFolder}/${email.name}/body.html, email.body); fs.writeFileSync(${targetFolder}/${email.name}/subject.txt, email.subject); });每个模板独立成子目录分别写出body.html与subject.txt输出结构与 en 目录 完全吻合可直接被 Go 端加载器读取。4. locale 参数校验const args process.argv.slice(2); const locale args[0]; if (!locale) { console.error(Please provide a locale for the emails.); process.exit(1); } renderEmails(locale);脚本要求第一个命令行参数必须是 locale缺失时报错并以非零码退出。因此pnpm generate:emails不带参数会直接失败pnpm generate:emails de才会正常生成德语模板。四、模板源码与占位符变量生成器目录下的 TSX 组件就是邮件的设计稿。以 email-confirm-change.tsx 为例它从react-email/components引入Html、Head、Body、Container、Heading、Text、Button、Hr、Section、Row、Column、Img、Link等组件用内联样式对象main、container、heading、paragraph、button等定义了一套以白色卡片 #0052CD主色按钮为核心的干净版式Container style{container} Heading style{heading}Confirm Email Change/Heading Text style{paragraph}Use this link to confirm changing email:/Text Section style{buttonContainer} Button style{button} href${link} Change Email /Button /Section ... /Container关键细节在于${link}它不是普通 React 字符串而是刻意保留的模板占位符。生成出的body.html中同样保留${link}最终由 Go 端渲染时替换为真实链接。类似的占位符还有${link}邮件内 CTA 按钮的目标链接用于 email-confirm-change、email-verify、password-reset、signin-passwordless 等模板${ticket}、${redirectTo}OTP 模板 signin-otp.tsx 中展示一次性密码与登录目标地址。Go 端渲染时templates.go 中的TemplateData定义了完整的可注入变量集合——Link、DisplayName、Email、NewEmail、Ticket、RedirectTo、Locale、ServerURL、ClientURL并通过ToMap映射为${link}、${displayName}、${email}、${newEmail}、${ticket}、${redirectTo}、${locale}、${serverUrl}、${clientUrl}。模板用 fasttemplate 以${...}语法执行替换见templates.go中的fasttemplate.New(string(f), ${, })这意味着你在翻译模板时可以在任何位置自由使用这些变量例如在subject.txt中写入你好${displayName}。五、渲染与回退机制Templates.Rendertemplates.go的工作流程如下按locale/template-name/body.html与subject.txt查找模板若目标 locale 下找不到对应模板打印template not found, falling back to default locale警告并回退到默认 locale默认英语en的模板用TemplateData.ToMap注入变量后分别执行 HTML 正文与主题的字符串替换。这一设计保证了即使某个 locale 只翻译了部分模板缺失的模板也会自动用英文兜底不会导致邮件发送失败。你可以利用这一点分阶段推进翻译工作——先跑pnpm generate:emails locale生成全部骨架再逐个模板、逐条文案完成翻译未完成的部分由回退机制临时接管。短信场景同样适用回退GetTemplateSMStemplates.go读取locale/signin-passwordless-sms/body.txt缺失时回退默认 localeRenderSMS通过TemplateSMSData注入${code}变量。六、目录约定如何被测试固化这套目录约定并非文档中的软约束而是有测试用例硬性验证的。templates_test.go 中的TestGetRawTemplates直接以../../email-templates/为路径加载全部模板并断言输出列表中精确包含bg/、cs/、en/、es/、fr/五个 locale 下全部body.html/subject.txt/body.txt文件。也就是说新增 locale 后其文件结构必须与既有 locale 完全一致才能被加载器识别若你修改了某个 locale 的模板文件或目录结构跑一遍该测试即可快速发现破坏性变更测试同时验证了变量替换结果例如用Link: http://link.test渲染出的body.html中按钮href与正文均被正确替换见templates_test.go第 137-183 行。七、实战步骤为你的项目添加一个新 locale综合以上内容为 Nhost Auth 添加新语言的完整流程如下安装依赖确保仓库根目录已执行pnpm install项目使用 pnpm见根目录 package.json 中的packageManager: pnpm11.24.0预览默认模板运行pnpm dev:email在浏览器中熟悉五类邮件的版式与文案生成新 locale 骨架运行pnpm generate:emails locale如pnpm generate:emails de生成email-templates/de/目录翻译文案逐文件编辑body.html与subject.txt把subject占位符替换为真实主题文案正文翻译为对应语言同时保留${link}、${ticket}、${redirectTo}等变量不变补齐 SMS 模板如需支持无密码登录短信在 locale 目录下手动创建signin-passwordless-sms/body.txt并翻译验证运行 Go 端模板测试templates_test.go 与 email_test.go确认目录结构、模板加载与变量渲染均正常随服务打包新 locale 目录会被 embed.go 的go:embed指令编译进 Auth 服务二进制需同步更新 embed 指令中的 locale 列表运行时即可按用户 locale 自动选择模板缺失时回退到默认英语模板。结语Nhost 将 React Email 的组件化开发体验与 Go 端fasttemplate的高效渲染结合在一起形成了一条TSX 设计 → 脚本批量产出 → Go 运行时渲染 → 测试固化结构的完整邮件本地化流水线。掌握pnpm dev:email与pnpm generate:emails locale两条命令再理解${link}、${ticket}、${redirectTo}等占位符与回退机制你就能为 Auth 服务的验证、重置、OTP 等全部事务邮件快速铺开多语言支持让产品在任意语言环境下都能提供一致、可信的邮件体验。【免费下载链接】nhostThe Open Source Firebase Alternative with GraphQL.项目地址: https://gitcode.com/GitHub_Trending/nh/nhost创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表