i18n.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. export const LANDING_LOCALE_KEY = 'mailhub-landing-locale';
  2. export const supportedLocales = ['zh-CN', 'en-US'];
  3. const messages = {
  4. 'zh-CN': {
  5. 'nav.features': '功能',
  6. 'nav.integrate': '接入',
  7. 'nav.quickstart': '使用说明',
  8. 'nav.api': 'API',
  9. 'nav.mailboxes': '邮箱',
  10. 'nav.receiving': '收信',
  11. 'nav.domains': '域名配置',
  12. 'nav.smtp': 'SMTP',
  13. 'nav.webhooks': 'Webhooks',
  14. 'cta.login': '登录',
  15. 'cta.signup': '开始使用',
  16. 'cta.viewApi': '查看 API 示例',
  17. 'cta.github': 'GitHub',
  18. 'common.copy': '复制',
  19. 'common.copied': '已复制',
  20. 'common.yes': '是',
  21. 'common.no': '否',
  22. 'hero.eyebrow': '事务邮件平台',
  23. 'hero.title': '用 API 与 SMTP 发送可靠的事务邮件',
  24. 'hero.lede': '自托管 MailHub 提供域名 DNS 引导、DKIM 签名、投递日志与签名 Webhook —— 无需被黑盒 SaaS 锁定。',
  25. 'hero.curl': `curl -X POST https://mail.example.com/api/send \\
  26. -H 'Authorization: Bearer <USER_API_TOKEN>' \\
  27. -H 'Content-Type: application/json' \\
  28. -d '{
  29. "from": "noreply@example.com",
  30. "to": "user@example.com",
  31. "subject": "Hello from MailHub",
  32. "text": "Signed with DKIM and queued by MailHub."
  33. }'`,
  34. 'trust.selfHosted': '自托管',
  35. 'trust.webhooks': '投递 Webhooks',
  36. 'features.title': '为生产发信而设计',
  37. 'features.sub': '完成域名认证、发送与可观测所需的关键能力。',
  38. 'features.dns.title': '域名与 DNS',
  39. 'features.dns.body': 'SPF / DKIM / DMARC 引导,支持 DNS 服务商一键写入。',
  40. 'features.smtp.title': 'SMTP Submission',
  41. 'features.smtp.body': '面向应用的 SMTP 接入,凭据由你掌控。',
  42. 'features.api.title': 'HTTP 发送 API',
  43. 'features.api.body': 'Bearer Token + 简洁 JSON 发送接口,适合服务端集成。',
  44. 'features.mailboxes.title': '邮箱与收信',
  45. 'features.mailboxes.body': '创建长期或到期邮箱,支持 IMAP、POP3、转发和未知地址收取。',
  46. 'features.logs.title': '投递日志',
  47. 'features.logs.body': '跟踪入队与 MTA 结果,支持检索发送历史。',
  48. 'features.hooks.title': 'Webhooks',
  49. 'features.hooks.body': '对已送达 / 退信 / 失败终态事件进行签名回调。',
  50. 'features.multi.title': '多用户隔离',
  51. 'features.multi.body': '域名、Token 与日志按账号隔离。',
  52. 'integrate.title': '三种接入方式',
  53. 'integrate.sub': '选择适合你技术栈的路径 —— 注册登录后完成配置。',
  54. 'integrate.api.title': 'API',
  55. 'integrate.api.body': '创建 API Token,使用 Bearer 认证 POST JSON 到 /api/send。',
  56. 'integrate.api.link': '查看 API 示例 →',
  57. 'integrate.smtp.title': 'SMTP',
  58. 'integrate.smtp.body': '将应用指向 MailHub Submission 端口,使用独立登录凭据。',
  59. 'integrate.smtp.link': '查看 SMTP 说明 →',
  60. 'integrate.hooks.title': 'Webhooks',
  61. 'integrate.hooks.body': '为终态投递事件订阅端点,校验 HMAC 签名。',
  62. 'integrate.hooks.link': '查看 Webhook 事件 →',
  63. 'quickstart.title': '四步开始使用',
  64. 'quickstart.sub': '在同一个控制台完成域名、Token、邮箱和投递配置。',
  65. 'quickstart.domain.title': '添加域名',
  66. 'quickstart.domain.body': '添加发信域名,并发布 MailHub 展示的 DNS 记录。',
  67. 'quickstart.domain.link': '查看域名配置 →',
  68. 'quickstart.token.title': '创建最小权限 Token',
  69. 'quickstart.token.body': '只为每个接入授予所需的发信或邮箱权限。',
  70. 'quickstart.token.link': '查看 API 权限 →',
  71. 'quickstart.mailbox.title': '创建邮箱',
  72. 'quickstart.mailbox.body': '可在控制台创建长期邮箱,也可通过 API 创建长期或临时邮箱。',
  73. 'quickstart.mailbox.link': '查看邮箱 API →',
  74. 'quickstart.client.title': '接入客户端',
  75. 'quickstart.client.body': '使用 SMTP 发信,用 IMAP 或 POP3 收信,均使用完整邮箱地址和密码。',
  76. 'quickstart.client.link': '查看协议配置 →',
  77. 'api.title': 'API 认证与发信',
  78. 'api.sub': '所有公开 API 均使用 Bearer Token。下列主机名为占位符,请替换为你的 MailHub 地址。',
  79. 'api.auth.title': '创建并保护 Token',
  80. 'api.auth.body': '在控制台的 API Token 页面创建 Token。完整密钥仅显示一次,请存储在服务端环境,切勿写入浏览器代码或公开仓库。',
  81. 'api.auth.send': '使用 POST /api/send 发信',
  82. 'api.auth.read': '使用 GET /api/mailboxes 查询邮箱',
  83. 'api.auth.write': '使用 POST /api/mailboxes 创建邮箱',
  84. 'api.send.title': '发送一封邮件',
  85. 'api.send.body': 'From 域名必须属于该 Token 所在账号。若启用了已验证域名发信,请先完成控制台中的 DNS 校验。',
  86. 'api.curl': `curl -X POST https://mail.example.com/api/send \\
  87. -H 'Authorization: Bearer <USER_API_TOKEN>' \\
  88. -H 'Content-Type: application/json' \\
  89. -d '{
  90. "from": "noreply@example.com",
  91. "to": "user@example.com",
  92. "subject": "Hello from MailHub",
  93. "text": "Signed with DKIM and queued by MailHub."
  94. }'`,
  95. 'api.fields.name': '字段',
  96. 'api.fields.required': '必填',
  97. 'api.fields.description': '说明',
  98. 'api.field.from': '该账号已添加域名上的发件地址',
  99. 'api.field.to': '单个收件人字符串或地址数组',
  100. 'api.field.subject': '默认值为 (no subject)',
  101. 'api.field.text': '纯文本正文',
  102. 'api.field.html': 'HTML 正文;启用打开或点击跟踪时需要提供',
  103. 'api.field.tracking': 'true/false,或 { opens, clicks };仅改写 HTML',
  104. 'api.field.relay': '属于当前账号的外部 SMTP 出口 ID',
  105. 'api.responseLabel': '202 响应',
  106. 'api.response': `{
  107. "eventId": 42,
  108. "queued": true,
  109. "domain": "example.com",
  110. "recipients": ["user@example.com"],
  111. "smtp": "Message queued",
  112. "queueId": "AB12CD34",
  113. "tracking": { "enabled": false, "opens": false, "clicks": false }
  114. }`,
  115. 'api.note': '202 表示 MailHub 已接受邮件并交给 SMTP 投递。后续投递结果请查看控制台日志或使用 Webhook。',
  116. 'mailboxes.title': '邮箱 API 与客户端接入',
  117. 'mailboxes.sub': '为持续使用创建长期邮箱;为短流程创建可自动过期的临时邮箱。',
  118. 'mailboxes.api.title': '邮箱 API 权限',
  119. 'mailboxes.api.body': '使用拥有 mailboxes:write 权限的 Token 调用 POST /api/mailboxes,目标域名必须属于该账号。',
  120. 'mailboxes.api.mode': 'permanent 或 temporary',
  121. 'mailboxes.api.address': '传入完整邮箱,或使用 domain 加 localPart',
  122. 'mailboxes.api.expires': '临时邮箱必填,范围为 5 分钟到 30 天',
  123. 'mailboxes.api.password': '可选;不传时会仅在创建响应中返回安全密码',
  124. 'mailboxes.client.title': '使用返回的客户端配置',
  125. 'mailboxes.client.body': '创建响应包含邮箱地址、密码、到期时间,以及可直接使用的 IMAP、POP3、SMTP 配置。',
  126. 'mailboxes.client.imap': '推荐,支持同步文件夹与已发送邮件',
  127. 'mailboxes.client.pop3': '适合下载到本地的客户端',
  128. 'mailboxes.client.smtp': '发信时同样使用完整邮箱地址和密码',
  129. 'mailboxes.permanent.label': 'POST /api/mailboxes - 长期邮箱',
  130. 'mailboxes.permanent.curl': `curl -X POST https://mail.example.com/api/mailboxes -H 'Authorization: Bearer <MAILBOX_API_TOKEN>' -H 'Content-Type: application/json' -d '{
  131. "mode": "permanent",
  132. "address": "support@example.com",
  133. "password": "<MAILBOX_PASSWORD>",
  134. "displayName": "Support",
  135. "aliases": ["help"],
  136. "forwardTo": ["archive@example.net"],
  137. "keepForwarded": true,
  138. "quotaMb": 1024
  139. }'`,
  140. 'mailboxes.temporary.label': 'POST /api/mailboxes - 临时邮箱',
  141. 'mailboxes.temporary.curl': `curl -X POST https://mail.example.com/api/mailboxes -H 'Authorization: Bearer <MAILBOX_API_TOKEN>' -H 'Content-Type: application/json' -d '{
  142. "mode": "temporary",
  143. "domain": "example.com",
  144. "expiresInMinutes": 60
  145. }'`,
  146. 'mailboxes.list.curl': "curl -H 'Authorization: Bearer <MAILBOX_API_TOKEN>' https://mail.example.com/api/mailboxes",
  147. 'mailboxes.responseLabel': '201 创建响应',
  148. 'mailboxes.response': `{
  149. "mailbox": {
  150. "address": "tmp-a1b2c3@example.com",
  151. "temporary": true,
  152. "expiresAt": "2026-07-15T12:00:00.000Z"
  153. },
  154. "password": "<GENERATED_MAILBOX_PASSWORD>",
  155. "clientConfig": {
  156. "incoming": { "protocol": "IMAP", "host": "mail.example.com", "port": 993, "security": "IMAPS" },
  157. "pop3": { "protocol": "POP3", "host": "mail.example.com", "port": 995, "security": "POP3S" },
  158. "outgoing": { "protocol": "SMTP", "host": "mail.example.com", "port": 465, "security": "SMTPS" }
  159. }
  160. }`,
  161. 'mailboxes.lifecycle.password': '自动生成的密码仅在创建响应中返回一次;请立即保存。',
  162. 'mailboxes.lifecycle.temporary': '临时邮箱在指定时间后到期,随后停止收信和认证。',
  163. 'mailboxes.lifecycle.list': '使用 mailboxes:read 查询邮箱元数据;列表接口永不返回密码。',
  164. 'receiving.title': '收信',
  165. 'receiving.sub': '邮件通过域名 MX 记录投递。在 MailHub 收件箱或标准 IMAP/POP3 客户端中读取;当前没有单独的 Bearer 收信读取 API。',
  166. 'receiving.delivery.title': '邮件投递到 MailHub',
  167. 'receiving.delivery.body': '将域名 MX 指向收信主机。外部邮件服务器会投递到 SMTP 25 端口;MailHub 将邮件存入已有邮箱、别名或未知地址收取目标。',
  168. 'receiving.routing.title': '邮箱、别名与未知地址收取',
  169. 'receiving.routing.body': '先创建完整邮箱地址,再在邮箱上添加别名或转发。通过控制台的域名未知地址收取设置,将不存在的本地部分路由到某个邮箱或外部地址。',
  170. 'receiving.protocols.protocol': '协议',
  171. 'receiving.protocols.ports': '推荐端口',
  172. 'receiving.protocols.security': '加密',
  173. 'receiving.protocols.use': '用途',
  174. 'receiving.protocols.imapSecurity': 'SSL/TLS 或 STARTTLS',
  175. 'receiving.protocols.imapUse': '推荐,用于同步文件夹',
  176. 'receiving.protocols.pop3Security': 'SSL/TLS 或 STLS',
  177. 'receiving.protocols.pop3Use': '下载到本地的客户端',
  178. 'receiving.protocols.smtpSecurity': 'SMTPS 或 STARTTLS',
  179. 'receiving.protocols.smtpUse': '使用相同邮箱地址和密码发信',
  180. 'receiving.folders': 'IMAP 会提供 INBOX、Sent、Drafts、Trash、Junk 和 Archive。需要同步这些文件夹并保存已发送邮件时,请优先使用 IMAP。',
  181. 'domainsDoc.title': '域名配置',
  182. 'domainsDoc.sub': '先在 MailHub 中添加域名。控制台 DNS 面板展示的验证、DKIM、SPF、DMARC 与发信主机值是该域名的最终准则。',
  183. 'domainsDoc.col.purpose': '用途',
  184. 'domainsDoc.col.record': '记录',
  185. 'domainsDoc.col.requirement': '要求',
  186. 'domainsDoc.row.verify': '域名归属验证',
  187. 'domainsDoc.row.verifyValue': '发布控制台生成的验证值。',
  188. 'domainsDoc.row.dkim': '发布该域名生成的公钥。',
  189. 'domainsDoc.row.spf': '仅保留一条 SPF,并包含 MailHub 要求的发信 IP/主机。',
  190. 'domainsDoc.row.dmarc': '先以监控策略开始,确认对齐后再逐步增强策略。',
  191. 'domainsDoc.row.mx': '收信',
  192. 'domainsDoc.row.mxValue': 'MX 指向 MailHub 收信主机,并确保该主机存在 A/AAAA 记录。',
  193. 'domainsDoc.note': '为提高投递可靠性,还需将发信 IP 的 PTR 配置为 MailHub 发信主机名,并在防火墙放行文档所列 SMTP、IMAP、POP3 端口。',
  194. 'smtp.title': 'SMTP Submission',
  195. 'smtp.sub': '默认监听端口(部署时可覆盖):',
  196. 'smtp.app.title': '应用 SMTP',
  197. 'smtp.app.body': '在控制台创建 SMTP 登录凭据供应用使用,并搭配属于该账号的 From 域名。',
  198. 'smtp.mailbox.title': '邮箱 SMTP',
  199. 'smtp.mailbox.body': '创建出的邮箱也可以用完整地址和密码通过 SMTP 认证发信;IMAP 与 POP3 使用相同的凭据。',
  200. 'smtp.note': '发信优先使用 465 或 587,IMAP 使用 993,POP3 使用 995。若部署覆盖了默认端口或 TLS 监听,请以创建邮箱响应中的 clientConfig 为准。',
  201. 'errors.title': '响应与常见错误',
  202. 'errors.sub': 'API 返回 JSON。使用响应体前,请先判断 HTTP 状态码。',
  203. 'errors.status': '状态码',
  204. 'errors.meaning': '含义',
  205. 'errors.action': '处理方式',
  206. 'errors.201.meaning': '邮箱已创建',
  207. 'errors.201.action': '保存一次性密码与 clientConfig。',
  208. 'errors.202.meaning': '邮件已被接受并交给 SMTP 投递',
  209. 'errors.202.action': '在日志或 Webhook 中查看后续投递状态。',
  210. 'errors.400.meaning': '请求参数不正确,或不满足域名归属规则',
  211. 'errors.400.action': '阅读 JSON error 字段,修正请求体或域名配置。',
  212. 'errors.401.meaning': 'Token 缺失、无效、已撤销或已过期',
  213. 'errors.401.action': '创建或轮换一个有效 Token。',
  214. 'errors.403.meaning': 'Token 缺少所需权限',
  215. 'errors.403.action': '在控制台 API Token 页面授予最小所需权限。',
  216. 'errors.409.meaning': '邮箱地址已存在',
  217. 'errors.409.action': '换用其他地址,或使用现有邮箱。',
  218. 'webhooks.title': '投递 Webhooks',
  219. 'webhooks.sub': '仅终态事件 —— 向你的系统发送签名 HTTPS 回调。',
  220. 'webhooks.col.status': '状态',
  221. 'webhooks.col.type': 'type',
  222. 'webhooks.sig': '签名请求头:',
  223. 'ctaBand.title': '准备好发送了吗?',
  224. 'ctaBand.sub': '创建账号、添加域名,几分钟内发出第一封邮件。',
  225. 'footer.tag': '自托管邮件投递控制平面'
  226. },
  227. 'en-US': {
  228. 'nav.features': 'Features',
  229. 'nav.integrate': 'Integrate',
  230. 'nav.quickstart': 'Quick start',
  231. 'nav.api': 'API',
  232. 'nav.mailboxes': 'Mailboxes',
  233. 'nav.receiving': 'Receiving',
  234. 'nav.domains': 'Domain setup',
  235. 'nav.smtp': 'SMTP',
  236. 'nav.webhooks': 'Webhooks',
  237. 'cta.login': 'Log in',
  238. 'cta.signup': 'Get started',
  239. 'cta.viewApi': 'View API sample',
  240. 'cta.github': 'GitHub',
  241. 'common.copy': 'Copy',
  242. 'common.copied': 'Copied',
  243. 'common.yes': 'Yes',
  244. 'common.no': 'No',
  245. 'hero.eyebrow': 'Transactional email platform',
  246. 'hero.title': 'Send reliable email via API & SMTP',
  247. 'hero.lede': 'Self-hosted MailHub gives you domain DNS guidance, DKIM signing, delivery logs, and signed webhooks — without locking you into a black-box SaaS.',
  248. 'hero.curl': `curl -X POST https://mail.example.com/api/send \\
  249. -H 'Authorization: Bearer <USER_API_TOKEN>' \\
  250. -H 'Content-Type: application/json' \\
  251. -d '{
  252. "from": "noreply@example.com",
  253. "to": "user@example.com",
  254. "subject": "Hello from MailHub",
  255. "text": "Signed with DKIM and queued by MailHub."
  256. }'`,
  257. 'trust.selfHosted': 'Self-hosted',
  258. 'trust.webhooks': 'Delivery webhooks',
  259. 'features.title': 'Built for production senders',
  260. 'features.sub': 'Everything you need to authenticate domains and observe delivery.',
  261. 'features.dns.title': 'Domains & DNS',
  262. 'features.dns.body': 'Guided SPF, DKIM, DMARC, and one-click DNS provider writes.',
  263. 'features.smtp.title': 'SMTP Submission',
  264. 'features.smtp.body': 'App-friendly SMTP listeners with credentials you control.',
  265. 'features.api.title': 'HTTP Send API',
  266. 'features.api.body': 'Bearer tokens and a simple JSON send endpoint for apps and services.',
  267. 'features.mailboxes.title': 'Mailboxes & receiving',
  268. 'features.mailboxes.body': 'Create persistent or expiring inboxes with IMAP, POP3, forwarding, and catch-all routing.',
  269. 'features.logs.title': 'Delivery logs',
  270. 'features.logs.body': 'Track queue and MTA outcomes with searchable send history.',
  271. 'features.hooks.title': 'Webhooks',
  272. 'features.hooks.body': 'Signed callbacks for sent, bounced, and failed terminal events.',
  273. 'features.multi.title': 'Multi-user isolation',
  274. 'features.multi.body': 'Domains, tokens, and logs stay scoped to each account.',
  275. 'integrate.title': 'Three ways to integrate',
  276. 'integrate.sub': 'Pick the path that matches your stack — configure after sign-in.',
  277. 'integrate.api.title': 'API',
  278. 'integrate.api.body': 'Create an API token, then POST JSON to /api/send with Bearer auth.',
  279. 'integrate.api.link': 'See API sample →',
  280. 'integrate.smtp.title': 'SMTP',
  281. 'integrate.smtp.body': 'Point your app at MailHub submission ports with per-user credentials.',
  282. 'integrate.smtp.link': 'See SMTP details →',
  283. 'integrate.hooks.title': 'Webhooks',
  284. 'integrate.hooks.body': 'Subscribe endpoints to terminal delivery events with HMAC signatures.',
  285. 'integrate.hooks.link': 'See webhook events →',
  286. 'quickstart.title': 'Start in four steps',
  287. 'quickstart.sub': 'Keep domain, token, mailbox, and delivery configuration in one console.',
  288. 'quickstart.domain.title': 'Add a domain',
  289. 'quickstart.domain.body': 'Add your sending domain and publish the DNS records shown by MailHub.',
  290. 'quickstart.domain.link': 'Review domain setup →',
  291. 'quickstart.token.title': 'Create a scoped token',
  292. 'quickstart.token.body': 'Give each integration only the send or mailbox permissions it needs.',
  293. 'quickstart.token.link': 'Review API access →',
  294. 'quickstart.mailbox.title': 'Provision mailboxes',
  295. 'quickstart.mailbox.body': 'Create persistent mailboxes in the console or create persistent and temporary mailboxes by API.',
  296. 'quickstart.mailbox.link': 'Review mailbox API →',
  297. 'quickstart.client.title': 'Connect your client',
  298. 'quickstart.client.body': 'Use SMTP to send and IMAP or POP3 to receive with the full mailbox address and password.',
  299. 'quickstart.client.link': 'Review protocol settings →',
  300. 'api.title': 'API authentication and sending',
  301. 'api.sub': 'All public API calls use a Bearer token. The hostname below is a placeholder; replace it with your MailHub host.',
  302. 'api.auth.title': 'Create and protect a token',
  303. 'api.auth.body': 'Create a token in Console > API Tokens. The complete secret is shown only once, so store it outside browser code and public repositories.',
  304. 'api.auth.send': 'send messages with POST /api/send',
  305. 'api.auth.read': 'list mailboxes with GET /api/mailboxes',
  306. 'api.auth.write': 'create mailboxes with POST /api/mailboxes',
  307. 'api.send.title': 'Send a message',
  308. 'api.send.body': 'The From domain must belong to the token account. When verified sending is enabled, complete the domain DNS checks before sending.',
  309. 'api.curl': `curl -X POST https://mail.example.com/api/send \\
  310. -H 'Authorization: Bearer <USER_API_TOKEN>' \\
  311. -H 'Content-Type: application/json' \\
  312. -d '{
  313. "from": "noreply@example.com",
  314. "to": "user@example.com",
  315. "subject": "Hello from MailHub",
  316. "text": "Signed with DKIM and queued by MailHub."
  317. }'`,
  318. 'api.fields.name': 'Field',
  319. 'api.fields.required': 'Required',
  320. 'api.fields.description': 'Description',
  321. 'api.field.from': 'sender address on an account-owned domain',
  322. 'api.field.to': 'recipient string or an address array',
  323. 'api.field.subject': 'defaults to (no subject)',
  324. 'api.field.text': 'plain-text body',
  325. 'api.field.html': 'HTML body; required when enabling open or click tracking',
  326. 'api.field.tracking': 'true/false, or { opens, clicks }; rewrites HTML only',
  327. 'api.field.relay': 'an account-owned outbound SMTP relay ID',
  328. 'api.responseLabel': '202 response',
  329. 'api.response': `{
  330. "eventId": 42,
  331. "queued": true,
  332. "domain": "example.com",
  333. "recipients": ["user@example.com"],
  334. "smtp": "Message queued",
  335. "queueId": "AB12CD34",
  336. "tracking": { "enabled": false, "opens": false, "clicks": false }
  337. }`,
  338. 'api.note': 'A 202 response means MailHub accepted the message for SMTP delivery. Use the console delivery log or webhooks to observe the later result.',
  339. 'mailboxes.title': 'Mailbox API and clients',
  340. 'mailboxes.sub': 'Create a persistent address for ongoing work, or an expiring address for a short-lived workflow.',
  341. 'mailboxes.api.title': 'Mailbox API scope',
  342. 'mailboxes.api.body': 'POST to /api/mailboxes with a token holding mailboxes:write. The target domain must belong to that account.',
  343. 'mailboxes.api.mode': 'permanent or temporary',
  344. 'mailboxes.api.address': 'use a full address, or choose domain plus localPart',
  345. 'mailboxes.api.expires': 'required for temporary mailboxes; 5 minutes to 30 days',
  346. 'mailboxes.api.password': 'optional; a secure password is returned once when omitted',
  347. 'mailboxes.client.title': 'Use the returned configuration',
  348. 'mailboxes.client.body': 'Creation returns the address, password, expiration, and ready-to-use IMAP, POP3, and SMTP settings.',
  349. 'mailboxes.client.imap': 'recommended for synchronized folders and sent mail',
  350. 'mailboxes.client.pop3': 'for download-oriented clients',
  351. 'mailboxes.client.smtp': 'use the same full mailbox address and password to send',
  352. 'mailboxes.permanent.label': 'POST /api/mailboxes - permanent',
  353. 'mailboxes.permanent.curl': `curl -X POST https://mail.example.com/api/mailboxes -H 'Authorization: Bearer <MAILBOX_API_TOKEN>' -H 'Content-Type: application/json' -d '{
  354. "mode": "permanent",
  355. "address": "support@example.com",
  356. "password": "<MAILBOX_PASSWORD>",
  357. "displayName": "Support",
  358. "aliases": ["help"],
  359. "forwardTo": ["archive@example.net"],
  360. "keepForwarded": true,
  361. "quotaMb": 1024
  362. }'`,
  363. 'mailboxes.temporary.label': 'POST /api/mailboxes - temporary',
  364. 'mailboxes.temporary.curl': `curl -X POST https://mail.example.com/api/mailboxes -H 'Authorization: Bearer <MAILBOX_API_TOKEN>' -H 'Content-Type: application/json' -d '{
  365. "mode": "temporary",
  366. "domain": "example.com",
  367. "expiresInMinutes": 60
  368. }'`,
  369. 'mailboxes.list.curl': "curl -H 'Authorization: Bearer <MAILBOX_API_TOKEN>' https://mail.example.com/api/mailboxes",
  370. 'mailboxes.responseLabel': '201 creation response',
  371. 'mailboxes.response': `{
  372. "mailbox": {
  373. "address": "tmp-a1b2c3@example.com",
  374. "temporary": true,
  375. "expiresAt": "2026-07-15T12:00:00.000Z"
  376. },
  377. "password": "<GENERATED_MAILBOX_PASSWORD>",
  378. "clientConfig": {
  379. "incoming": { "protocol": "IMAP", "host": "mail.example.com", "port": 993, "security": "IMAPS" },
  380. "pop3": { "protocol": "POP3", "host": "mail.example.com", "port": 995, "security": "POP3S" },
  381. "outgoing": { "protocol": "SMTP", "host": "mail.example.com", "port": 465, "security": "SMTPS" }
  382. }
  383. }`,
  384. 'mailboxes.lifecycle.password': 'The returned password is the only opportunity to read an automatically generated password.',
  385. 'mailboxes.lifecycle.temporary': 'A temporary mailbox expires after the requested interval and then stops receiving mail and authenticating.',
  386. 'mailboxes.lifecycle.list': 'Use mailboxes:read to list mailbox metadata; passwords are never returned by the list endpoint.',
  387. 'receiving.title': 'Receiving mail',
  388. 'receiving.sub': 'Mail arrives through the domain MX record. Read it in MailHub Inbox or through standard IMAP/POP3 clients; there is no separate inbound Bearer API.',
  389. 'receiving.delivery.title': 'Inbound delivery',
  390. 'receiving.delivery.body': 'Set the domain MX record to the receiving host. External mail servers then deliver to SMTP port 25, and MailHub stores mail for an existing mailbox, alias, or catch-all target.',
  391. 'receiving.routing.title': 'Mailbox, aliases, and catch-all',
  392. 'receiving.routing.body': 'Create a full mailbox address first. Add aliases or forwarding on that mailbox, and configure the domain catch-all in the console to route unknown local parts to a mailbox or another address.',
  393. 'receiving.protocols.protocol': 'Protocol',
  394. 'receiving.protocols.ports': 'Recommended ports',
  395. 'receiving.protocols.security': 'Security',
  396. 'receiving.protocols.use': 'Use',
  397. 'receiving.protocols.imapSecurity': 'SSL/TLS or STARTTLS',
  398. 'receiving.protocols.imapUse': 'recommended for synchronized folders',
  399. 'receiving.protocols.pop3Security': 'SSL/TLS or STLS',
  400. 'receiving.protocols.pop3Use': 'download-oriented clients',
  401. 'receiving.protocols.smtpSecurity': 'SMTPS or STARTTLS',
  402. 'receiving.protocols.smtpUse': 'send with the same mailbox address and password',
  403. 'receiving.folders': 'IMAP exposes INBOX, Sent, Drafts, Trash, Junk, and Archive. Use IMAP when the client should synchronize these folders and save sent messages.',
  404. 'domainsDoc.title': 'Domain configuration',
  405. 'domainsDoc.sub': 'Create the domain in MailHub first. Its DNS panel is the source of truth for your exact verification, DKIM, SPF, DMARC, and sender-host values.',
  406. 'domainsDoc.col.purpose': 'Purpose',
  407. 'domainsDoc.col.record': 'Record',
  408. 'domainsDoc.col.requirement': 'Requirement',
  409. 'domainsDoc.row.verify': 'Domain ownership',
  410. 'domainsDoc.row.verifyValue': 'Publish the verification value generated in the console.',
  411. 'domainsDoc.row.dkim': 'Publish the public key generated for this domain.',
  412. 'domainsDoc.row.spf': 'Keep one SPF record and include the sender IP/host required by MailHub.',
  413. 'domainsDoc.row.dmarc': 'Start with monitoring, then strengthen the policy after alignment is verified.',
  414. 'domainsDoc.row.mx': 'Inbound mail',
  415. 'domainsDoc.row.mxValue': 'Point MX to the MailHub receiving host and ensure that host has an A/AAAA record.',
  416. 'domainsDoc.note': 'For reliable delivery, also configure the sending IP\'s PTR to match the MailHub sending hostname and allow the documented SMTP, IMAP, and POP3 ports through your firewall.',
  417. 'smtp.title': 'SMTP submission',
  418. 'smtp.sub': 'Default listener ports (override in your deployment):',
  419. 'smtp.app.title': 'Application SMTP',
  420. 'smtp.app.body': 'Create an SMTP login credential in the console for an application. Use that credential with an account-owned From domain.',
  421. 'smtp.mailbox.title': 'Mailbox SMTP',
  422. 'smtp.mailbox.body': 'A created mailbox can also authenticate over SMTP with its full email address and password. Use the same credentials for IMAP or POP3.',
  423. 'smtp.note': 'Prefer 465 or 587 for sending, 993 for IMAP, and 995 for POP3. The creation response is the source of truth when a deployment overrides default ports or TLS listeners.',
  424. 'errors.title': 'Responses and common errors',
  425. 'errors.sub': 'The API returns JSON. Validate the HTTP status before consuming a response body.',
  426. 'errors.status': 'Status',
  427. 'errors.meaning': 'Meaning',
  428. 'errors.action': 'What to do',
  429. 'errors.201.meaning': 'Mailbox created',
  430. 'errors.201.action': 'Store the one-time password and clientConfig.',
  431. 'errors.202.meaning': 'Message accepted for SMTP delivery',
  432. 'errors.202.action': 'Inspect delivery logs or webhooks for later delivery status.',
  433. 'errors.400.meaning': 'Invalid request or domain ownership rule',
  434. 'errors.400.action': 'Read the JSON error and correct the request body or domain setup.',
  435. 'errors.401.meaning': 'Missing, invalid, revoked, or expired token',
  436. 'errors.401.action': 'Create or rotate a valid token.',
  437. 'errors.403.meaning': 'Token does not have the required scope',
  438. 'errors.403.action': 'Grant the minimum required scope in Console > API Tokens.',
  439. 'errors.409.meaning': 'Mailbox address already exists',
  440. 'errors.409.action': 'Choose another address or use the existing mailbox.',
  441. 'webhooks.title': 'Delivery webhooks',
  442. 'webhooks.sub': 'Terminal events only — signed HTTPS callbacks to your systems.',
  443. 'webhooks.col.status': 'Status',
  444. 'webhooks.col.type': 'type',
  445. 'webhooks.sig': 'Signature header:',
  446. 'ctaBand.title': 'Ready to send?',
  447. 'ctaBand.sub': 'Create an account, add a domain, and ship your first message in minutes.',
  448. 'footer.tag': 'Self-hosted email delivery control plane'
  449. }
  450. };
  451. export function detectLocale() {
  452. try {
  453. const stored = localStorage.getItem(LANDING_LOCALE_KEY);
  454. if (stored && supportedLocales.includes(stored)) return stored;
  455. } catch {
  456. /* ignore */
  457. }
  458. const nav = typeof navigator !== 'undefined' ? navigator.language || '' : '';
  459. return nav.toLowerCase().startsWith('zh') ? 'zh-CN' : 'en-US';
  460. }
  461. export function t(locale, key) {
  462. return messages[locale]?.[key] ?? messages['en-US'][key] ?? key;
  463. }
  464. export function setStoredLocale(locale) {
  465. try {
  466. localStorage.setItem(LANDING_LOCALE_KEY, locale);
  467. } catch {
  468. /* ignore */
  469. }
  470. }