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:
- 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
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.
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
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.
gh-pages branch contains an exact copy of the content in
Here are the steps I use in my workflow, each time a new set of generated HTML has been committed to
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>.
-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.
<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
../../ 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.