如何配置Next.js i18n以兼容Laravel导出的含参数翻译文本
这个问题我太熟了!之前帮同事处理过几乎一模一样的场景——Laravel和Next.js用的i18n占位符语法不兼容,Laravel是:变量名,而i18next(Next.js常用的i18n库)默认认的是{{变量名}}这类格式。不过完全不用手动改几百个翻译文件,两种方案都能完美解决:
方案1:直接修改i18next的插值规则(推荐)
你只需要在Next.js的i18n配置文件里,自定义插值的前缀和后缀,让它适配Laravel的格式。
假设你的配置文件是next-i18next.config.js,修改成这样:
module.exports = { i18n: { locales: ['en', 'zh-CN'], // 你的语言列表 defaultLocale: 'en', }, interpolation: { prefix: ':', // 匹配Laravel的占位符前缀 suffix: '', // Laravel的占位符没有后缀,设为空 escapeValue: false, // Next.js环境下一般不需要转义HTML,设为false即可 }, };
配置完成后重启Next.js服务,再调用t('common:greeting', { name: 'John' }),就能正常显示Hi, John了。这个方案的好处是不用动任何翻译文件,完全靠配置适配。
方案2:导出翻译文件时批量替换占位符
如果你不想修改i18n的默认配置,也可以写个简单的脚本,在把Laravel翻译文件导出到Next.js的时候,自动把:name替换成i18next默认的{{name}}。
比如写个Node.js脚本:
const fs = require('fs'); const path = require('path'); // 转换单个文件的占位符 function convertFile(srcPath, destPath) { const content = fs.readFileSync(srcPath, 'utf8'); // 正则匹配:变量名,替换成{{变量名}} const convertedContent = content.replace(/:([a-zA-Z0-9_]+)/g, '{{$1}}'); fs.writeFileSync(destPath, convertedContent, 'utf8'); } // 递归遍历目录处理所有文件 function convertDir(srcDir, destDir) { fs.mkdirSync(destDir, { recursive: true }); fs.readdirSync(srcDir).forEach(item => { const srcItemPath = path.join(srcDir, item); const destItemPath = path.join(destDir, item); if (fs.statSync(srcItemPath).isDirectory()) { convertDir(srcItemPath, destItemPath); } else if (path.extname(item) === '.json') { // 假设你把Laravel的php翻译转成了json convertFile(srcItemPath, destItemPath); } }); } // 调用示例:把Laravel导出的翻译目录转成Next.js可用的格式 convertDir('./laravel-exported-translations', './public/locales');
运行这个脚本后,所有翻译文件里的:name都会变成{{name}},直接用默认的i18next配置就能正常渲染参数了。
小提示
如果你的翻译文本里有需要保留的冒号(比如请输入: 用户名),可以在Laravel里写成请输入\: 用户名,然后在脚本里调整正则,跳过转义的冒号,比如把正则改成/(?<!\\):([a-zA-Z0-9_]+)/g,这样就不会替换\:后面的内容了。
内容的提问来源于stack exchange,提问作者phen pani
相关产品推荐
相关产品推荐

