Static Site Generators rundown - How I set up my own blog with Jekyll
Some time ago I decided to move my blogs from Medium to Dev.to, I have detailed the reasons in the below post.
A lot of people suggested in the comments to set up my own blog and cross-post to Dev.to instead of relying only on one platform and I completely agree with them. I was procrastinating setting up my own blog for quite some time now. Finally, I decided to do it and set up my own blog at https://deepu.tech/blogs/ in the process I also updated my personal website to use the same platform.
So when I decided to do this finally I had to choose a blogging platform and there were few requirements I was keen about which influenced my decision.
Requirements
- The platform should support writing posts using Markdown with code syntax highlights
- I love the Dev community and hence wanted to cross-post everything to Dev.to as well without having to make any changes to the post. Means I would author once and publish to both my blog and Dev. This means some constraints/requirements
- It should support customizable front matter so that I can align it with Dev
- It should support the custom liquid tags used by Dev or I should be able to easily add those
- I should be able to have custom pages for my personal website
- Should be open source and have a good stable community
- Should be theme-able, have plugins for SEO, search and so on
- Should be statically generated and reasonably fast
- Should be able to host using GitHub pages - This was an optional requirement
The options rundown
With these in mind, I started evaluating some of the popular options below.
Jekyll
Pros:
- I have experience with Jekyll since I built the new JHipster website using it
- Supports Markdown, Liquid tags and Front Matter
- Supports custom pages, themes, plugins and is statically generated
- Is OSS and has a vibrant community
- Can be hosted on GitHub
Cons:
- I would have to build or find replacements for the custom Liquid tags used by Dev
- I don’t have much experience with Ruby and I’m not very familiar with the Ruby ecosystem
- Not the fastest among the options. Becomes slower as site size increases
Hugo
Pros:
- Is very fast
- I have extensive experience with Go and Go templates which would be helpful
- Supports Markdown and Front Matter
- Supports custom pages, themes and is statically generated
- Is OSS and has a vibrant community
- Can be hosted on GitHub
Cons:
- Doesn’t support Liquid tags
- Doesn’t have plugins. The built-in options are enough for my requirements at the moment though
VuePress
Pros:
- Built with VueJS and I have good experience with JavaScript and quite familiar with Vue
- Supports Markdown and Front Matter
- Supports custom pages, themes, SEO, search and is statically generated
- Is OSS and has a vibrant community
- Can be hosted on GitHub
Cons:
- Doesn’t support Liquid tags
- Doesn’t have plugins. The built-in options are enough for my requirements at the moment though
- Not geared towards blogging, but it’s possible to do it easily with some hacking
Gatsby
Pros:
- Built with React and I have good experience with React
- Supports Markdown and Front Matter
- Supports custom pages, themes, plugins and is statically generated
- Is OSS and has a vibrant community
- Can be hosted on GitHub
Cons:
- Doesn’t support Liquid tags
WordPress
Pros:
- Have used it in the past and is a battle-tested solution
- Supports Markdown using plugins
- Supports custom pages, themes, plugins and can be statically generated using plugins
- Is OSS and has a vibrant community
- Can be hosted on GitHub with some workarounds
Cons:
- Doesn’t support Front Matter and Liquid tags
- Since most of my core requirements can only be achieved using plugins and workarounds it feels too clumsy
Though I personally liked Hugo because of its speed, based on the above the most logical choice for me was Jekyll.
Building a personal website and blog with Jekyll
Getting started
Setting up Jekyll is super easy, I followed the official guide and had a site up and running in minutes. The steps in order were as below
- Install a full Ruby development environment
- Install Jekyll and bundler gems for my user -
gem install jekyll bundler --user-install
- Create a new site -
jekyll new DeepuKSasidharan --skip-bundle
, skipped the bundle install as I want to install to a vendor folder - Cd into the folder
DeepuKSasidharan
and install gems to a vendor folder -bundle install --path vendor/bundle --full-index
- Start server -
bundle exec jekyll serve
and go to http://localhost:4000
Using a Theme
Up next was setting up a custom theme, since I really like the minimal design of Medium, I decided to use Mediumish Jekyll Theme so I did the below steps to switch to this. Steps 3-5 above can be skipped and instead step 2 from the below can be done directly as well.
- Delete the folder
DeepuKSasidharan
we created above - Clone the theme to this folder -
git clone https://github.com/wowthemesnet/mediumish-theme-jekyll.git DeepuKSasidharan
- Cd into the folder
DeepuKSasidharan
and install gems to a vendor folder -bundle install --path vendor/bundle --full-index
- Customize the
_config.yaml
file with my own user details, Google Analytics, Disqus ID and so on- I had to update the
exclude
section to addvendor/
to it and to.gitignore
as well - Updated the
jekyll-paginate
plugin tojekyll-paginate-v2
in theplugins
section - Commented out the
baseurl
section
- I had to update the
- Start server -
bundle exec jekyll serve
and go to http://localhost:4000
Customizations
So now I had a good looking website with an about page and blog up and running. I customized the look and feel a bit and changed the default page from blogs to about. You can check the source code at deepu105/deepu105.github.io
Now the next challenge was to make sure I can author once and post to both my blog and Dev.to, this means I have to make sure the front matter supported by Dev.to also works on my blog and any custom Liquid tags from Dev I use in the blog needs to work on my site as well.
The first part was easy, I just had to customize my sites includes and layouts to use cover_image
instead of image
and use the tag: []
syntax for tags.
I also added support for Dev.to like series and read time with a custom ruby plugin.
Adding custom liquid tags
In order to use Dev.to tags, first I tried if I can reuse them from Dev since its OSS, but it seems like they are heavily coupled with Rails and internal models to be extracted into Gems. I created a ticket hoping this would happen eventually.
So decided to write my own Liquid tags in Ruby. I reused available OSS Liquid tags and customized them to work like the Dev.to ones in syntax and feature. I ended up creating the codesandbox
, twitter
, gist
, link
, speakerdeck
and youtube
tags. You can find them here. Probably will add more as I use them. This is not scalable and I would love to see the Dev.to tags published as Ruby gems.
For example, here is a simple stub for the youtube
tag.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module Jekyll
# A simple stub for the Dev.to youtube tag
class YoutubeTag < Liquid::Tag
def initialize(name, id, tokens)
super
@id = id
end
def render(context)
%(<p>
<div class="embed-video-container">
<iframe width="710" height="399" src="https://www.youtube.com/embed/#{@id}" allowfullscreen></iframe>
</div>
</p>)
end
end
end
Liquid::Template.register_tag('youtube', Jekyll::YoutubeTag)
Publishing to GitHub
Now that I have a site up and running with markdown posts that work in both my blog and Dev.to without having to make any adjustments, I decided to publish this to my Github accounts Github pages.
But there was an issue here. Github doesn’t allow running any custom Ruby code on GitHub pages, so I can’t just push to GitHub and get the site built and published so I decided to write a simple script to do the site generation on my machine from the source branch and push it to the master branch on GitHub.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/bash
rm -rf _site
if [ -z "$(git status --porcelain)" ]; then
echo ">>> Working directory clean"
TMP_LOC=/tmp/deepu.github.io
/bin/rm -rf _site || exit
/bin/rm -rf $TMP_LOC || exit
echo ">> Publish to Dev.to and update slugs"
npm run publish-to-dev || exit
git add --all || exit
git commit --allow-empty -am "Updated posts with Dev.to slug" || exit
echo ">> Building site"
bundle update listen || exit
bundle exec jekyll build || exit
echo ">> Move site to temp folder"
mkdir --parents $TMP_LOC || exit
mv _site/* $TMP_LOC || exit
echo ">> Checkout and clean master"
git checkout master || exit
find -mindepth 1 -depth -print0 | grep -vEzZ '(_drafts(/|$)|node_modules(/|$)|temp(/|$)|vendor(/|$)|\.git(/|$)|/\.gitignore$)' | xargs -0 rm -rvf || exit
echo ">> Move site form temp & publish to GitHub"
mv $TMP_LOC/* . || exit
now=$(date)
git add --all || exit
git commit -am "Updated site on $now" || exit
git push origin master --force || exit
echo ">> $now: Published changes to GitHub"
git checkout site_src
else
echo ">> Working directory is not clean. Commit changes!"
exit
fi
My current workflow
I also wrote a small script to automatically publish or update posts to Dev.to as well using their API. Here is the script.
So now that I have things in place, I author posts as markdown with a full front matter like below and publish on my blog and the script automatically cross-post the same to Dev.to as well.
1
2
3
4
5
6
7
8
---
title: "Static Site Generators rundown - How I set up my own blog with Jekyll"
published: false
description: Static Site Generators comparison
tags: [showdev, ruby, Jekyll, blogging]
cover_image:
canonical_url: https://deepu.tech/setting-up-a-blog-with-jekyll/
---
I’m not using the RSS import option in Dev as it uses the rendered blog and hence might need adjustments. I also set the canonical_url
to my blog site.
When I update a post the same script above takes care of updating it on my site and Dev.to as well so both are always kept in sync.
Future plans
There are some things that can be improved.
- Use the Dev.to API to publish this direct from my publish script when I author a new post or make updates to an existing one. Update: This is done
- Improve the link tag and add some more tags for GitHub. Update: This is partially done
- Use local assets image for my own blog and generate the image URL for Dev.to when publishing.
- Currently, all links point to Dev.to, make the link tag smart enough to point to my blog when published to my site(I don’t want my readers to switch between sites). This might be a bit hard since Dev.to links have a random suffix. Update: This is done
So what do you think? If you have any suggestions on improvements or questions leave a comment.
If you like this article, please leave a like or a comment.
You can follow me on Twitter and LinkedIn.
Cover image credit: Photo by Patrick Fore on Unsplash