Serving a static blog from a subdirectory with Cloudflare Workers

Last updated: October 10, 2020
2 minute read
Serving a static blog from a subdirectory with Cloudflare Workers

When we first published our blog a couple of years back, we decided to use Jekyll. It’s simple, Ruby-based, established, and it does this one job really well. We’ve stuck with it.

According to the experts, there’s an SEO edge to hosting your blog in a subdirectory (statushero.com/blog) rather than a subdomain (blog.statushero.com ). Some claim (including Google) that it’s a negligible difference when you’re just starting your blog, but it seemed easy enough at the the time to implement, so why not.

Quick and Dirty

Since our main app and landing page is a Rails app deployed many times a week, we just published the static output from Jekyll to public/blog with some git submodule trickery. The blog files are almost immediately cached in the Cloudflare CDN and almost never incur a Rails request.

Hax

As you may have guessed, this coupling is cumbersome and bit of a hack for a variety of reasons. It would be much easier to host the blog on GitHub pages–a piece of cake with Jekyll–publish minor changes quickly, and open up the blog publishing step to those without prod access.

An nginx reverse proxy would do the job, but we’re serving the Rails app from Heroku with Puma app servers, so to do that we’d have to insert an extra bit of infrastructure somewhere in the stack. (Perhaps by switching to Phusion.) The trade-off didn’t seem worth it.

Enter Cloudflare Workers

We were just about to setup the redirects and switch back to blog.statushero.com when we stumbled across Cloudflare Workers. Have a look - it’s a powerful offering. With a few of lines of Javascript, our problem was solved:

addEventListener('fetch', event => {
  var url = new URL(event.request.url);
  if (url.pathname.startsWith('/blog/') || url.pathname === '/blog') {
    handleBlog(event, url);
  } else {
    event.respondWith(fetch(event.request));
  }
})

async function handleBlog(event, url) {
  var originUrl = url.toString().replace(
    'https://statushero.com/blog',
   'https://8012labs.github.io/statushero-blog');
  event.respondWith(fetch(originUrl)); 
}

Cloudflare even gives you a nice little browser-based UI to preview and test your Worker code.

Now we have the best of both worlds - a subdirectory for the blog with convenience of the Jekyll/GitHub pages combo.

Related Articles in Engineering:

    Henry Poydar

    Hello there! 👋

    I'm Henry Poydar, founder of Status Hero. I've been writing software and leading both co-located and remote software teams for 20+ years.

    In that time I've learned a lot about team communication, software estimation, and managing people — mostly the hard way.

    If you want to learn from my missteps (instead of your own) our newsletter is just right for you.

    Subscribe to get curated articles, tips, and links to support your efforts leading a modern, productive digital team every week or two.

    This is a private mailing list. Your name and email address will never be shared with any other entity. And every email to you will have an instant unsubscribe link.

    Try it out!

    Join thousands of other successful teams today.

    Use Status Hero for 21 days with no obligation, payment, or credit card required. Take it for a spin by yourself, or add a few other people to see if it works for your team.