Notice: I've migrated my blog off WordPress and into Jekyll a few years ago, but I never wrote much about it. Many of the choices I took would be different if I was going to do the same thing nowadays (mainly which frameworks I would choose).
This is going to be a series on how I migrated my personal website off Wordpress and what you need to do if you want to embark in the same journey.
I had been thinking about doing it for almost 5 years before actually going through with it. I had always been scared of totally breaking the website by migrating it off something well estabilished as WordPress and that I'd been using for years at that point to something less "mainstream". My process looked something like this: I would write each post in markdown in Byword (both on iOS and Mac OSX), convert it to HTML and paste it manually into the WordPress textbox. Doing all of this each time felt a bit too much friction. It wasn't broke, but it surely could have been improved.
Early on I decided that I would want to go for a static site. The content of the site would not change much and it surely wasn't dynamic. I could easily rebuild all the static pages when I published an article.
Static Website using Markdown - What are the options?
Since I've been interested in doing this for years, I've read about and tried locally many markdown static website generators.
This is a comprehensive list of everything I've tried:
- Jekyll - The standard that started the whole movement of static markdown websites.
- Octopress - Opinionated customization of Jekyll built for blogging.
- Second Crack - A hobby project of a developer I follow. It works well, but it should not be used for production use since it doesn't really have a community behind it.
- Hugo - Really fast builds, but lacks plugins and extensibility.
- Ghost - Great look out of the box, needs a VPS.
- Gatsby - Based on React. Great if you're already using React on other project or if you'd like to learn it.
- Gitbook - Super simple to set up and use, but limited in extensibility and customization. Great for documentation, books, and tutorials.
I'm sure I missed many of them, but I feel like these ones are the most used and/or famous. Of all of these, I particularly liked Gatsby, Jekyll, and Ghost.
A few of these solutions (Ghost and Second Crack for example) need either a VPS to build the website or a manual deployment process where you built the website yourself and deploy the generated website to your server.
Nowadays you can use Netlify to automatically run a "cloud function" after each deploy to generate your website and deploy it so it's less of a hassle, but it still not straightforward to setup. I've tried Netlify with both Jekyll and Gatsby and it works well.
Why I chose Jekyll
In the end, I chose Jekyll over Gatsby and Ghost for multiple reasons:
It's the framework with wider adoption, a history of consistent updates over a decade (it was launched in 2008) and most activity on Github. It might be that in the future newer frameworks will overtake it and if that's the case it might be worth migrating, but for now Jekyll is still the king.
2. Automatic integration with Github
Github Pages runs on Jekyll with almost no setup. I could simply host my website there and have all the goodies of Github included for free. Otherwise would have been forced to use two different services instead of one: Github to host the code and Netlify to host the site. I tend to avoid that whenever possible.
It being old might be seen as a negative point of some people, and in some cases of bloated and old software it is, but I don't think this is the case. The framework is very much alive and used by most static websites, not to forget that just the fact of Github officially supporting it means a lot more people using it and more people contributing code and fixes. I know it is unlikely that any of the other 2 frameworks I was considering (Ghost and Gatsby) are going to shut down any time soon since they're both widely used.
What would be a blog without content? Practically worthless.
During this restructuring I also realized that I didn't like the fact of having 2 separate websites, with their relative blogs, when it could be just the one.
Disclaimer: I used to have one website for my personal blog where I wrote everything that came to mind and one website for my work where I wrote everything about my development gigs
I've thought for a very long time about it when I was deciding if it was worth having two different blogs with their topics clearly separated and I thought it was worth it. Google still penalizes websites that have different kind of content, but their content was not different enough for that to take effect and I'm not in the business of SEO anyway (at least not excessively). I still think I had a solid point at the time, but now I feel like a simple `/patchnotes` page for each of my apps is enough and if I really need to say anything more, I can just write it on my normal blog which will now cover both areas: me, my hobbies, my business and whatever I feel like it's worth sharing. About including the business area to my personal blog, that's a part of me, of what I'm doing and what I am, I'm not trying to sell you anything, I'm just writing about what I'm doing. I'll always strive to find the balance in writing without feeling like I'm pressuring my readership into buying my products or that I'm only talking about them. I think a balance can be found and that I proved in the past years that I have found it. I know that this is a difficult area to tackle, I've unsubscribed to great blogs just because they were self-promoting way too much, even though I still enjoyed the content, only because I couldn't stand all the spam I was forced to read, so I'm definitely aware of that and I will try my best to avoid doing it.
Jekyll is the most widely used Static Site Generator. It is written in ruby and it generates static pages from your files in markdown. You can fully control the styling and plugins of your website, for example, I added a script to show the number of words in an article and another one to show an estimate of the reading time.
I love this part of Jekyll's README:
Put simply, Jekyll gets out of your way and allows you to concentrate on what truly matters: your content.
Truth be told, most static generators are like that. Customizable if needed, but they don't force you to, you can simply choose one of the multiple themes and get started.
To start we will install a local development environment on your Mac so that you can test your website design and content without actually publishing it. The neat thing is that once the website is ready you can use it to preview new articles before syncing the changes to the server to have a real view on its look.
This article will focus on Mac OSX since it's the OS that I'm using. If you need to install Jekyll on a different OS the official website has a guide on how to install it on each OS.
Install RVM and Ruby
Before trying to install any dev tools on a Mac it is a good idea to install the Xcode command line helper from Apple. Open Terminal.app and run "sudo xcode-select --install". It will ask for your Mac's password and install the developer tools.
The version of Ruby that comes installed with OSX is really outdated and it shouldn't be used — ever.
Open Terminal.app again and install RVM (a version manager for Ruby that lets you install and switch between different versions of Ruby with ease), and the latest version of Ruby:
"\curl -sSL https://get.rvm.io | bash -s stable --ruby"
After that is good practice to update your gems (the ruby 'libraries' you have installed), run:
After all of that is done it is time to install Jekyll itself.
Open terminal again and run:
"gem install jekyll"
Additionally, install "bundler", we'll need it later:
"gem install bundler"
During the installation it might happen that nokogiri fails to install. If it fails, try installing it without the native extensions. Before trying to install jekyll again run:
"gem install nokogiri -- --use-system-libraries --with-xml2-include=/usr/include/libxml2 --with-xml2-lib=/usr/lib"
If it fails again try following this thread for troubleshooting steps.
Setting up your GitHub pages repository
Login into Github and create a new public repository [Unless you plan on forking a theme], choose a name, ignoring the `Need inspiration? How about verbose-octo-waffle.` proposed by Github. I'm sure you can come up with a better name yourself.
Before doing anything else you need to think about which url you want to use:
Decide if your website is going to be at `http://USERNAME.github.io/` of at `http://USERNAME.github.io/REPOSITORY_NAME`. For now, I plan to have my website at `http://valeIT.github.io/` of course if you plan to redirect to it from your main website URL it is not really relevant. In my case http://www.valentinourbano.com will bring you there so it's not really important where it is located.
Usually, the `http://USERNAME.github.io/REPONAME` is used for singular projects while the `http://USERNAME.github.io/` is used for personal sites not related to a specific project.
Please note that this Article is mainly based on forking the mediator theme so that's the easiest way to follow the guide if you're new to Jekyll.
If you forked a theme go here to set up your theme. Otherwise continue with setting up a new repository:
If you have a new repository running `jekyll new` will automatically generate a base template for you to get started[^3]. Note that this will create a basic site (best suited for blogs), if you have different needs you should use a [theme](#forked-a-theme) For now leave everything as it is and [skip](#testing-the-website) the next section.
- Open Terminal.app app and run `jekyll new`.
- Open your browser of choice to http://localhost:8000
Forked a theme
If you've forked a theme instead, you should follow the theme's installation instructions. For example, using the mediator theme the process is as follows:
- Clone it to your local machine: `git clone https://github.com/USERNAME/mediator`
- Open Terminal.app and navigate (`cd`) to the folder: `cd mediator`
- From the Terminal run `bundle install`
- Run `jekyll serve` to generate your website
- Open your browser of choice to http://localhost:8000
Mediator is a medium-like theme and it's the theme that I'm currently using for my personal website. If that's not the theme for you, a good source is Jekyll Themes.
Jekyll File Structure
The structure of your new website is not super complicated. Everything that starts with an underscore "_" is your source that will generate the website. Once generated the site will live in the "_site" folder.
This file stores the configuration of your website like the URL, the name, setup defaults and so on.
This folder includes files used to get data that will be accessible from anywhere else on the site. For example you could have a .yaml file with a list of your projects for a portfolio or a list of links.
The folder to store the drafts of your articles that will not be published on the web until the get moved to the _posts folder.
Files here can be included from anywhere else on the website so you usually put here your headers and footers, but also utilities.
Here are stored templates for your pages. You could have one template for your blog posts and another template for your pages.
It includes all your published blog posts. Keep in mind that the filename should follow this convenction: YEAR-MONTH-DAY-title.extension
It includes all of your css that will be compacted into one output file during the build.
Once built your site will be generated inside this folder.
- other folders
Any other folder will be copied to your website, so you could have a folder called "folder1" that point to mysite.com/folder1 and so on.
Setting up your machine for SSH access to Github
If you've already set up your machine for SSH access, or you're used to do it, freely skip this section
First you will need to make sure that `openssl` is installed. If not you can install it using homebrew: `brew install openssl`.
Generate a key
Open up your terminal and generate the key by running (taking care of adding your email instead of the example one):
`ssh-keygen -t rsa -b 4096 -C "[email protected]"`
You can leave the default filename or choose a custom one, if you don't have a need for a custom name you should leave the default one.
Choose a strong password to protect your key and save it in your password manager.
Add the key to the SSH agent
- Start the ssh-agent if it's not already running by typing `eval "$(ssh-agent -s)"` in your Terminal
- Edit `~/.ssh/config` (for example by running `nano ~/.ssh/config`) and set up the SSH agent to automatically load keys on startup on top of allowing it to save passwords to the keychain so you don't have to type it every time:
- Finally add the key to the agent by running `ssh-add -K ~/.ssh/id_rsa`