URL rewriting with fly.io

Recently, I moved this site to be a static site (via Hugo), as well as moving to .com (instead of .org, which I've owned for a lot longer). I didn't want to break previous URLs, but my new posts have entirely new paths, so a simple path-for-path 301 redirect won't work. Most importantly, I wanted the redirection to require nearly no maintenance and be near free.

To avoid running a small server, I considered serverless approaches that would handle the URL rewriting for me. After playing with a few, I decided on fly.io. For those who have used reverse proxies before, consider their edge library like a super-flexible, scriptable reverse proxy.

This concept is incredibly flexible, and allows both requests and responses to be manipulated between your web app and client, including execution of fairly advanced routing logic, assembly of multiple RPCs, caching, etc. For my purpose, however, it's as simple as redirecting based on the request URL, and to the best I can tell, will run basically free[1] for low-traffic sites.

const URL = require('url');

const oldToNew = {
  "/old-path": "https://andrewconner.com/posts/new-path/",
  // etc ...
};

fly.http.respondWith(function(request){
  const reqUrl = URL.parse(request.url);
  let redirPath = '';
  if (oldToNew[reqUrl.pathname]) {
    redirPath = oldToNew[reqUrl.pathname] + (reqUrl.search || '');
  } else {
    let oldPath = reqUrl.pathname.length > 1 ? 'orig=' + encodeURIComponent(reqUrl.pathname + (reqUrl.search || '')) : '';
    let ref = (request.referrer ? '&ref=' + encodeURIComponent(request.referrer) : '');
    redirPath = 'https://andrewconner.com/?' + oldPath + ref;
  }
  return new Response('', { headers: { 'Location': redirPath }, status: 301});
});

This also lets me be a bit smarter about pages that will 404, where I redirect to the home page, but throw in the original path and referrer so I can fix future bad links that crop up.


  1. Update October 2019: Yep, basically free. I've paid a total of roughly $2. ↩︎

Stay connected

I send out occasional updates on posts, interesting finds, and projects I'm working on. I'd love to include you. No tracking, one-click unsubscribe.