Docusaurus Single-Locale Pages Deployment
Single-locale deployment is used to avoid ESA Pages static file count limits. The idea is to keep one Git repository, but create two ESA Pages projects. Each project builds only one locale.
Deployment Shape
Recommended structure:
Chinese Pages project -> https://nevergpdzy.com
English Pages project -> https://en.nevergpdzy.com
Both sites are deployed at the domain root. The English site does not use the /en prefix.
The route layout is:
https://nevergpdzy.com/docs/intro -> Chinese docs
https://nevergpdzy.com/blog -> Chinese blog
https://en.nevergpdzy.com/docs/intro -> English docs
https://en.nevergpdzy.com/blog -> English blog
Build Commands
Chinese project:
npm run build:zh
English project:
npm run build:en
Both commands generate site stats first, then build only one locale:
docusaurus build --locale zh-Hans
docusaurus build --locale en
In local verification, each single-locale output contains about 814 files, 413 directories, and 1227 total items, which stays below the common ESA Pages 2000 static file limit.
Environment Variables
Independent-domain single-locale mode requires both variables:
SITE_URL
SINGLE_LOCALE_DEPLOY
Chinese Pages project:
SITE_URL=https://nevergpdzy.com
SINGLE_LOCALE_DEPLOY=true
English Pages project:
SITE_URL=https://en.nevergpdzy.com
SINGLE_LOCALE_DEPLOY=true
If either variable is missing, the configuration falls back to the single-site bilingual behavior. In that fallback mode, hand-written links in the English locale continue to use /en/docs/intro and /en/blog.
Links And Language Switching
When independent-domain single-locale mode is enabled:
- Docusaurus
urlusesSITE_URL. baseUrlstays/.- Hand-written footer links no longer add
/enfor the English locale. - Navbar uses the custom
custom-locale-switchinstead of the defaultlocaleDropdown.
The custom language switch only changes navigation behavior and does not introduce new visual styling. Desktop uses Docusaurus' default navbar__link style, and the mobile sidebar uses the default menu__link menu style, so the same language switch is visible on mobile.
Switching rules:
https://nevergpdzy.com/docs/intro
-> https://en.nevergpdzy.com/docs/intro
https://en.nevergpdzy.com/docs/intro
-> https://nevergpdzy.com/docs/intro
Query strings and hashes are preserved:
https://nevergpdzy.com/docs/intro?x=1#title
-> https://en.nevergpdzy.com/docs/intro?x=1#title
The component derives the counterpart domain from the current SITE_URL:
- If the current hostname does not start with
en., the target hostname is prefixed withen.. - If the current hostname starts with
en., the target hostname removesen..
ESA Pages Project Settings
Chinese project:
Repository: current repository
Build command: npm run build:zh
Output directory: build
SITE_URL: https://nevergpdzy.com
SINGLE_LOCALE_DEPLOY: true
English project:
Repository: current repository
Build command: npm run build:en
Output directory: build
SITE_URL: https://en.nevergpdzy.com
SINGLE_LOCALE_DEPLOY: true
Do not build the full bilingual site in either single-locale ESA Pages project, or the deployment can hit the same file count problem again.
Verification Checklist
After a local or ESA build, check:
- The Chinese project has no
build/endirectory. - The English project has no
build/endirectory. - The Chinese project serves
/docs/intro. - The English project serves English content at
/docs/intro. - The English project's footer does not contain
/en/docs/introor/en/blog. - The Chinese site switches to
https://en.nevergpdzy.com. - The English site switches back to
https://nevergpdzy.com. sitemap.xmluses the current project'sSITE_URL.- The output stays under the ESA Pages file limit:
Get-ChildItem build -Recurse -File | Measure-Object
Get-ChildItem build -Recurse -Directory | Measure-Object
Old /en Paths
After split deployment succeeds, old /en/... URLs do not automatically become English independent-domain URLs. If old links must be preserved, add redirects in ESA later:
https://nevergpdzy.com/en/docs/intro
-> https://en.nevergpdzy.com/docs/intro
This redirect is not required for the first rollout. Add it after the main split deployment is working.