Documentation
Subpath Hosting
Use these templates when mode is SUBPATH. Replace /articles with your selected base path and set YOUR_TEXTA_UPSTREAM_HOST to the runtime host from integration config.
Required Paths
{basePath}{basePath}/:path*/blog-assets/:path*/_blog/:path*/api/blog-request/.well-known/:path*
Keep these rewrites above generic catch-all handlers to avoid accidental interception by app routes.
Vercel
{
"rewrites": [
{ "source": "/articles", "destination": "https://YOUR_TEXTA_UPSTREAM_HOST/blog" },
{ "source": "/articles/:path*", "destination": "https://YOUR_TEXTA_UPSTREAM_HOST/blog/:path*" },
{ "source": "/blog-assets/:path*", "destination": "https://YOUR_TEXTA_UPSTREAM_HOST/blog-assets/:path*" },
{ "source": "/_blog/:path*", "destination": "https://YOUR_TEXTA_UPSTREAM_HOST/_blog/:path*" },
{ "source": "/api/blog-request", "destination": "https://YOUR_TEXTA_UPSTREAM_HOST/api/blog-request" },
{ "source": "/.well-known/:path*", "destination": "https://YOUR_TEXTA_UPSTREAM_HOST/.well-known/:path*" }
],
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Forwarded-Host", "value": "blog.example.com" },
{ "key": "X-Forwarded-Proto", "value": "https" }
]
}
]
}Cloudflare Worker
export default {
async fetch(request) {
const url = new URL(request.url);
const upstream = new URL(request.url);
upstream.hostname = "YOUR_TEXTA_UPSTREAM_HOST";
if (url.pathname === "/articles") {
upstream.pathname = "/blog";
} else if (url.pathname.startsWith("/articles/")) {
upstream.pathname = "/blog" + url.pathname.slice("/articles".length);
} else if (
url.pathname.startsWith("/blog-assets/") ||
url.pathname.startsWith("/_blog/") ||
url.pathname === "/api/blog-request" ||
url.pathname.startsWith("/.well-known/")
) {
upstream.pathname = url.pathname;
} else {
return new Response("Not handled", { status: 404 });
}
const headers = new Headers(request.headers);
headers.set("X-Forwarded-Host", url.host);
headers.set("X-Forwarded-Proto", url.protocol.replace(":", ""));
return fetch(upstream.toString(), {
method: request.method,
headers,
body: request.body,
});
},
};Nginx
location = /articles {
proxy_set_header Host YOUR_TEXTA_UPSTREAM_HOST;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://YOUR_TEXTA_UPSTREAM_HOST/blog;
}
location /articles/ {
proxy_set_header Host YOUR_TEXTA_UPSTREAM_HOST;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://YOUR_TEXTA_UPSTREAM_HOST/blog/;
}
location /blog-assets/ {
proxy_set_header Host YOUR_TEXTA_UPSTREAM_HOST;
proxy_pass https://YOUR_TEXTA_UPSTREAM_HOST/blog-assets/;
}
location /_blog/ {
proxy_set_header Host YOUR_TEXTA_UPSTREAM_HOST;
proxy_pass https://YOUR_TEXTA_UPSTREAM_HOST/_blog/;
}
location = /api/blog-request {
proxy_set_header Host YOUR_TEXTA_UPSTREAM_HOST;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://YOUR_TEXTA_UPSTREAM_HOST/api/blog-request;
}
location /.well-known/ {
proxy_set_header Host YOUR_TEXTA_UPSTREAM_HOST;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://YOUR_TEXTA_UPSTREAM_HOST/.well-known/;
}AWS CloudFront
- Create behavior for
{basePath}and{basePath}/*. - Set origin to
YOUR_TEXTA_UPSTREAM_HOST. - Include
Host,X-Forwarded-Host,X-Forwarded-Protoin origin request policy. - Add separate behaviors for
/blog-assets/*,/_blog/*,/api/blog-request,/.well-known/*. - Rewrite
{basePath}to/blogand{basePath}/*to/blog/*in viewer-request function.
CSP Checklist
- Preserve existing script/style/image directives required by the blog runtime.
- Do not strip nonce/hash-based directives if already applied upstream.
- Keep
upgrade-insecure-requestsenabled for HTTPS-only custom hosts.