ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Comp AI CRM 多语言化改造方案(ADR):基于 next-intl 的目录化文案架构

Comp AI CRM 多语言化改造方案(ADR):基于 next-intl 的目录化文案架构 后端前端CRM人工智能AI Agent【免费下载链接】crmComp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.项目地址https://gitcode.com/gh_mirrors/crm48/crm点击查看免费下载这是一篇围绕仓库内 adrs/i18n.md 架构决策记录展开的技术解读。Comp AI CRM项目根目录目前将全部用户可见文案硬编码为英文该 ADR 提出引入 next-intl 目录catalog机制让新增一种语言从一次全局重构变成一次纯翻译提交。读完本文你将掌握这套方案的设计边界哪些字符串要进目录、哪些格式不翻译、语言选择与路由策略cookie user.locale不引入 URL segment、packages/ui的零依赖设计、CI 强制检查与伪语言校验手段以及约十个 PR 的渐进式落地路线。一、背景与动机为什么需要让 CRM 说多种语言ADR 以真实使用场景开场提案作者同时在越南的两家公司一家初创、一家成熟企业重度使用本 CRM。当前仓库里所有文案都硬编码为英文——打开 apps/app 下的任意页面组件都能看到直接写在 JSX 里的句子。这种做法的直接后果是本地化即 fork 风暴想让某个地区使用自己的语言就必须 fork 每一个渲染句子的文件上游同步成本极高一旦上游更新文案或组件结构fork 后的本地化补丁需要重新逐文件对账工作量巨大社区贡献无入口其他国家的用户即使愿意贡献语言包也没有一个统一的、可被自动化校验的载体。因此提案的核心诉求是把说另一种语言从一次重构降级为一次翻译任务。这也是adrs/README.md所鼓励的提案格式——说明想改什么、为什么现有行为是问题、替代方案会破坏什么。从当前仓库现状看该 ADR 属于提案待落地状态apps/app/package.json的依赖列表中尚没有next-intlpackages/db/prisma/schema.prisma的User模型也还没有locale列。文中所有方案描述均以 ADR 提案为准并标注可对照的源码证据。二、方案设计一切用户可见字符串进入统一目录2.1 目标范围apps/app与packages/ui提案明确圈定改造范围apps/app和packages/ui中每一个用户可见字符串都必须经由目录catalog输出。这一范围覆盖了 Web 前端的所有渲染层——包括 app 目录 下的页面组件以及 packages/ui/src/components 下的通用组件库。这一约束非常彻底不仅是页面正文还包括可翻译的属性translatable attributes例如aria-label、placeholder、title等以及toast 通知文案。当前仓库中 toast 是 sonner 驱动的例如 create-company-sheet.tsx/[slug]/companies/create-company-sheet.tsx#L76-L89) 中的toast.success(\${company.name} added.)与toast.error(error.message)这些都属于必须进入目录的字符串。2.2 本轮只做英文语言是翻译工作不是重构方案采用 next-intl 作为基础设施但本轮只内置英文。这背后的设计意图值得注意Strings only; date, number and currency formatting stay.即只翻译字符串不翻译格式。日期、数字、货币的呈现格式保持现状不动。从源码看packages/ui的日历组件 calendar.tsx 已经通过react-day-picker的Locale类型与locale?.code参数支持了按区域设置格式化如date.toLocaleString(locale?.code, { month: short })说明格式层已有独立的国际化能力与文案层天然解耦这正是该边界可行性的底层依据。之所以英文优先是为了把改造风险降到最低渲染出的英文文本与改造前逐字一致整个工作是管道铺设plumbing而非文案校对copy edit——CI 可以据此验证没有引入任何措辞变化。2.3 语言选择与路由策略cookie user.locale不要 URL segment这是本方案最有个性的设计决策。常见的多语言站点会在 URL 上挂语言段如/vi/companies并配套 middleware 重写但 ADR 明确拒绝这条路理由是本应用整体位于登录墙之后无 URL segment不在路径中引入/en/、/vi/前缀无 middleware不为语言切换增加任何请求拦截逻辑一个 cookie 加一个user.locale列即可语言偏好存储在客户端 cookie快速响应 用户表列持久化。当前仓库的 proxy.ts 展示了应用的门控结构未登录请求会被重定向到/sign-in登录后按 workspace 门控分流到[slug]路径。整个应用处于认证之后因此语言偏好完全可以通过登录态携带无需依赖 URL 暴露。从数据结构看schema.prisma 的User模型当前还没有locale字段这正是 ADR 提出要新增的列而其下AppSetting单行 upsert 的读写模式参见 packages/db/src/settings.ts 的SETTINGS_ID app与upsert用法可作为设置类字段持久化的现成参考实现。三、packages/ui的零 i18n 依赖策略ADR 对组件库提出了一条硬性约束packages/ui不引入任何 i18n 依赖。设计模式是包内自带英文默认值组件库本身直接书写英文文案保持其独立可运行、可测试通过 Provider 覆盖由上层应用apps/app注入翻译覆盖组件渲染时优先取注入的翻译取不到则回退英文。这样做的好处是双重的。其一组件库保持纯净任何不关心 i18n 的消费方包括测试环境、文档演示都能零成本使用其二将翻译职责收敛到应用层packages/ui的消费者只需对接一个 provider 契约。这与上面日历组件locale作为可选 prop 透传的风格一致——组件库只提供接缝由上层决定注入什么。四、强制检查让目录成为唯一事实来源只靠约定无法长期维持所有文案进目录因此 ADR 配套了两层强制执行机制4.1 CI 中的 AST 检查器在 CI 中运行一个基于 AST抽象语法树的静态检查器出现以下情况即构建失败硬编码的 JSX 文本例如直接写在 JSX 里的New company、Add company、Cancel当前大量存在于 create-company-sheet.tsx/[slug]/companies/create-company-sheet.tsx#L41-L48) 这类组件中可翻译属性placeholder、aria-label等属性上的硬编码字符串toast 文案sonner 的toast.success(...)/toast.error(...)传入的字面量。该检查器的存在意味着每新增一个字符串都必须进入目录否则 CI 失败——文案的单一来源由机制保证而非开发者的自觉。这与仓库现有工程纪律一脉相承仓库内已有自定义 oxlint 插件集见 tools/oxlint/anti-slop通过oxlint/plugins定义了一系列拒绝低质量模式的规则说明以自定义静态检查约束代码模式在该项目中是成熟的实践路径。4.2 伪语言pseudo-locale兜底静态分析无法发现所有问题——比如字符串拼接、隐式插值、运行时才暴露的硬编码。为此 ADR 提出伪语言校验用一套刻意加长的伪翻译例如把每个字符替换为带重音符号的变体并拉长文本渲染整个应用人工或截图对比即可发现哪些文案没有被目录接管仍显示纯英文哪些布局在文本变长后会溢出、截断或错位硬编码宽度/固定高度的隐患。这层校验捕捉的是静态分析看不到的东西两者互补形成完整防线。五、成本与取舍ADR 不回避代价明确列出两条/落地页放弃完整静态预渲染改为输出一个静态外壳static shell动态部分如语言偏好在客户端解析。当前落地页 page.tsx/page.tsx#L11-L15) 是带metadata的纯静态页面改造后其预渲染范围会收窄其他预渲染路由保持原有预渲染能力——只有依赖 cookie 的页面受影响不会波及全部路由。这里可参考apps/app/lib/env.ts的isMarketing()逻辑IS_MARKETING环境变量控制落地页是否对外公开见 env.ts落地页与非营销页面本就分流处理改造影响面可控。其余成本约束包括每个新字符串必须进目录否则 CI 失败英文保持唯一内置语言语言包以贡献形式合入缺失的 key 按字符串粒度回退到英文因此发布流程永远不必等待某一种翻译完成。六、落地路线约十个 PR渐进式推进ADR 给出的执行计划是分片落地、每片小且绿small and green第 1 片基础设施——引入 next-intl、搭建目录结构与 Provider、建立 CI 检查器与伪语言管线后续 N 片按功能区域逐个提取文案——公司/联系人/商机/设置/仪表盘等模块各自一个 PR将硬编码英文迁移进目录全部改造已在提案作者的 fork 上验证运行。最终形态是英文是唯一内置语言越南语作为第一个社区语言包由提案作者贡献并附带如何用编码 Agent 最高效地翻译语言包的指南——这也呼应了本仓库 apps/agent 所代表的 Agent 优先定位翻译工作本身也可借助 Agent 完成。从仓库现状看apps/app 下还有大量待迁移的硬编码文案例如各处 settings 页面的按钮、表格、sheet 标题这与 ADR 描述的本轮全量英文迁移工作量一致而 packages/ui 的组件文本同样如此。任何贡献者若想跟进该方案都可以从基础设施 PR或单个模块的提取 PR入手并遵守目录 key 的命名约定与 CI 检查。七、总结一份可以照着实现的 i18n 决策记录这份 ADR 的价值在于它把多语言支持这个常见但容易失控的需求收敛成了一组清晰、可执行、有边界的决策决策点方案基础设施next-intl 目录catalog本轮仅内置英文翻译边界只翻译字符串日期、数字、货币格式保持现状语言选择cookie user.locale列无 URL segment、无 middleware组件库策略packages/ui零 i18n 依赖英文默认值 Provider 覆盖强制机制CI AST 检查器JSX 文本/可翻译属性/toast 伪语言兜底回退策略缺失 key 按字符串粒度回退英文发布不等待翻译性能取舍/转为静态外壳其余预渲染路由保持落地节奏约十个 PR基础设施先行再按模块分片提取对想要参与 Comp AI CRM 的开发者而言这份文档既是一份待执行的技术蓝图也提供了清晰的第一贡献入口对任何正在为Agent 优先产品设计多语言方案的技术团队它则是一份可迁移的决策模板——尤其是语言是翻译工作而非重构与静态检查 伪语言双重防线这两个判断值得直接复用。赞分享后端前端CRM人工智能AI Agent【免费下载链接】crmComp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.项目地址https://gitcode.com/gh_mirrors/crm48/crm点击查看免费下载相关推荐Payload 多语言实战基于 Localization 与 next-intl 搭建国际化网站Payload 多语言实战基于 Localization 与 next intl 搭建国际化网站 本篇以 examples/localization 示例 h后端CMS基于 Turborepo 的 Monorepo 工程化实践以 Comp AI CRM 的 apps/packages 架构为例基于 Turborepo 的 Monorepo 工程化实践以 Comp AI CRM 的 apps/packages 架构为例 本篇技术指南围绕 .agent后端前端CRM人工智能AI Agent如何用 next-intl 把 React Email 模板改造为多语言版本如何用 next intl 把 React Email 模板改造为多语言版本 如果你已经用 React Email 写好了一套英文邮件模板现在需要让同一封邮件前端UI组件上一篇C Insights属性语法解析GNU和标准属性的区别下一篇VideoSrt字幕文件处理SRT格式解析与批量翻译转换终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表