This repository hosts the Cloudflare Pages implementation of the Wechaty Website Proxy, replacing the legacy Nginx + Docker setup and enabling the JS.org custom domain without requiring DNS control.
This repository now uses Cloudflare Pages + _worker.js to implement a full reverse-proxy layer that merges two GitHub Pages sites (Jekyll + Docusaurus) into the unified domain wechaty.js.org, exactly replicating the original Nginx configuration.
Unlike Pages Functions β which cannot intercept static paths like /img, /css, /js, or /assets β the _worker.js file provides full Worker-level request control, enabling:
- Transparent reverse proxying
- URL rewriting and prefix routing
- Upstream redirect following (301/302/303/307/308)
- Jekyll β Docusaurus fallback
- Static asset interception
- GitHub Pages SSR-like merging of two upstreams
This achieves 100% feature parity with the original Nginx setup but is now faster, serverless, globally distributed, and fully compatible with JS.org custom domains.
Cloudflare Pages processes requests in this order:
- Static files (
/public) - _worker.js (FULL Worker control) β our proxy runs here
- Pages Functions (
/functions)
Pages Functions cannot intercept:
/img/*/css/*/js/*/assets/*/favicon.ico/manifest.json- Any other static-like path
But _worker.js intercepts every incoming request β making it the correct tool for reverse proxying.
flowchart LR
A[Visitor Browser] --> B[DNS: js.org]
B --> C[Cloudflare Pages<br>wechaty-js-org.pages.dev]
C --> D[_worker.js Reverse Proxy<br>Full Worker Runtime]
D -->|/docs, /img, /css, /js...| E[Docusaurus<br>wechaty.github.io/docusaurus]
D -->|All other paths| F[Jekyll<br>wechaty.github.io/jekyll]
F -->|404 fallback| E
E --> D --> C --> A
flowchart TD
A["Incoming Request"] --> B{"Path matches docs/img/css/js etc?"}
B -->|Yes| C["Route to Docusaurus<br/>(docusaurus + original path)"]
B -->|No| D["Route to Jekyll<br/>(jekyll + original path)"]
D --> E{"Did Jekyll return 404?"}
E -->|Yes| C
E -->|No| F["Return Jekyll Response"]
C --> G["Return Docusaurus Response"]
flowchart TD
A[Request] --> B{Cache Hit?}
B -->|Yes| C[Return Cached Response]
B -->|No| D[Fetch Upstream<br>Follow Redirects]
D --> E[Store in Edge Cache]
E --> C
/
ββ functions/
β ββ [[path]].js # Cloudflare Pages Function (proxy logic)
ββ public/ # Optionally used for static assets
ββ README.md
The core logic lives in functions/[[path]].js which intercepts all incoming paths.
- Cloudflare Dashboard β Pages β Create Project β Connect GitHub Repo
/
ββ _worker.js # Full Worker runtime for proxy logic
ββ public/ # Optional static files
ββ README.md
Cloudflare builds automatically. Deployment URL example:
https://wechaty-js-org.pages.dev
Open PR at: https://github.com/js-org/js.org
"wechaty.js.org": "wechaty-js-org.pages.dev"Cloudflare Pages CLI (wrangler pages dev) cannot simulate GitHub Pages reverse proxying β it rewrites origin hosts to localhost.
Use instead:
wrangler dev _worker.jsThis accurately simulates production Worker behavior.
Cloudflare Dashboard β Pages β Create Project β Connect GitHub Repo.
- Framework preset: None
- Build command: (empty)
- Output directory:
./ - Pages Functions automatically detected in
/functions
Cloudflare will assign:
https://<project>.pages.dev
Open PR in https://github.com/js-org/js.org:
"wechaty.js.org": "<project>.pages.dev"JS.org maintainers will CNAME wechaty.js.org β Cloudflare Pages.
run scripts/custom-domain-4-pages-dev.sh with your cloudflare account email/id and the global api key.
The _worker.js file provides:
- Full Worker API inside Cloudflare Pages
- Transparent GitHub Pages reverse proxy
- Prefix-based routing like original Nginx
- 404 fallback (Jekyll β Docusaurus)
- Internal redirect following
- Edge caching
- Universal asset handling (
/img,/css,/js, etc.)
Pages Functions do not run for static-like paths.
_worker.js is necessary to ensure complete routing control.
The Pages Function implements:
- Docusaurus/Jekyll routing
- 404 fallback
- GitHub Pages redirect handling
- Edge caching
- Transparent proxying
Code is located in functions/[[path]].js.
- Nginx + Docker Compose used as a transparent proxy
- Auto TLS with nginx-proxy + ACME companion
- Routing merged two GitHub Pages sites
All original infrastructure has been preserved in:
/deprecated/
- Removed all server dependencies
- Adopted globally distributed proxy logic
- Replaced Nginx config with Pages Functions
- Fully decoupled from Cloudflare DNS limitations
Huan LI (ζεζ‘) β Creator of Wechaty, open-source advocate, cloud-native architect.
GitHub: https://github.com/huan Website: https://wechaty.js.org
Released under the Apache-2.0 License.