URL rewriting with Github Pages

redirectI adore Github Pages. I use them for everything I can, and try to avoid server-side code like the plague, exactly so that I can use them. The convenience of pushing to a repo and having the changes immediately reflected on the website with no commit hooks or any additional setup, is awesome. The free price tag is even more awesome. So, when the time came to publish my book, naturally, I wanted the companion website to be on Github Pages.

There was only one small problem: I wanted nice URLs, like http://play.csssecrets.io/pie-animated, which would redirect to demos on dabblet.com. Any sane person would have likely bitten the bullet and used some kind of server-side language. However, I’m not a particularly sane person 😀

Turns out Github uses some URL rewriting of its own on Github Pages: If you provide a 404.html, any URL that doesn’t exist will be handled by that. Wait a second, is that basically how we do nice URLs on the server anyway? We can do the same in Github Pages, by just running JS inside 404.html!

So, I created a JSON file with all demo ids and their dabblet URLs, a 404.html that shows either a redirection or an error (JS decides which one) and a tiny bit of Vanilla JS that reads the current URL, fetches the JSON file, and redirects to the right dabblet. Here it is, without the helpers:

(function(){

document.body.className = 'redirecting';

var slug = location.pathname.slice(1);

xhr({
	src: 'secrets.json',
	onsuccess: function () {
		var slugs = JSON.parse(this.responseText);
		
		var hash = slugs[slug];
		
		if (hash) {
			// Redirect
			var url = hash.indexOf('http') == 0? hash : 'http://dabblet.com/gist/' + hash;
			$('section.redirecting > p').innerHTML = 'Redirecting to <a href="' + url + '">' + url + '</a>…';
			location.href = url;
		}
		else {
			document.body.className = 'error not-found';
		}
	},
	onerror: function () {
		document.body.className = 'error json';
	}
});

})();

That’s all! You can imagine using the same trick to redirect to other HTML pages in the same Github Pages site, have proper URLs for a single page site, and all sorts of things! Is it a hack? Of course. But when did that ever stop us? 😀

  • dzr33

    Nice, I didn’t know github pages had url rewrites in place.

    One issue with using 404 for URL rewriting is that it gives the browser (or other client) wrong status information, and it might behave unexpectedly. On the server side this is easily fixed by forcing the correct status header, but for HTML I don’t think http-equiv=”Status” exists yet…?

  • Johannes Müller

    To me this looks too wrong from an HTTP perspektive to consider using this hack. I’ rather use HTML meta tag redirection if any hack at all.

  • GitHub Pages is extremely limited in terms of functionality – The lack of proper redirects is just the tip of the iceberg. You could consider using something like Netlify, which is a similar product but *does* offer redirects, and is free for open-source projects.

    Alternatively, why don’t you just host the redirects on whatever server is hosting this blog? You could do something similar to GitHub Pages where it’s automatically deployed via Git commits, except much more powerful. The setup of commit hooks is just a once-off cost, and it easily pays for itself once you want to do something more advanced than what GitHub Pages allows.

  • Roman Komarov

    I thought about similar solution when we moved Stylus’ gh-pages from the github.io to its domain, but I ended up with writing a special redirect layout — https://github.com/LearnBoost/stylus/blob/gh-pages/_layouts/redirect.html — so each page I need a redirect to would have a proper meta refresh redirect (should work even with JS disabled), as well as a really simple JS counterpart that would also pass the location’s hash (was useful as there were a lot of links to old documentation with all the headers’ anchors).

    That way for each page I had to use a redirect I needed just a really simple file with yaml front-matter — https://github.com/LearnBoost/stylus/blob/gh-pages/redirects/try.html

    • That’s still not a proper redirect though – Search engines won’t understand that it’s a permanent redirect, for example.

      • Roman Komarov

        Quick search told me that at least Google understands it (https://support.google.com/webmasters/answer/79812?hl=en, some other sources). For Stylus’ site I didn’t check when exactly, but now all the search results have the new site and don’t have the old. Of course, when there is a possibility to add a proper server-side redirects, they should be preferred, but for gh-pages or other similar static hostings the meta refresh seems to work fine enough.

        • Hmm, interesting. The page you linked to doesn’t actually specify whether Google treat it as a redirect, but I guess they do based on your comment about Stylus’ site.

          > “other similar static hostings”

          Every other static host I know of allows redirects. Github Pages is an outlier in terms of their lack of functionality 🙂

  • thanks for the post. I will follow these steps

  • Post free Classified ads from worldwide. visit http://www.adsskrill.com

  • Ahahah, oh my this is really dirty. 😀
    It did tear me a smile on an otherwise gloomy morning, so thanks for that!

  • estaples

    I think this is brilliant. A very resourceful end to a simple need.

  • Michael

    Unfortunately this makes it harder to use the back button to get back to the page before the redirect. On Chrome at least.

  • Lily Lily

    I ve heard about it. Thanks for sharing. prayer times

  • [REDACTED]

    Nice hack. I hate to be “that guy”, but why not just have your CMS create empty pages at those paths with HTTP-REFRESH meta tags pointing at the proper URLS? If you’re using Jekyll, there’s even a plugin for it (whitelisted for use with GHPages): https://github.com/jekyll/jekyll-redirect-from

    • If the pages are few and/or static, that approach works and thanks for the info! But what if they are dynamic?

  • ❦ emoji

  • smith