Skip to content

Blog /Teamwork /

Serving a static blog from a subdirectory with Cloudflare Workers

October 10th, 2018

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.

More in Teamwork

Subscribe to The Steady Beat

A weekly round-up of hand-picked articles for people who make software: designers, engineers, product managers, and leaders.