Node.js 服务要面向不同语言用户时,日志、提示语和页面返回内容都需要尽快完成国际化接入。本文用 Ubuntu 环境下的一个最小示例,把 Node.js、Express 与 i18next 的落地步骤串起来,同时说明翻译文件目录、语言检测机制和回退语言的实际作用,读完后你可以判断这套方案能否直接作为项目起点。
环境准备:先把 Node.js 和 npm 装好
如果 Ubuntu 里还没有 Node.js 和 npm,可以先执行下面的安装命令:
sudo apt update
sudo apt install nodejs npm
这是后续初始化项目和安装依赖的基础步骤。文章示例默认你已经具备可正常运行 node 与 npm 命令的环境。
初始化项目并安装多语言依赖
先创建一个新的项目目录,并生成默认的 package.json:
mkdir my-nodejs-app
cd my-nodejs-app
npm init -y
接下来安装多语言所需的核心依赖。文章采用的是 i18next,再配合 HTTP 中间件与 Express 使用:
npm install i18next i18next-http-middleware
Express 本身也需要安装:
npm install express
在后面的入口文件中,还会用到从文件系统读取翻译内容的后端适配器,因此还要补上这一项:
npm install i18next-fs-backend
这几项依赖的分工比较明确:
i18next负责翻译能力本身i18next-http-middleware负责请求级语言检测i18next-fs-backend负责从本地文件系统加载 JSON 翻译文件express负责提供 HTTP 服务
准备翻译文件:先把目录结构想清楚
项目根目录下先创建一个 locales 文件夹:

mkdir locales
原始示例给出的翻译内容如下:
// locales/en.json
{
"welcome": "Welcome to our application!"
}
// locales/zh.json
{
"welcome": "欢迎使用我们的应用程序!"
}
这里有一个实际使用时需要注意的点:后文代码中的 loadPath 被配置成 ./locales/{{lng}}/{{ns}}.json,也就是按“语言目录 + 命名空间文件”的方式读取翻译文件。换句话说,如果直接沿用这段配置,那么文件结构应更接近下面这种形式:
locales/en/translation.json
locales/zh/translation.json
对应内容可以写成:
// locales/en/translation.json
{
"welcome": "Welcome to our application!"
}
// locales/zh/translation.json
{
"welcome": "欢迎使用我们的应用程序!"
}
这样才能和示例里的加载路径保持一致。原文提到的 common.json、errors.json 这类拆分方式,本质上也是在做命名空间管理,项目规模一旦变大,这种组织方式通常比把所有 key 堆进一个 JSON 文件更容易维护。
编写 app.js:配置回退语言和自动检测
在项目根目录创建 app.js,写入以下代码:

const express = require('express');
const i18next = require('i18next');
const Backend = require('i18next-fs-backend');
const middleware = require('i18next-http-middleware');
const app = express();
i18next
.use(Backend)
.use(middleware.LanguageDetector)
.init({
fallbackLng: 'en',
backend: {
loadPath: './locales/{{lng}}/{{ns}}.json'
}
}, (err, t) => {
if (err) return console.error(err);
app.get('/', (req, res) => {
res.send(t('welcome'));
});
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
});
这段代码里有三个关键点值得单独看清:
1. fallbackLng: 'en' 是兜底策略
当客户端语言无法匹配现有翻译,或者某个 key 在目标语言中不存在时,i18next 会回退到英文。这样至少能保证接口返回一份可用文本,而不是直接出现空值。
2. LanguageDetector 负责识别用户语言偏好
中间件会根据请求信息自动检测语言,常见场景就是读取浏览器发来的 Accept-Language 请求头。这样在最小示例里,用户不需要额外点选语言,服务就能优先返回对应语言内容。
3. t('welcome') 决定最终输出文本
当访问根路由时,服务端调用翻译函数读取 welcome 对应的内容。如果命中的语言是英文,返回英文文案;如果命中中文,则返回中文文案。这个调用方式也是后续把国际化扩展到错误信息、接口提示和模板渲染中的基础。
原文还提到,如果你不想从本地文件系统读取翻译,也可以替换后端实现,例如使用 i18next-http-backend 从远程服务加载资源。这更适合需要集中管理翻译内容的场景,但对最小演示来说,本地 JSON 文件已经足够直接。
运行与验证:看浏览器语言是否生效
完成配置后,直接启动服务:
node app.js
服务启动后访问 http://localhost:3000,可以按浏览器语言来验证结果:
- 浏览器语言为英文时,页面显示
Welcome to our application! - 浏览器语言为中文时,页面显示
欢迎使用我们的应用程序!
这个效果说明自动语言检测已经接通,最小可用链路是成立的:客户端发出请求,服务端识别语言偏好,再从对应翻译文件里取出文案返回。
不过,这个示例还只是起步版本。真正用于生产环境时,通常还会继续补齐下面几类能力:
- 提供手动切换语言的 UI,而不只依赖浏览器默认语言
- 支持翻译文件热更新,减少每次调整文案都要重启服务的成本
- 处理复数、日期、货币等更完整的本地化需求
- 按模块或页面拆分命名空间,避免单个翻译文件不断膨胀
如果你的目标只是先把 Node.js 应用在 Ubuntu 上跑通多语言返回,这套 i18next + i18next-http-middleware + i18next-fs-backend + Express 的组合已经足够作为起点。后续再根据项目规模,决定是否引入更细的命名空间设计、远程翻译资源和更完整的语言切换策略。







