Hey everyone, I know some people have successfully set up Ghost on a sub-path (e.g., example.com/blog/) instead of a subdomain, which is better for SEO. However, I’m not sure how to do this, especially using Cloudflare Workers.
I have checked the guide but it won’t worked.
Has anyone here managed to configure Ghost this way? What steps or configurations are needed?
Thanks in advance! 
Okay i figured it out and wanted to share how i setup on subpath ghost:
https://qrcodedynamic.com/blog
Cloudflare Setup for Ghost Sub-Path Setup :
- Log in to your Cloudflare dashboard.
- Navigate to Workers > Overview > Create a Worker.
- Write the Worker Script:
- Below is a basic example script to proxy requests and rewrite URLs:
Step #1: Creating Cloudflare Worker Code: You need to change your website domain only.
// src/index.ts
var src_default = {
async fetch(request, env, ctx) {
const config = {
subdomain: "blog.qrcodedynamic.com",
root: "qrcodedynamic.com",
blogPath: "blog"
};
const url = new URL(request.url);
const targetPath = url.pathname;
let requestPath = `https://${config.subdomain}${targetPath}`;
if (targetPath == "/") {
requestPath = `https://${config.subdomain}/${config.blogPath}/`;
}
let response = await fetch(requestPath);
if (targetPath.includes(`/${config.blogPath}/favicon.png`) || targetPath.includes(`/${config.blogPath}/sitemap.xsl`) || targetPath.includes(`/${config.blogPath}/assets/`) || targetPath.includes(`/${config.blogPath}/public/`) || targetPath.includes(`/${config.blogPath}/content/`)) {
return response;
}
let body = await response.text();
body = body.split(config.subdomain).join(config.root);
response = new Response(body, response);
return response;
}
};
export {
src_default as default
};
//# sourceMappingURL=index.js.map
- Deploy the Worker:
- Save and deploy the script in the Cloudflare dashboard.
- Add a route (e.g., example.com/blog/*) under Workers > Your Worker > Triggers to associate it with your domain.
Step #2: You need to change your website url on ghostconfiguration.json as https://blog.qrcodedynamic.com/blog
-
- Explanation:
- The script checks if the request is for /blog/*.
- It removes /blog from the path and proxies the request to the Ghost instance.
- For HTML responses, it uses HTMLRewriter to prepend /blog to relative URLs (e.g., /post/123 becomes /blog/post/123).
If you have any question i am here to help