nginx 的 root 指令不支持直接变量拼接,但可通过 http 块中的 map 指令将域名映射为预计算路径变量(如 $lang_root),再在 server 块中用 root $lang_root 实现多语言站点自动切换根目录,兼顾性能与配置简洁性。

Nginx 的 root 指令本身不支持直接嵌套变量运算(比如 $host 拼接字符串),但可以通过 map 指令预定义安全、静态映射的变量,再在 root 中引用它,从而实现多语言站点按域名自动切换根目录。这不是“在 root 里写变量”,而是“用 map 把域名转成路径,再让 root 用这个路径”。
多语言域名到目录的映射(推荐用 map)
用 map 将不同语言子域映射为对应文件路径,避免 if 或重复 server 块:
http {
# 定义语言映射:从 host 提取子域,映射到物理路径
map $host $lang_root {
default /var/www/default;
zh.example.com /var/www/zh;
en.example.com /var/www/en;
ja.example.com /var/www/ja;
fr.example.com /var/www/fr;
}
server {
listen 80;
server_name example.com *.example.com;
# root 使用预定义的 $lang_root 变量
root $lang_root;
index index.html;
try_files $uri $uri/ /index.html;
}
}
-
$lang_root是一个只读、预计算的变量,Nginx 在请求解析初期就完成匹配,性能开销极小; - 所有语言站点复用同一个
server块,配置简洁,便于统一加 HTTPS、缓存或日志; - 路径必须真实存在且 Nginx 进程有读取权限(如
/var/www/zh/index.html)。
替代方案:用多个 server 块(适合少量语言)
每个语言单独一个 server,语义清晰、调试简单:
server {
listen 80;
server_name zh.example.com;
root /var/www/zh;
index index.html;
try_files $uri $uri/ /index.html;
}
server {
listen 80;
server_name en.example.com;
root /var/www/en;
index index.html;
try_files $uri $uri/ /index.html;
}
- 不依赖
map,兼容性更好(老版本 Nginx 也支持); - 缺点是语言增多时配置冗余,HTTPS 证书、重定向等需逐个复制。
注意 root 和 alias 的区别,别混用
-
root是拼接:root /var/www/zh;+ 请求/css/app.css→ 查找/var/www/zh/css/app.css; -
alias是替换:location /zh/ { alias /var/www/zh/; }+ 请求/zh/css/app.css→ 查找/var/www/zh/css/app.css; - 多语言站点通常用
root,因为每个子域对应完整站点结构,不需要路径前缀替换。
补充:支持带路径的语言标识(如 /en/xxx)
如果不想用子域,而用路径前缀(example.com/en/),就不能靠 root 动态切换——因为 root 在 location /en/ { ... } 内不生效(Nginx 会忽略)。此时应:
- 用
alias配合多location:location ^~/en/ { alias /var/www/en/; try_files $uri $uri/ /en/index.html; } location ^~/zh/ { alias /var/www/zh/; try_files $uri $uri/ /zh/index.html; } - 或统一入口 + 后端路由(前端框架如 Vue Router 的 history 模式需配合
try_files回退)。
不复杂但容易忽略:map 必须定义在 http 块顶层,不能放在 server 或 location 里;root 后面只能跟变量名或绝对路径,不能写 $var1$var2 这类拼接表达式。











