How I built this blog with Github Pages, Jekyll and Cloudflare

October 11, 2014 (Updated September 9, 2015)

I’ve been thinking of doing a personal website for some time but never got round to it. Now with so many free services and tools from Github Pages, Jekyll and Cloudflare, there’s no excuse not to do so.

After 30 minutes setting up everything, I had this clean blog that I can update with Github’s web editor or a git push. Given many of my friends recently got a free .me domain, I’d love to see more people creating their own personal websites.

Getting started

Depending on how much tweaking you want to do, setting it up is just going to Github Pages and following the steps. At step 2 where it asks you to clone the repository, switch to this guide where you can pick a theme and start writing blog posts.

However, I didn’t quite like the themes in Github, so I followed this guide which has a base theme like this. Pretty awesome!

Jekyll Now Theme Screenshot

Making it my own

Out of the box, the blog was already looking good but I had to make it my own.

[Update: The avatar is not my Facebook profile picture as the API call takes a long time to load. However, if you want your avatar to be always up to date this section is still relavant]

Configuration and using my Facebook profile picture

First, I changed the defaults in the configuration file _config.yml. The hardest issue to figure out was how I could switch my avatar to my Facebook profile picture. Simply pointing it to the URL of my current profile picture was no good since the next time I changed my profile picture on Facebook, I would have to update the URL in configuration file as well. Luckily, Facebook’s Graph API comes to the rescue! As of v2.1, the {user-id}/picture endpoint gives us the current profile picture. We need some details before we can construct the API call:

  1. Your user ID: Find yours at What is my Facebook ID?
  2. Size of the avatar: My theme sets the size at 70 x 70

Since the API format is{your user ID}/picture?{options}, plugging these in gives us, shown right here!

Stirling's current profile picture

For best results, use a protocol-less URL, so modify _config.yml like this:

# URL of your avatar or profile pic (from FB's open graph profile picture)
avatar: //

Blog archive page

Then, I switched the blog link in the navigation bar to point to a blog archive page instead of the homepage. I followed the steps in Joshua Lande’s blog under the heading Customizations. I updated the navigation bar in _layouts/default.html to <a href="/blog">Blog</a> and added the new blog archive page at

New url for blog posts

Next, I wanted the posts to appear under the folder /blog, so that this post would be /blog/github-pages-jekyll-cloudflare instead of /github-pages-jekyll-cloudflare. This meant changing the permalink of blog posts to include /blog/ in front of the post’s title. I updated the permalink in _config.yml to permalink: /blog/:title/

Finally, to make it easier for visitors to deep-link into sections of my blog post, I wanted to add little unobtrusive indicators next to headers. Ben Balter has a jQuery solution while Parker Moore has a plain Javascript solution. Personally, I wanted to load less libraries so I went with plain Javascript. I tweaked it further by only highlighting h2 to h4, and using Octicons instead of Font Awesome.

We’re all set!

Using a custom domain and (maybe) Cloudflare

At this point, you should be able to see your site at {your Github username} However, some of you might want to see the blog at a shorter domain. To buy a domain, go to registries such as Namecheap (Non-referral link) or Name. If you’re a student, you’re in luck because you can get a free (!) .me domain for one year in Github’s Student Developer Pack via Namecheap.

After you get the domain, it’s time to consider whether to use Cloudflare. The next steps depend on whether you use Cloudflare.

What is Cloudflare?

Cloudflare is a CDN with many many goodies you can enable. At a basic level, a CDN helps bring your content closer to visitors, so to them the website loads faster! There is much more to that though:

  • content (such as JS and CSS) compression
  • apps such as Google Analytics and A Better Browser
  • offline cache in case of the unlikely event that Github Pages is offine
  • Free SSL

You can look into details what their plans include and decide. For me, the free plan is more than sufficient.

Using Cloudflare

For this part, we’ll assume your Github username is stirlingpoon and your domain is Replace as needed.

First, sign up at Cloudflare and register your domain name with them. At some point, they will ask you to point your nameservers at Cloudflare and you can follow this guide.

Then, when setting DNS, you need to point the domain to Github Pages, like this:

Cloudflare DNS settings for Github Pages

Some of you may be thinking why I am setting a CNAME for the bare domain (@, meaning when Github says we shouldn’t. Github is right of course, but did you notice the blue information icon next to the first CNAME record? Cloudflare is doing CNAME flattening which allows us to set a CNAME when in reality it’s a A record. How Cloudflare pulled this trick off can be found in their blog post.

Now when you go to, you’ll find a Github Pages error page waiting for you. To recify that, go to your repository on Github and add a file CNAME (yes, no file extension). Then follow the guide Adding a CNAME file to your repository. Most people put either or, although I prefer the latter as it’s cleaner.

At this point you should be able to view your blog at We are now going to tweak some settings in Cloudflare!

On the DNS tab, look for the IPv6 Compatibility and set that to On. This will allow people to connect to your site on IPv6, which is increasingly important as IPv4 addresses become scarce. Then, click on the Crypto tab and set SSL to Full. Next switch to the Page Rules tab, and create the rules* and ** and turn on Always use https for both of them. If you want Google Analytics, go to Apps, scroll down the Google Analytics and follow the steps. You can enable other settings as you wish.

If you go to now, you should see automatically. Good? Now comes the fun part. Despite your efforts, attackers can still force visitors to visit the HTTP site by using attacks such as sslstrip. To prevent that, there is one more step - enabling HSTS. Click on Change HSTS Settings, read the warning and say yes, then set:

  • Enable HSTS (Strict-Transport-Security): On
  • Max Age (max-age): 6 months
  • Apply HSTS Policy to subdomains (includeSubDomains): On *
  • No-Sniff Header: On

Note for Apply HSTS Policy to subdomains: I are only hosting my blog on my current site so all subdomains should be on HTTPS. If you have existing subdomains, you should set this to Off first and try to access these subdomains on HTTPS.

What did all this do?

  • Enabled HTTPS and SPDY
  • Redirect HTTP users to HTTPS, so people visiting see
  • HSTS
  • Enabled IPv6
  • (maybe) Google Analytics

Not bad for free, eh? From nothing, you’ve built a blog that needs minimal maintenance other than you having to write content. Congratulations!

Not using Cloudflare

If you don’t want to use Cloudflare, see this guide which uses Namecheap.

What next?

This blog post has been mostly on the how but no the whys. Check out my follow up post for further reading!

Short URL: https://😂.cf/gpjc

Comment on this post...