Publishing HTML on GitHub Pages

GitHub Pages provides a service that's hard to beat

  • Serve a website directly from your GitHub repo
  • Use your own domain with a CNAME or the default: http://<user><repo>/
  • Deliver content through the fastly CDN
  • Instant updates when files change
  • Proper gzipping of compressible files like HTML and CSS
  • Support for index.html files in directories
  • No charge for bandwidth

Compare that to hosting on S3 or S3 + Cloudfront

If you use CloudFront

  • You pay for CloudFront bandwidth - a lot if your traffic spikes
  • You get CDN performance but slooooow updates when your content changes
  • CloudFront doesn't fetch index.html files on requests for folders (just on the root)
  • CloudFront doesn't auto-gzip compressible content
  • You have to learn to work with the CloudFront console UI

There are also some benefits to using CloudFront

  • You get free SNI HTTPS - not available on GitHub Pages
  • You can configure CloudFront to route to dynamic back-end services
  • Like GitHub Pages, you can use your own domain name

You can also host websites on S3 without CloudFront in which case you don't get CDN performance but, (small consolation) you do get index.html support on sub directories.

Auto-gzip support is missing on S3. This means you are forced to decide between always compressing your HTML, potentially breaking browsers/crawlers which don't accept gzipped content, or never compressing your HTML, making large pages even larger and slower to download.

Publishing to GitHub Pages

Push a gh-pages branch to GitHub, and the files are published on the Internet. There is no CDN to configure. Everything is automatic.

Hosting on GitHub Pages does not require installing Ruby or learning Jekyll.

To prevent GitHub from running your content through the Jekyll site generator, just include an empty file called .nojekyll.

This is particularly important if you site has files or folders starting with _

How to generate and preview the HTML

There are many static site generators which can produce a static HTML website from a set of input files. Selecting the right one for you is the topic of a separate blog post.

This blog uses pub-server, the javascript site generator with a built-in editor. The markdown lives on GitHub here.

To preview at http://localhost:3001/ while I edit the markdown locally using any text editor, I simply run pub. The browser preview auto-reloads whenever I save the file.

To generate a new set of HTML into ./out

pub -O

The new set of files includes not just the HTML, but also any static images or CSS or other files like jQuery which are bundled with the theme or included with pub-server.

To preview the generated HTML output

pub -S out

This last step emulates a static-only web server, including some subtle behaviors like serving index.html when a directory URL is requested, or redirecting requests for a directory to a path with a terminating '/'.

Updating the gh_pages branch

I use just one repo.* The master branch holds the markdown source, and a copy of the generated HTML in /out. This makes generating and previewing easy, without having to switch branches.

The gh-pages branch contains an exact copy of the content in /out.

Here are the steps I use in my workflow, each time a new set of generated HTML has been committed to master.

git checkout gh-pages
git read-tree -u -m master:out
git commit -m 'publish to gh-pages'
git push
git checkout master

The step which does all the work, is git read-tree -u -m <tree-ish>.

The -m parameter merges the updated tree, and -u also updates the files in the working tree so that you can see the result, and test it locally.

* 2015-09-30 An even simpler approach is to use 2 repos, one for the source, and one for the published html. See here for details.

A note on relative paths

If you use GitHub Pages without a CNAME, your site will live at /repo-name, so you have to be careful not to include any "rooted" relative paths in your HTML.

E.g. <img src> should not point to "/images/..." because GitHub Pages won't be serving your site from the root.

pub-server can automatically prefix urls with ./ or ../ or ../../ etc. when it generates HTML, even if the markdown source contains links without these prefixes.

This is also useful if you want to test generated HTML files by opening them directly from your local file system using your browser.


powered by pub-server and pub-theme-pubblog