Previously, the Chinese and English content on my WordPress site was separated by URL path:
中文站:
https://www.shuijingwanwq.com/
英文站:
https://www.shuijingwanwq.com/en/
As the English site became more independent, I moved the English content to a dedicated subdomain:
https://en.shuijingwanwq.com/
After the English subdomain went live, the homepage, posts, categories, tags, and series URLs previously located under /en/ all needed to be permanently migrated to the new domain with 301 redirects.
On a new site with no legacy redirect rules, a single Nginx rewrite might be enough.
My site, however, had already accumulated thousands of rules for tag slug conversion, legacy tag consolidation, and series path changes. Adding a generic /en/* redirect could bypass the existing slug mappings and also create a two-step 301 redirect chain.
This article documents the migration strategy, the final Nginx structure, the validation process, and how I now maintain 301 rules separately for the www primary domain and the en English subdomain.
For additional context, see the earlier article:
1. URL Structure Before and After the Migration
Before the migration, the English homepage and a regular English post used these URLs:
https://www.shuijingwanwq.com/en/
https://www.shuijingwanwq.com/en/2026/07/05/18871/
After the migration, the corresponding URLs became:
https://en.shuijingwanwq.com/
https://en.shuijingwanwq.com/2026/07/05/18871/
The basic migration target was therefore:
https://www.shuijingwanwq.com/en/
→
https://en.shuijingwanwq.com/
And:
https://www.shuijingwanwq.com/en/2026/07/05/18871/
→
https://en.shuijingwanwq.com/2026/07/05/18871/
The migration needed to remove the leading /en/ path segment while preserving the rest of the post path and any query parameters.

/en/ homepage returns a 301 before the English homepage loads successfully from the en subdomain.2. Why a Single Generic rewrite Was Not Enough
If a site has no other legacy redirects, a rule like the following may be sufficient:
rewrite ^/en(?:/(.*))?$ https://en.shuijingwanwq.com/$1 permanent;
My site, however, already had a large set of legacy URL mappings used to:
- Consolidate Chinese tag slugs;
- Convert Chinese tag slugs under the original
/en/path into English slugs; - Merge old series paths into new series paths;
- Normalize duplicate tags and other historical paths.
These rules were already maintained with an Nginx map in a structure similar to this:
map $uri $new_tag_uri {
default "";
~^/tag/权限/?$ "/tag/permission/";
~^/en/tag/权限/?$ "/en/tag/permission/";
~^/tag/30-天试用/?$ "/tag/30-day-trial/";
~^/en/tag/30-天试用/?$ "/en/tag/30-day-trial-en/";
~^/series/15-year-backend-dev-survival-notes-in-ai-era/?$
"/series/ai-era-developer-monetization-system/";
~^/en/series/15-year-backend-dev-survival-notes-in-ai-era-en/?$
"/en/series/ai-era-developer-monetization-system-en/";
}
Before migrating the English site, the mapped result could be returned directly from the server block:
if ($new_tag_uri != "") {
return 301 $new_tag_uri;
}
The problem is that if the generic /en/ redirect runs before the legacy mapping, the following URL:
https://www.shuijingwanwq.com/en/tag/30-天试用/
May be redirected directly to:
https://en.shuijingwanwq.com/tag/30-天试用/
The existing rule responsible for converting the Chinese tag slug into an English slug would then be bypassed.
If the legacy mapping runs first and the domain migration is handled separately afterward, the request may instead follow this path:
https://www.shuijingwanwq.com/en/tag/30-天试用/
→
https://www.shuijingwanwq.com/en/tag/30-day-trial-en/
→
https://en.shuijingwanwq.com/tag/30-day-trial-en/
The final destination is correct, but the browser has to pass through two separate 301 responses.
The preferable result is:
https://www.shuijingwanwq.com/en/tag/30-天试用/
→
https://en.shuijingwanwq.com/tag/30-day-trial-en/
In other words, a single 301 should perform both operations:
旧标签 slug 转换
+
英文域名迁移
Because the final configuration is already live, this two-step redirect can no longer be reproduced online. I have therefore kept the path-flow explanation without adding a screenshot for that intermediate scenario.
3. The Final Layered Redirect Strategy
Rather than editing thousands of existing mappings one by one, I added a second layer after the legacy mapping to convert the normalized path into its final domain URL.
The overall flow is:
请求进入 Nginx
↓
检查是否命中旧标签或旧专题规则
↓
命中后生成标准目标路径
↓
判断标准路径是否以 /en/ 开头
↓
以 /en/ 开头:
移除 /en/,跳转到 en 英文子域名
↓
不以 /en/ 开头:
继续跳转到 www 中文主域名
↓
如果没有命中旧路径映射
↓
检查原始请求是否为普通 /en/ 页面
↓
统一迁移到 en 英文子域名
This approach satisfies all of the following requirements:
- Existing tag and series mappings continue to work;
- Legacy English tag URLs reach their final English destinations in one redirect;
- Legacy Chinese tag URLs remain on the
wwwprimary domain; - Regular English posts, pages, and categories are migrated consistently;
- Existing rules do not need to be rewritten individually.
4. Layer One: Keep the Existing Legacy Path Mappings
The original $new_tag_uri variable continues to normalize historical URLs into canonical paths.
For example:
~^/tag/30-天试用/?$ "/tag/30-day-trial/";
This means:
/tag/30-天试用/
→
/tag/30-day-trial/
Legacy English paths continue to retain the /en/ marker:
~^/en/tag/30-天试用/?$ "/en/tag/30-day-trial-en/";
This means:
/en/tag/30-天试用/
→
/en/tag/30-day-trial-en/
At this stage, the mapping only produces a normalized destination path. It is not yet returned to the browser.
Keeping the /en/ prefix is important because the next layer can use it to determine that the final destination belongs on the English subdomain.
5. Layer Two: Convert the Normalized Path into the Final Domain URL
I added a second map to the existing mapping file:
# 仅处理 www/裸域旧规则的映射结果
# en.shuijingwanwq.com 后续使用独立的英文标签跳转规则
map "$host:$new_tag_uri" $www_final_redirect_uri {
default "";
# www 旧 /en/ 路径:去掉 /en/,跳转到英文子域名
~*^(?:www\.shuijingwanwq\.com|shuijingwanwq\.com):/en/(.*)$
"https://en.shuijingwanwq.com/$1";
# www 中文旧路径:继续留在 www 主域名
~*^(?:www\.shuijingwanwq\.com|shuijingwanwq\.com):/(.*)$
"https://www.shuijingwanwq.com/$1";
}
This map evaluates both:
$host
$new_tag_uri
It can therefore distinguish between:
www.shuijingwanwq.com:/en/tag/...
And:
www.shuijingwanwq.com:/tag/...
When the first layer produces:
/en/tag/30-day-trial-en/
The second layer converts it into:
https://en.shuijingwanwq.com/tag/30-day-trial-en/
When the first layer produces:
/tag/30-day-trial/
It is converted into:
https://www.shuijingwanwq.com/tag/30-day-trial/
This allows legacy English and Chinese tag URLs to be routed correctly while still using the same historical mapping set.
6. A Fallback Rule for Regular /en/ Pages
The legacy tag and series mappings only cover historical paths that have been explicitly registered.
Regular English posts, pages, and categories usually do not match $new_tag_uri, so a fallback mapping is still required for ordinary /en/ paths:
# www/裸域普通 /en/ 路径迁移到英文子域名
# 仅作为旧标签、旧专题映射之后的兜底规则
map "$host:$uri" $www_en_migration_uri {
default "";
~*^(?:www\.shuijingwanwq\.com|shuijingwanwq\.com):/en/?$
"https://en.shuijingwanwq.com/";
~*^(?:www\.shuijingwanwq\.com|shuijingwanwq\.com):/en/(.*)$
"https://en.shuijingwanwq.com/$1";
}
It handles:
https://www.shuijingwanwq.com/en/
https://www.shuijingwanwq.com/en/2026/07/05/18871/
https://www.shuijingwanwq.com/en/category/wordpress/
As well as any other /en/ URL that does not match a legacy mapping.
7. Execution Order Inside the server Block Matters
Inside the Nginx server block, the precise legacy mapping result must be checked before the generic /en/ migration fallback:
# 旧标签、旧专题先映射,再一次跳转到最终中文或英文域名
if ($www_final_redirect_uri != "") {
return 301 $www_final_redirect_uri$is_args$args;
}
# 未命中旧规则的普通 /en/ 页面迁移到英文子域名
if ($www_en_migration_uri != "") {
return 301 $www_en_migration_uri$is_args$args;
}
The order must not be reversed.
If the generic /en/ fallback runs first, legacy English tag URLs are moved to the English subdomain before the original tag slug conversion has a chance to run.
The current order can be summarized as:
先处理精确的旧标签和旧专题映射
再处理通用的 /en/ 域名迁移
This is the most important part of the implementation. The production virtual host follows this order and only checks the English subdomain’s independent rules afterward.
8. Preserving Query Parameters from the Original Request
During testing, I found that the path was redirected to the correct final English URL, but the initial version did not preserve the test query parameters.
For example:
?utm_source=redirect-test&utm_medium=nginx
To preserve UTM parameters, advertising attribution data, and other query strings, I added the following to the final return directive:
$is_args$args
The complete form is:
return 301 $www_final_redirect_uri$is_args$args;
And:
return 301 $www_en_migration_uri$is_args$args;
Where:
$argscontains the original request’s query parameters;$is_argsoutputs?when query parameters are present;- When there are no query parameters,
$is_argsis empty.
Test command:
curl -4 -sS -I --max-time 20 "https://www.shuijingwanwq.com/en/tag/30-%E5%A4%A9%E8%AF%95%E7%94%A8/?utm_source=redirect-test&utm_medium=nginx" | grep -Ei "HTTP/|location:|server:|eo-cache-status"
Actual response:
HTTP/2 301
server: nginx
location: https://en.shuijingwanwq.com/tag/30-day-trial-en/?utm_source=redirect-test&utm_medium=nginx
eo-cache-status: MISS
As shown in the response, the legacy tag URL completes both slug conversion and domain migration while keeping the query parameters intact.

utm_source and utm_medium query parameters remain intact after the legacy English tag URL completes its 301 redirect.9. A Separate Rule File for the English Subdomain
After completing the migration, I created a separate file:
/usr/local/nginx/conf/include/shuijingwan_en_redirect.conf
This file is not used to process historical URLs under /en/.
For example:
https://www.shuijingwanwq.com/en/tag/旧地址/
The source belongs to the legacy www site, so it should still be handled by:
shuijingwan_nginx_redirect.conf
This file remains responsible for that redirect.
By contrast, a URL such as:
https://en.shuijingwanwq.com/tag/旧地址/
Because this source URL is already on the new English subdomain, it should be handled by:
shuijingwan_en_redirect.conf
This file remains responsible for that redirect.
en.shuijingwanwq.com only went live as part of this migration, so it does not yet have thousands of historical English-subdomain URLs to support.
There is therefore no reason to duplicate thousands of existing /en/tag/... mappings and manually remove /en/ from every one.
For now, the English rule file contains only an empty framework:
# en.shuijingwanwq.com 独立旧路径跳转规则
# 以后英文域名自身出现需要合并或变更的网址时,在这里添加
map $uri $en_new_uri {
default "";
}
If a tag on the English subdomain needs to be merged later, a rule can be added such as:
~^/tag/old-slug/?$ "/tag/new-slug/";
The following map can then build the complete destination URL:
# 仅在 en.shuijingwanwq.com 上执行英文旧路径跳转
map "$host:$en_new_uri" $en_final_redirect_uri {
default "";
~*^en\.shuijingwanwq\.com:(/.*)$
"https://en.shuijingwanwq.com$1";
}
The corresponding logic in the server block is:
if ($en_final_redirect_uri != "") {
return 301 $en_final_redirect_uri$is_args$args;
}
The final English rule file therefore contains only an empty mapping framework and a domain restriction; it does not duplicate the thousands of historical rules from the former /en/ path.
10. Responsibilities of the Two Rule Files
After the migration, the responsibilities of the two configuration files are clearly separated.
shuijingwan_nginx_redirect.conf
It handles historical source URLs on:
www.shuijingwanwq.com
As well as:
shuijingwanwq.com
These are the domains covered by the legacy rule set.
This includes:
# 中文主站旧地址
~^/tag/旧中文标签/?$ "/tag/新中文标签/";
# 历史上位于 www /en/ 下的英文旧地址
~^/en/tag/旧英文标签/?$ "/en/tag/新英文标签/";
Although the second type of rule remains in the historical www rule file, the second map layer automatically converts its destination to:
en.shuijingwanwq.com
shuijingwan_en_redirect.conf
It handles only future legacy URLs whose source is already on:
en.shuijingwanwq.com
This English subdomain.
There are currently no active path mappings in this file. New rules will be added only after the English subdomain develops its own tag mergers, series renames, or path changes.
A simple way to remember the separation is:
www 或旧 www/en/ 来源
→ shuijingwan_nginx_redirect.conf
en 子域名来源
→ shuijingwan_en_redirect.conf

include directory, together with backup files created during the migration.11. Validating Each Redirect Scenario
After updating the configuration, I tested the legacy English homepage, a legacy English tag, a regular English post, a legacy Chinese tag, and a legacy English series URL separately.
To avoid accidental spaces after backslashes when copying multiline Bash commands, all commands below are written on a single line.
1. Test the Legacy English Homepage
curl -4 -sS -I -L --max-time 30 "https://www.shuijingwanwq.com/en/" | grep -Ei "HTTP/|location:|server:|eo-cache-status|cf-cache-status"
Expected redirect chain:
HTTP/2 301
location: https://en.shuijingwanwq.com/
HTTP/2 200
The browser developer tools also show the old /en/ request returning a 301 before the English subdomain homepage loads successfully.
2. Test a Legacy English Tag URL
For paths containing Chinese characters, it is safer to use percent-encoded URLs:
curl -4 -sS -I -L --max-time 30 "https://www.shuijingwanwq.com/en/tag/30-%E5%A4%A9%E8%AF%95%E7%94%A8/" | grep -Ei "HTTP/|location:|server:|eo-cache-status|cf-cache-status"
Actual result:
HTTP/2 301
server: nginx
location: https://en.shuijingwanwq.com/tag/30-day-trial-en/
eo-cache-status: MISS
HTTP/2 200
server: cloudflare
cf-cache-status: MISS
The entire process uses only one 301 redirect.

3. Test a Regular English Post
curl -4 -sS -I -L --max-time 30 "https://www.shuijingwanwq.com/en/2026/07/05/18871/" | grep -Ei "HTTP/|location:|server:|eo-cache-status|cf-cache-status"
Actual result:
HTTP/2 301
server: nginx
location: https://en.shuijingwanwq.com/2026/07/05/18871/
eo-cache-status: MISS
HTTP/2 200
server: nginx
This confirms that the regular English post correctly matched the /en/ migration fallback.

/en/ is 301 → 200.4. Test a Legacy Chinese Tag URL
curl -4 -sS -I -L --max-time 30 "https://www.shuijingwanwq.com/tag/30-%E5%A4%A9%E8%AF%95%E7%94%A8/" | grep -Ei "HTTP/|location:|server:|eo-cache-status|cf-cache-status"
Actual result:
HTTP/2 301
server: nginx
location: https://www.shuijingwanwq.com/tag/30-day-trial/
eo-cache-status: MISS
HTTP/2 200
server: nginx
eo-cache-status: MISS
The legacy Chinese tag remains on the Chinese www primary domain and is not incorrectly moved to the English subdomain.

www primary domain.5. Test a Legacy English Series URL
curl -4 -sS -I -L --max-time 30 "https://www.shuijingwanwq.com/en/series/15-year-backend-dev-survival-notes-in-ai-era-en/" | grep -Ei "HTTP/|location:|server:|eo-cache-status|cf-cache-status"
Actual result:
HTTP/2 301
server: nginx
location: https://en.shuijingwanwq.com/series/ai-era-developer-monetization-system-en/
eo-cache-status: MISS
HTTP/2 200
server: cloudflare
cf-cache-status: MISS
This confirms that the legacy series rule can normalize the slug first and then reach the final English-subdomain URL in a single redirect.

12. Why a Copied Multiline curl Command May Fail
During testing, I copied a command similar to this:
curl -4 -sS -I -L \ "https://www.shuijingwanwq.com/en/tag/..."
curl then returned an error:
curl: (1) Protocol " https" not supported or disabled in libcurl
The server did support HTTPS. The actual problem was a space after the backslash:
\
In the shell, a backslash escapes the character immediately following it.
When that character is a space, curl receives a URL that effectively begins with a space:
https://www.shuijingwanwq.com/...
curl therefore interprets the protocol as:
https
Instead of the valid form:
https
To avoid hidden spaces introduced when copying from WordPress, chat windows, or code blocks, every test command in this article is written as a single line.
When a multiline Bash command is unavoidable, the backslash must be the final character on the line, with no spaces or other characters after it.
13. curl May Return 400 for an Unencoded Chinese URL
When testing a tag URL containing Chinese characters, I initially ran:
curl -I "https://en.shuijingwanwq.com/tag/30-天试用/"
In this test environment, the response was:
HTTP/2 400
This does not necessarily mean that the Nginx mapping failed, because the Chinese path in the command had not yet been percent-encoded.
After encoding the Chinese path:
curl -4 -sS -I --max-time 20 "https://en.shuijingwanwq.com/tag/30-%E5%A4%A9%E8%AF%95%E7%94%A8/"
The request was sent successfully.
Browsers usually encode Chinese paths automatically, so the same problem is less likely to appear during normal browser access.
When testing URLs containing Chinese characters from the command line, it is best to use the percent-encoded form consistently.
14. Why the 301 Rules Live in Nginx Instead of Entirely at the CDN Layer
The Chinese primary domain and the English subdomain currently use different CDN configurations:
www.shuijingwanwq.com
→ EdgeOne
en.shuijingwanwq.com
→ Cloudflare
Both EdgeOne and Cloudflare can issue redirects, but I still chose Nginx as the authoritative source for this migration’s 301 rules for several reasons:
- The legacy tag and series rules already lived in Nginx;
- Path normalization and domain migration need to be evaluated together;
- Splitting the rules across two CDN dashboards would make redirect precedence harder to troubleshoot;
- The origin rules will continue to work if the CDN provider changes later;
- Thousands of legacy mappings should not be maintained repeatedly in multiple control panels.
A CDN may cache some 301 responses, but the underlying redirect logic remains centrally managed at the origin.
This is easier to maintain over the long term and makes the complete redirect flow visible in one configuration.
15. Final Result
After the migration, all of the following scenarios were verified successfully.
Regular English Pages
www.shuijingwanwq.com/en/...
→
en.shuijingwanwq.com/...
English Tag URLs with Legacy Slugs
www.shuijingwanwq.com/en/tag/旧-slug/
→
en.shuijingwanwq.com/tag/最终-slug/
Only one 301 redirect is used.
Legacy Chinese Tag URLs
www.shuijingwanwq.com/tag/旧-slug/
→
www.shuijingwanwq.com/tag/最终-slug/
They remain on the Chinese primary domain.
Future Rules Created on the English Subdomain
en.shuijingwanwq.com/旧路径/
→
en.shuijingwanwq.com/新路径/
They are added to the dedicated English rule file and are not mixed with the legacy /en/ migration rules.
16. Conclusion
Migrating a WordPress English site from /en/ to a dedicated subdomain may appear to require nothing more than removing one path prefix.
Once a site has accumulated extensive tag consolidation, slug translation, and series redirect rules, however, a single generic rewrite can easily cause:
- Legacy rules to be bypassed;
- Slugs to remain unconverted;
- Two consecutive 301 redirects;
- Lost query parameters;
- Interference between Chinese and English rules;
- Uncertainty about which configuration file should be updated later.
The final implementation uses layered mappings:
历史路径映射
→
最终域名转换
→
普通 /en/ 兜底迁移
It also separates:
旧 www 和旧 www/en/ 规则
From:
英文子域名上线后产生的新规则
For ongoing maintenance.
This preserves the existing thousands of rules while allowing legacy English URLs to reach their final English-subdomain destinations in a single redirect. It also leaves a clear extension point for future tag and series path changes.
Appendix 1: Sanitized Nginx Virtual Host Configuration
The following example preserves the complete virtual host structure relevant to this migration.
Certificate paths, log paths, the WordPress document root, and the PHP-FPM socket have been replaced with generic placeholders. The configuration must not be copied into production without adapting those values.
# map 必须位于 http 上下文。
# 当前环境中的 vhost 文件由 nginx.conf 在 http 块内引入。
# 引入 www 主域名及历史 /en/ 路径规则
include /usr/local/nginx/conf/include/shuijingwan_nginx_redirect.conf;
# 引入 en.shuijingwanwq.com 独立旧路径规则
include /usr/local/nginx/conf/include/shuijingwan_en_redirect.conf;
server {
limit_req zone=site_limit burst=50 nodelay;
limit_conn conn_limit 50;
limit_req_status 429;
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /path/to/ssl/example.com.crt;
ssl_certificate_key /path/to/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256;
ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256;
ssl_conf_command Options PrioritizeChaCha;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_buffer_size 2k;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
server_name
www.shuijingwanwq.com
shuijingwanwq.com
en.shuijingwanwq.com;
access_log /path/to/logs/example.com.access.log combined;
index index.html index.htm index.php;
root /path/to/wordpress;
if ($ssl_protocol = "") {
return 301 https://$host$request_uri;
}
if ($host = shuijingwanwq.com) {
return 301 $scheme://www.shuijingwanwq.com$request_uri;
}
# 非 www 域名访问 WordPress 后台时,统一跳回 www 主域名。
set $redirect_non_www_admin "";
if ($host != www.shuijingwanwq.com) {
set $redirect_non_www_admin "${redirect_non_www_admin}H";
}
if ($uri ~* "^/(wp-admin(?:/|$)|wp-login\.php$)") {
set $redirect_non_www_admin "${redirect_non_www_admin}U";
}
if ($redirect_non_www_admin = "HU") {
return 301 https://www.shuijingwanwq.com$request_uri;
}
include /usr/local/nginx/conf/rewrite/wordpress.conf;
location ~ .*\.(wma|wmv|asf|mp3|mmf|zip|rar|jpg|gif|png|swf|flv|mp4)$ {
valid_referers
none
blocked
*.shuijingwanwq.com
www.shuijingwanwq.com
shuijingwanwq.com;
if ($invalid_referer) {
return 403;
}
}
# 所有 /amp 后缀链接跳转到对应规范页面。
location ~* ^(.+)/amp/?$ {
return 301 $1/;
}
# 旧标签、旧专题先完成映射,
# 再一次跳转到最终中文或英文域名。
if ($www_final_redirect_uri != "") {
return 301 $www_final_redirect_uri$is_args$args;
}
# 未命中旧规则的普通 /en/ 页面,
# 统一迁移到英文子域名。
if ($www_en_migration_uri != "") {
return 301 $www_en_migration_uri$is_args$args;
}
# en 子域名以后产生的独立旧路径规则。
if ($en_final_redirect_uri != "") {
return 301 $en_final_redirect_uri$is_args$args;
}
location ~ [^/]\.php(/|$) {
fastcgi_pass unix:/path/to/php-fpm.sock;
fastcgi_index index.php;
fastcgi_read_timeout 150s;
include fastcgi.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
expires 30d;
access_log off;
}
location ~ .*\.(js|css)?$ {
expires 7d;
access_log off;
}
location ~ /(\.user\.ini|\.ht|\.git|\.svn|\.project|LICENSE|README\.md) {
deny all;
}
location /.well-known {
allow all;
}
}
Appendix 2: Historical Redirect Rules for www and the Former /en/ Path
In production, $new_tag_uri contains thousands of tag and series mappings.
Expanding every rule in the article would make it unnecessarily large and obscure the two-layer conversion logic that actually matters.
The example below therefore preserves the real file structure and representative rules, while omitting large groups of equivalent mappings with comments.
map $uri $new_tag_uri {
default "";
# 中文标签合并
~^/tag/权限/?$ "/tag/permission/";
~^/tag/菜单/?$ "/tag/menu/";
~^/tag/安装/?$ "/tag/installation/";
# 原 /en/ 路径下的英文标签标准化
~^/en/tag/权限/?$ "/en/tag/permission/";
~^/en/tag/菜单/?$ "/en/tag/menu/";
~^/en/tag/安装/?$ "/en/tag/installation/";
# 同一个中文标签在中英文站使用不同的最终 slug
~^/tag/30-天试用/?$ "/tag/30-day-trial/";
~^/en/tag/30-天试用/?$ "/en/tag/30-day-trial-en/";
~^/tag/在线商店/?$ "/tag/online-store/";
~^/en/tag/在线商店/?$ "/en/tag/online-store-en/";
~^/tag/多个-php-版本/?$ "/tag/multiple-php-versions/";
~^/en/tag/多个-php-版本/?$ "/en/tag/multiple-php-versions-en/";
~^/tag/chrome扩展/?$ "/tag/chrome-extension/";
~^/en/tag/chrome扩展/?$ "/en/tag/chrome-extension-en/";
# ……中间省略数千条同类标签映射……
# 中文专题合并
~^/series/15-year-backend-dev-survival-notes-in-ai-era/?$
"/series/ai-era-developer-monetization-system/";
# 原 /en/ 下的英文专题合并
~^/en/series/15-year-backend-dev-survival-notes-in-ai-era-en/?$
"/en/series/ai-era-developer-monetization-system-en/";
}
# 仅处理 www/裸域旧规则的映射结果
# en.shuijingwanwq.com 后续使用独立的英文标签跳转规则
map "$host:$new_tag_uri" $www_final_redirect_uri {
default "";
# www 旧 /en/ 路径:
# 去掉 /en/,一次跳转到英文子域名
~*^(?:www\.shuijingwanwq\.com|shuijingwanwq\.com):/en/(.*)$
"https://en.shuijingwanwq.com/$1";
# www 中文旧路径:
# 继续留在中文主域名
~*^(?:www\.shuijingwanwq\.com|shuijingwanwq\.com):/(.*)$
"https://www.shuijingwanwq.com/$1";
}
# www/裸域普通 /en/ 路径迁移到英文子域名
# 仅作为旧标签、旧专题映射之后的兜底规则
map "$host:$uri" $www_en_migration_uri {
default "";
~*^(?:www\.shuijingwanwq\.com|shuijingwanwq\.com):/en/?$
"https://en.shuijingwanwq.com/";
~*^(?:www\.shuijingwanwq\.com|shuijingwanwq\.com):/en/(.*)$
"https://en.shuijingwanwq.com/$1";
}
In the future, if a source URL belongs to:
www.shuijingwanwq.com
Or to the former:
www.shuijingwanwq.com/en/
The mapping should still be added to this file.
Appendix 3: Independent Redirect Rules for the English Subdomain
en.shuijingwanwq.com only went live during this migration, so there is currently no large set of historical English-subdomain URLs to migrate.
The final file contains only the rule framework:
# en.shuijingwanwq.com 独立旧路径跳转规则
# 以后英文域名自身出现需要合并或变更的网址时,在这里添加
map $uri $en_new_uri {
default "";
# 示例:
# ~^/tag/old-slug/?$ "/tag/new-slug/";
}
# 仅在 en.shuijingwanwq.com 上执行英文旧路径跳转
map "$host:$en_new_uri" $en_final_redirect_uri {
default "";
~*^en\.shuijingwanwq\.com:(/.*)$
"https://en.shuijingwanwq.com$1";
}
A mapping should be added to this file only when the source URL itself already belongs to:
https://en.shuijingwanwq.com/
This English subdomain.
需要长期技术维护或远程问题排查?
我是拥有 15+ 年经验的 PHP / Go 后端工程师,长期关注已有系统维护、Bug 修复、性能优化、服务器排查、WordPress 网站维护和小功能迭代。
如果你的项目遇到以下情况,可以先从一次小问题排查开始合作:
- ✅ PHP / Laravel / Yii2 老项目无人维护
- ✅ Go / Gin 后端接口需要排查或优化
- ✅ WordPress 网站访问慢、报错或插件冲突
- ✅ Nginx / MySQL / Redis / Linux 服务器异常
- ✅ CDN / Cloudflare / DNS / HTTPS 配置问题
- ✅ 需要长期远程技术支持或兼职维护
更多介绍请查看:关于我 & 合作
微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan


发表回复