DEV Community

Cover image for How I built 4 blogs in 15 minutes
Andrew (he/him)
Andrew (he/him)

Posted on

How I built 4 blogs in 15 minutes

Static Site Generators (SSGs) are a quick and easy way to get a simple blog up and running in just a few minutes.

I've been wanting to add some blogging functionality to my homepage, awwsmm.com, for a while now, but I've been dragging my feet because it seems like a lot of work...

  • write blog posts in Markdown
  • write some JavaScript to parse that markdown and render HTML
  • style everything, etc.

Fortunately, SSGs make things much simpler.

After some extensive research (googling "markdown javascript blog"), I discovered Jekyll and SSGs in general, and decided to take a whack at getting a simple blog up and running using a few of the bigger ones.

Here are my initial thoughts.

Next.js

Next.js is a JavaScript framework built on top of React, a JavaScript library for building user interfaces. Next.js can be used for building simple static sites as well as single-page applications (SPAs).

I followed this guide from the JetBrains team (who make IntelliJ and PyCharm) and was able to get the example app running in essentially a single command (after updating npm)

$ npx create-next-app nextjs-mdx-blog
Enter fullscreen mode Exit fullscreen mode

Here is the result

Next.js blog template screenshot

...okay, it's not too exciting, but it works!

Next.js had, in my opinion, the simplest and most straightforward setup of any of these four SSGs.

Gatsby

Gatsby is another React-based SSG which also integrates GraphQL and Netlify as a CMS. If any of that is confusing to you, don't worry about it, because that's all I'll say about it for now.

Gatsby claims to be able to give you super fast build times, but this is probably a non-issue for your static blog with a few dozen posts.

I followed Gatsby's own tutorial for getting a simple site set up] and was able to get this beauty up and running in just a few minutes

Gatsby blog template screenshot

The only major difference here was that I had to first install the Gatsby CLI via npm. Certainly not a show-stopper, but it was an extra step relative to the Next.js setup.

Hugo

Hugo is different from the previous two SSGs in that it's not React-based, but written in Go. Like Gatsby, Hugo plays nicely with Netlify and also claims to be "the fastest tool of its kind", able to build pages in < 1 ms.

Hugo also have a how-to guide on their website which was easy to follow and resulted in the following little blog in only a few commands

Hugo blog template screenshot

Hugo also requires installing a command-line tool (this time, via brew on macOS rather than via npm), and additionally requires you to select a theme (it doesn't provide a default one). That tiny extra step gave me some errors because my brain is fried by the Internet and I literally cannot read two sentences ahead

$ hugo server -D
Start building sites …
hugo v0.90.0+extended darwin/amd64 BuildDate=unknown
WARN 2021/12/10 17:00:11 found no layout file for "HTML" for kind "section": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/12/10 17:00:11 found no layout file for "HTML" for kind "home": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/12/10 17:00:11 found no layout file for "HTML" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/12/10 17:00:11 found no layout file for "HTML" for kind "page": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
...
Enter fullscreen mode Exit fullscreen mode

After I read those instructions, though, everything worked as expected.

Jekyll

Finally, we get to Jekyll, which started this whole adventure. Jekyll is a Ruby-based SSG and is the engine behind GitHub pages.

I had high hopes for Jekyll and started following their step-by-step tutorial here at the same time I was looking at the other SSGs above, in parallel. But Jekyll was the only SSG I had to google an error message for when getting started, and it took about 10 minutes longer than the others to get up and running (mostly because of Ruby).

If you want to use Jekyll, the first command you'll be given is a Ruby gem command

$ gem install jekyll bundler
Enter fullscreen mode Exit fullscreen mode

Before you do that, though, make sure you're using Ruby 2 and not Ruby 3

$ ruby -v # bad
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-darwin20]
Enter fullscreen mode Exit fullscreen mode
$ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin20]
Enter fullscreen mode Exit fullscreen mode

Why? Jekyll chokes on Ruby 3 with a cryptic error message

$ bundle exec jekyll serve
Configuration file: none
            Source: /Users/andrew/Git/SSGs/jekyll
       Destination: /Users/andrew/Git/SSGs/jekyll/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
                    done in 0.041 seconds.
 Auto-regeneration: enabled for '/Users/andrew/Git/SSGs/jekyll'
                    ------------------------------------------------
      Jekyll 4.2.1   Please append `--trace` to the `serve` command
                     for any additional information or backtrace.
                    ------------------------------------------------
/usr/local/lib/ruby/gems/3.0.0/gems/jekyll-4.2.1/lib/jekyll/commands/serve/servlet.rb:3:in `require': cannot load such file -- webrick (LoadError)
    from /usr/local/lib/ruby/gems/3.0.0/gems/jekyll-4.2.1/lib/jekyll/commands/serve/servlet.rb:3:in `<top (required)>'
    from /usr/local/lib/ruby/gems/3.0.0/gems/jekyll-4.2.1/lib/jekyll/commands/serve.rb:179:in `require_relative'
    from /usr/local/lib/ruby/gems/3.0.0/gems/jekyll-4.2.1/lib/jekyll/commands/serve.rb:179:in `setup'
...
Enter fullscreen mode Exit fullscreen mode

But suppose we're on the correct version of Ruby. Here's what I experienced next

$ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin20]

$ bundle exec jekyll serve
Traceback (most recent call last):
    2: from /usr/bin/bundle:23:in `<main>'
    1: from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (2.2.33) required by your /Users/andrew/Git/SSGs/jekyll/Gemfile.lock. (Gem::GemNotFoundException)
To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:2.2.33`
Enter fullscreen mode Exit fullscreen mode

Okay, it looks like we need to update the bundler, whatever that is

$ bundle update --bundler
You must use Bundler 2 or greater with this lockfile.
Enter fullscreen mode Exit fullscreen mode

Okay? Maybe it's missing?

$ gem install bundler:2.2.33
Fetching bundler-2.2.33.gem
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory.
Enter fullscreen mode Exit fullscreen mode

Guh, yeah, sudo, fine

$ sudo gem install bundler:2.2.33
Password:
Fetching bundler-2.2.33.gem
Successfully installed bundler-2.2.33
Parsing documentation for bundler-2.2.33
Installing ri documentation for bundler-2.2.33
Done installing documentation for bundler after 4 seconds
1 gem installed
Enter fullscreen mode Exit fullscreen mode

Now can I update?

$ bundle update --bundler
Fetching gem metadata from https://rubygems.org/.........
Using bundler 2.2.33
Following files may not be writable, so sudo is needed:
  /Library/Ruby/Gems/2.6.0
  /Library/Ruby/Gems/2.6.0/build_info
  /Library/Ruby/Gems/2.6.0/cache
  /Library/Ruby/Gems/2.6.0/doc
  /Library/Ruby/Gems/2.6.0/extensions
  /Library/Ruby/Gems/2.6.0/gems
  /Library/Ruby/Gems/2.6.0/specifications
Fetching public_suffix 4.0.6
Fetching colorator 1.1.0
Fetching concurrent-ruby 1.1.9
Fetching eventmachine 1.2.7


Your user account isn't allowed to install to the system RubyGems.
  You can cancel this installation and run:

      bundle config set --local path 'vendor/bundle'
      bundle install

  to install the gems into ./vendor/bundle/, or you can enter your password
  and install the bundled gems to RubyGems using sudo.

  Password:
Installing colorator 1.1.0
Installing public_suffix 4.0.6
Installing eventmachine 1.2.7 with native extensions
Installing concurrent-ruby 1.1.9
Fetching http_parser.rb 0.8.0
Installing http_parser.rb 0.8.0 with native extensions
Fetching ffi 1.15.4
Installing ffi 1.15.4 with native extensions
Fetching forwardable-extended 2.6.0
Installing forwardable-extended 2.6.0
Fetching rb-fsevent 0.11.0
Installing rb-fsevent 0.11.0
Fetching rexml 3.2.5
Installing rexml 3.2.5
Fetching liquid 4.0.3
Installing liquid 4.0.3
Fetching mercenary 0.4.0
Installing mercenary 0.4.0
Fetching rouge 3.26.1
Installing rouge 3.26.1
Fetching safe_yaml 1.0.5
Installing safe_yaml 1.0.5
Fetching unicode-display_width 1.8.0
Installing unicode-display_width 1.8.0
Fetching addressable 2.8.0
Installing addressable 2.8.0
Fetching i18n 1.8.11
Installing i18n 1.8.11
Fetching pathutil 0.16.2
Installing pathutil 0.16.2
Fetching kramdown 2.3.1
Installing kramdown 2.3.1
Fetching terminal-table 2.0.0
Installing terminal-table 2.0.0
Fetching kramdown-parser-gfm 1.1.0
Installing kramdown-parser-gfm 1.1.0
Fetching sassc 2.4.0
Fetching rb-inotify 0.10.1
Installing rb-inotify 0.10.1
Installing sassc 2.4.0 with native extensions
Fetching listen 3.7.0
Installing listen 3.7.0
Fetching jekyll-watch 2.2.1
Installing jekyll-watch 2.2.1
Fetching em-websocket 0.5.3
Installing em-websocket 0.5.3
Fetching jekyll-sass-converter 2.1.0
Installing jekyll-sass-converter 2.1.0
Fetching jekyll 4.2.1
Installing jekyll 4.2.1
Bundle updated!
Enter fullscreen mode Exit fullscreen mode

Ten minutes later, I can finally start my Jekyll site

$ bundle exec jekyll serve
Configuration file: none
            Source: /Users/andrew/Git/SSGs/jekyll
       Destination: /Users/andrew/Git/SSGs/jekyll/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
                    done in 0.029 seconds.
 Auto-regeneration: enabled for '/Users/andrew/Git/SSGs/jekyll'
    Server address: http://127.0.0.1:4000
  Server running... press ctrl-c to stop.
Enter fullscreen mode Exit fullscreen mode

And here it is

Jekyll blog template screenshot

"Sad trumpet noise" doesn't really do this justice.

Oh, and also

[2021-12-10 17:10:39] ERROR `/favicon.ico' not found.
Enter fullscreen mode Exit fullscreen mode

Cool.

Conclusion

In about 15 minutes*, I was able to go from knowing absolutely nothing about these four static site generators to having four different "blogs" running on my local machine.

Of course, there's much more work to be done in incorporating one of these into my site (I'm leaning toward Hugo or Next.js at the moment) -- and actually, you know, writing blog posts -- but those are for another day.

* 2/3s of which was due to Jekyll alone


Note to the Jekyll team: make this process a bit less bumpy for newbies.

Top comments (17)

Collapse
 
rrampage profile image
Raunak Ramakrishnan • Edited

I use rvm or rbenv to run multiple ruby versions. Both of them also do not need any sudo permissions.

Hugo is great in terms of installation and dependency management. It eliminates the need for gem or npm or any other package manager. Also, it is very fast at generating HTML from markdown and there are many great minimalist themes to get started.

If you are exploring SSGs, also have a look at Zola which is written in Rust. I have heard a lot of good things about it.

I have been working (somewhat sporadically) on my home-grown site generator using Pandoc and some shell scripts mostly for exporting my notes from Obsidian to HTML preserving internal references and diagrams. One of these days, I will finally get around to writing about it 😛

Collapse
 
awwsmm profile image
Andrew (he/him)

Nice! Looking forward to the writeup!

I'll have a look at Zola, as I'm not entirely sold on any of these SSGs I've explored so far. Also taking a deeper dive into Netlify.

Do you work with JVM languages much? SDKMAN! is a fantastic version manager for those, and I've played around with pyenv before and it's much better than that. It's a world of difference. I'll check out rbenv for sure.

Thanks!

Collapse
 
rrampage profile image
Raunak Ramakrishnan

Has been a while since I used JVM languages. I mostly keep to the LTS version of OpenJDK and keep JDK 8 for some of the older libraries.

A colleague of mine who is into polyglot development recommended asdf when dealing with Node + Python + Ruby versions.

Collapse
 
phantomhaze profile image
Alex Hernandez

Nice to know Ruby has an environment management tool like nvm! Storing this for later

Collapse
 
sfiquet profile image
Sylvie Fiquet

I’m looking into Eleventy at the moment. I love Next.js and I heard only good things about Gatsby, but I’m not convinced that my blog needs the overhead of React hydration. I also don’t want to invest into learning Go or Ruby just to tweak my site. Eleventy seems to do what Jekyll does but with JavaScript, I’m definitely interested.

Can’t try it right now as my computer died, just going through the docs…

Collapse
 
pontakornth profile image
Pontakorn Paesaeng

Eleventy is really good. My digital garden uses it. It's a nice tool for static blog that need low or even no JavaScript on the website at all. Eleventy supports plugins such as lazy load image, syntax highlighting, optimization and more. The downside is it lacks complex assets transform so you can't use advance tools such as WindiCSS.

Collapse
 
shrihankp profile image
Shrihan • Edited


[2021-12-10 17:10:39] ERROR `/favicon.ico' not found.

This is intended behaviour. /favicon.ico is a file that, among other things, is used to display a custom site icon on the tab (the small circular one). Jekyll isn't related to this, it's just how regular web servers work.

Collapse
 
awwsmm profile image
Andrew (he/him)

Right, but it's not even mentioned in the tutorial. They should provide a default favicon for the step-by-step tutorial so beginners don't have to worry about what this error might mean.

Collapse
 
shrihankp profile image
Shrihan

Fair point.

Collapse
 
imagineeeinc profile image
Imagineee

I am looking to make a blog soon and link it with dev.to, and I always use vanilla js. express server, ejs templating and a ton of custom css. Also if you are looking for a cms to store your content, id recommend to intergrate with notion and use their js sdk to get the blogs + its free

Collapse
 
zakwillis profile image
zakwillis

You did this all in 15 minutes?

Collapse
 
awwsmm profile image
Andrew (he/him)

Yep! And I had never touched any of these SSGs (or even really knew what an SSG was) before today. It honestly took longer to write this post than it did to get those four pages up and running.

Collapse
 
zakwillis profile image
zakwillis

Nice.

Collapse
 
triptych profile image
Andrew Wooldridge

You should check out Astro - it's new but already pretty great.

Collapse
 
tsolan profile image
Eugene

Rails could generate entire blog scaffold for you with basic crud functionality...

Collapse
 
awwsmm profile image
Andrew (he/him)

Yeah but it's a bit overkill for a static personal blog

Collapse
 
truong65650627 profile image
TRUONG

Very good