Cloudflare Workers
Use Cloudflare Workers to serve your blog at a subpath like yoursite.com/blog. Workers intercept requests and route them to the appropriate destination based on the URL path.
You'll need a Cloudflare account and a domain (either managed on Cloudflare or elsewhere). If using Cloudflare for DNS, consider disabling proxying for CNAME records to avoid configuration conflicts.
Create a Cloudflare Worker
If you don't already have a Worker, create one through the Cloudflare dashboard:
- Log into your Cloudflare dashboard
- Navigate to Workers & Pages
- Click Create Worker
- Give your Worker a descriptive name
- Click Deploy to create the initial Worker
For detailed steps, see Cloudflare's Workers getting started guide.
Configure the Worker Script
Edit your Worker's code to route Waldium paths to your Waldium site. Replace [SUBDOMAIN] with your Waldium subdomain and [YOUR_DOMAIN] with your website's domain.
Paths routed to Waldium:
/blog— Your blog content/waldium-assets— Static assets for your blog/_waldium— Internal Waldium resources/api/waldium-request— Waldium API endpoint
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
try {
const url = new URL(request.url);
// Route Waldium paths to Waldium
if (
url.pathname.startsWith("/blog") ||
url.pathname.startsWith("/waldium-assets") ||
url.pathname.startsWith("/_waldium") ||
url.pathname === "/api/waldium-request"
) {
const BLOG_URL = "[SUBDOMAIN].waldium.app";
const CUSTOM_URL = "[YOUR_DOMAIN]";
let proxyUrl = new URL(url.pathname + url.search, `https://${BLOG_URL}`);
let proxyRequest = new Request(proxyUrl, request);
proxyRequest.headers.set("Host", BLOG_URL);
proxyRequest.headers.set("X-Forwarded-Host", CUSTOM_URL);
proxyRequest.headers.set("X-Forwarded-Proto", "https");
proxyRequest.headers.set("CF-Connecting-IP", request.headers.get("CF-Connecting-IP"));
return await fetch(proxyRequest);
}
// Everything else passes through to origin
return await fetch(request);
} catch (error) {
return await fetch(request);
}
}
Click Deploy after adding the script.
Custom Subpath
By default, Waldium serves your blog at /blog. If you want to host it at a different path — for example, /articles or /news — you need to update the Worker script to rewrite paths and fix links in the HTML response.
The subpath you choose here must match the subpath you configure in your Waldium Domain Settings. For example, if you enter yoursite.com with subpath /articles in Waldium, your Worker must use /articles as the custom subpath.
Worker Script with Path Rewrite
Replace [SUBDOMAIN], [YOUR_DOMAIN], and the CUSTOM_SUBPATH value with your own:
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
try {
const url = new URL(request.url);
const CUSTOM_SUBPATH = "/articles"; // your chosen subpath
if (
url.pathname.startsWith(CUSTOM_SUBPATH) ||
url.pathname.startsWith("/waldium-assets") ||
url.pathname.startsWith("/_waldium") ||
url.pathname === "/api/waldium-request"
) {
const BLOG_URL = "[SUBDOMAIN].waldium.app";
const CUSTOM_URL = "[YOUR_DOMAIN]";
// Rewrite custom subpath to /blog for Waldium
let waldiumPath = url.pathname + url.search;
if (url.pathname.startsWith(CUSTOM_SUBPATH)) {
waldiumPath = "/blog" + url.pathname.slice(CUSTOM_SUBPATH.length) + url.search;
}
let proxyUrl = new URL(waldiumPath, `https://${BLOG_URL}`);
let proxyRequest = new Request(proxyUrl, request);
proxyRequest.headers.set("Host", BLOG_URL);
proxyRequest.headers.set("X-Forwarded-Host", CUSTOM_URL);
proxyRequest.headers.set("X-Forwarded-Proto", "https");
proxyRequest.headers.set("CF-Connecting-IP", request.headers.get("CF-Connecting-IP"));
const response = await fetch(proxyRequest);
// Rewrite /blog back to custom subpath in the HTML response
return new HTMLRewriter()
.on("a", {
element(el) {
const href = el.getAttribute("href");
if (href && href.startsWith("/blog")) {
el.setAttribute("href", CUSTOM_SUBPATH + href.slice(5));
}
}
})
.on("link", {
element(el) {
const href = el.getAttribute("href");
if (href && href.startsWith("/blog")) {
el.setAttribute("href", CUSTOM_SUBPATH + href.slice(5));
}
}
})
.on("script", {
element(el) {
const src = el.getAttribute("src");
if (src && src.startsWith("/blog")) {
el.setAttribute("src", CUSTOM_SUBPATH + src.slice(5));
}
}
})
.transform(response);
}
// Everything else passes through to origin
return await fetch(request);
} catch (error) {
return await fetch(request);
}
}
Why Path Rewriting Is Needed
Waldium always serves blog content at /blog internally. When you use a custom subpath like /articles:
| User requests | Worker fetches from Waldium |
|---|---|
/articles | /blog |
/articles/ | /blog/ |
/articles/my-post | /blog/my-post |
/waldium-assets/... | /waldium-assets/... (no rewrite) |
/_waldium/... | /_waldium/... (no rewrite) |
The HTMLRewriter handles the reverse — rewriting /blog back to /articles in all links, stylesheets, and scripts so that URLs in the browser stay consistent.
Worker Routes (Path-Specific)
When your main site already runs on the same domain (e.g. a WordPress or marketing site), use path-specific Worker Routes instead of attaching a Custom Domain to the Worker. This ensures only Waldium paths hit the Worker while all other traffic goes directly to your origin.
- In Cloudflare, go to Domains → yoursite.com → Workers Routes
- Add one route per path pattern, selecting your Worker for each:
| Route | Worker |
|---|---|
yoursite.com/articles | your-worker-name |
yoursite.com/articles/* | your-worker-name |
yoursite.com/waldium-assets/* | your-worker-name |
yoursite.com/_waldium/* | your-worker-name |
yoursite.com/api/waldium-request | your-worker-name |
Replace /articles with your chosen subpath. If your site also uses www, add matching www.yoursite.com routes.
Path-specific Worker Routes are the recommended approach when another service (WordPress, Webflow, etc.) already handles the root domain. Using a Custom Domain on the Worker would route all traffic through it, which can cause loops or break the main site.
Vercel Integration Considerations
If your main site is deployed on Vercel, the Worker must allow certain paths for domain verification and SSL certificates:
Required path allowlist:
/.well-known/acme-challenge/*— Let's Encrypt certificate verification/.well-known/vercel/*— Vercel domain verification
The script above passes all non-Waldium paths (including .well-known) through to your origin, so verification paths will work automatically. Ensure no additional rules block these paths.
Header forwarding:
The Host header must be correctly set in the Worker. The example script handles this, but custom modifications could break verification.
Webflow and Other Site Builders
If your main site runs on Webflow or another platform, you'll need the Worker to handle all traffic—routing blog requests to Waldium and everything else to your main site.
Ensure your main site is accessible before deploying this Worker, or visitors will see errors.
- Set up a staging URL for your main site (e.g.,
landing.yoursite.com) - Update the Worker to route non-blog traffic to your staging URL:
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
try {
const url = new URL(request.url);
// Route Waldium paths to Waldium
if (
url.pathname.startsWith("/blog") ||
url.pathname.startsWith("/waldium-assets") ||
url.pathname.startsWith("/_waldium") ||
url.pathname === "/api/waldium-request"
) {
const BLOG_URL = "[SUBDOMAIN].waldium.app";
const CUSTOM_URL = "[YOUR_DOMAIN]";
let proxyUrl = new URL(url.pathname + url.search, `https://${BLOG_URL}`);
let proxyRequest = new Request(proxyUrl, request);
proxyRequest.headers.set("Host", BLOG_URL);
proxyRequest.headers.set("X-Forwarded-Host", CUSTOM_URL);
proxyRequest.headers.set("X-Forwarded-Proto", "https");
proxyRequest.headers.set("CF-Connecting-IP", request.headers.get("CF-Connecting-IP"));
return await fetch(proxyRequest);
}
// Route everything else to your main site
const MAIN_SITE_URL = "[LANDING_DOMAIN]";
let mainSiteUrl = new URL(url.pathname + url.search, `https://${MAIN_SITE_URL}`);
return await fetch(mainSiteUrl, {
method: request.method,
headers: request.headers,
body: request.body
});
} catch (error) {
return await fetch(request);
}
}
Replace [LANDING_DOMAIN] with your staging URL (e.g., landing.yoursite.com).
Connect Your Domain
There are two ways to connect the Worker to your domain. Choose the one that fits your setup:
Option A: Custom Domain (Worker handles all traffic)
Use this when the Worker is the sole handler for the domain (e.g., Webflow or other site builder proxied through the Worker).
- In Cloudflare, navigate to your Worker
- Go to Settings > Domains & Routes > Add > Custom Domain
- Enter your domain (e.g.,
yoursite.com)
Add both yoursite.com and www.yoursite.com for complete coverage.
If your domain already has DNS records pointing elsewhere, you'll need to remove them first. The Worker must control all traffic for your domain.
Option B: Worker Routes (main site stays on origin)
Use this when another service (WordPress, a marketing site, etc.) already handles your root domain and you only want the Worker to intercept Waldium paths. See the Worker Routes table in the Custom Subpath section above for the exact routes to add.
Test Your Setup
Before going live, verify the Worker routes correctly:
- Test the Worker preview URL — Visit
your-worker.your-subdomain.workers.dev/blog - Confirm blog content loads — You should see your Waldium blog
- Check your main site — Ensure non-blog pages still work
DNS Propagation
After configuring your domain, changes typically appear within a few minutes. However, DNS propagation can take 1-4 hours, and occasionally up to 48 hours. If your subpath isn't working immediately, wait before troubleshooting.
Troubleshooting
| Issue | Solution |
|---|---|
| "Post not found" on custom subpath | The Worker must rewrite your custom path (e.g. /articles) to /blog when fetching from Waldium. Verify the CUSTOM_SUBPATH value and the pathname.slice() length match. |
Links in the blog point to /blog | Add the HTMLRewriter to rewrite /blog back to your custom subpath in a, link, and script elements. |
| Main site returns 404 or loops | You may have attached the domain as a Custom Domain on the Worker, routing all traffic through it. Use path-specific Worker Routes instead so only Waldium paths hit the Worker. |
| Assets (CSS/JS) not loading | Ensure Worker Routes include /waldium-assets/* and /_waldium/*. |
| "Domain already in use" error | The domain is already attached as a Custom Domain to another Worker or zone. Use Worker Routes instead of Custom Domain attachment. |