Jekyll site setup

Setup a Jekyll static site generator with the Minima theme for blog posts.

Jekyll installation

See Jekyll installation instructions for other Linux.

# install ruby with dependencies
sudo dnf install --setopt install_weak_deps=0 \
  ruby ruby-devel openssl-devel redhat-rpm-config gcc-c++ @development-tools \
  libffi-devel libyaml-devel
  # NOTE: these ruby packages install gems into `/usr/share/gems`

# configure gem to install binaries into a proper user folder
echo 'gem: --no-document --bindir ~/.local/share/gem/ruby/bin' > ~/.gemrc
# add gem bin path to PATH
export PATH="$(gem env user_gemhome)/bin:${PATH}"

# install jekyll and bundler
gem --version
gem install jekyll bundler

Persist the updated PATH variable for gem binaries in ~/.bashrc.

cat >> ~/.bashrc <<'
if command -v gem &>/dev/null
then
  GEM_HOME="$(gem env user_gemhome)"
  if ! [[ "$PATH" =~ "${GEM_HOME}/bin" ]]
  then
    PATH="${GEM_HOME}/bin:${PATH}"
  fi
fi
export PATH
'

Configure Jekyll site

Generate a site.

  • Do not run bundle install/bundle update before configuring project local gem location to ./vendor/bundle.
  • By default a new Jekyll site uses Minima v2 theme gem, which we change to Minima v3 using the “remote theme” plugin.
  • Replace all fixed gem x.y.z versions in Gemfile to x.y in order to get latest versions.
jekyll new . --skip-bundle
  # _config.yml
  # _posts/
  # index.markdown
  # about.markdown
  # 404.html
  # Gemfile
  # .gitignore

# configure bundler to install gems into project folder
bundle config set --local path 'vendor/bundle'

Clear the Gemfile in order to install latest gem versions. Manually remove directives related to Windows and JRuby.

# remove packages with fixed versions added by default
bundle remove --skip-install minima
bundle remove --skip-install jekyll-feed
bundle remove --skip-install jekyll

bundle add --skip-install jekyll

bundle add --skip-install \
  --group jekyll_plugins \
  jekyll-remote-theme \
  jekyll-feed \
  jekyll-seo-tag \
  jekyll-minifier

Remove all patch versions in the Gemfile. It should look like this:

source "https://rubygems.org"

gem "jekyll", "~> 4.4"

gem "jekyll-remote-theme", "~> 0.4", group: :jekyll_plugins
gem "jekyll-feed", "~> 0.17", group: :jekyll_plugins
gem "jekyll-seo-tag", "~> 2.8", group: :jekyll_plugins
gem "jekyll-minifier", "~> 0.2", group: :jekyll_plugins
# remove Gemfile.lock in order to update to latest gem package versions
rm Gemfile.lock
# update gem versions
bundle update --all
bundle install
# clean up unused gems
bundle clean  # project local
gem clean     # user installed gems

Edit _config.yml to configure the site. The variables in _config.yml will be accessible in the templates via {{ site.myvariable }} (e.g. {{ site.author.name }}).

# _config.yml
title: My Jekyll site
author:
  name: linjan2
  email:
description: >-
  Site description that will appear in document head meta and in feed.xml
  site description.
url: https://linda-jansson.com
baseurl: "" # the subpath of your site, e.g. /blog, if served from subpath

# Replace "theme: minima" with remote_theme
remote_theme: jekyll/minima@bf9ef98 # static ref for Minima v3
  # See docs at: https://github.com/jekyll/minima/tree/master

plugins:
  - jekyll-remote-theme
  - jekyll-feed
  - jekyll-minifier
  - jekyll-seo-tag

# Exclude files from processing (in addition to the default jekyll excludes)
exclude:
  - tmp

minima:
  skin: auto

jekyll-minifier:
  exclude: []
# test by serving on http://localhost:4000
bundle exec jekyll serve

# build the generated website into _site/
export JEKYLL_ENV=production # required to activate things like jekyll-minifier
bundle exec jekyll build

Commit the site files to Git repository.

echo 'tmp/' >> .gitignore
echo '.bundle/' >> .gitignore
git init . && git add . && git commit 'initial commit'

Add more custom site files

A Jekyll theme utilizes a folder structure to define the posts, layouts, and includes. Make custom additions by adding files to local project folder. Files in local project folder override those pre-defined in the theme.

./
├── assets/
│   ├── about.svg
│   ├── css/
│   │   └── custom.css
│   ├── index.svg
│   └── jekyll-example/
│       ├── index.js
│       └── style.css
├── _config.yml
├── _drafts/
├── favicon.ico
├── Gemfile
├── Gemfile.lock
├── _includes/
│   ├── custom-head.html
│   └── sub-footer.html
├── index.md
├── pages/
│   ├── 404.md
│   ├── about.md
│   └── categories.md
└── _posts/
    ├── 2026-04-08-jekyll-example-html-post.html
    └── 2026-04-06-jekyll-example-post.md

Update the _config.yml to add more configurations.

# ...

minima:
  # ...
  nav_pages: # Update the navigation pane with specific site pages
    - pages/categories.md
    - pages/about.md
  date_format: "%b %-d, %Y"
  social_links:
    - title: GitHub
      icon: github
      url: https://github.com/linjan2

disqus:
  shortname: linda-jansson-com

# set defaults for front matter variables
defaults:
  # for all files
  - scope:
      path: '' # matches all
    values:
      author: Linda Jansson
  # for all files under _posts/
  - scope:
      path: _posts
      type: posts
    values:
      layout: post
      permalink: /:title/
  # for all files under _pages/
  - scope:
      path: pages
    values:
      layout: page
      comments: false # don't display disqus

Create a custom “404 Not found” page.

<!-- pages/404.md -->
---
layout: page
title: 404 - Page Not Found
permalink: /404.html
---

Sorry, we couldn't find the page you're looking for.

[← Back to Home](/)

Create an “about” page. The liquid templating language is used to insert a SVG file fron static_files variables, which holds all “static” site files that don’t have a front matter.

<!-- pages/about.md -->
---
layout: page
title: About
permalink: /about/
---


{% assign file = site.static_files | where: "name", "about.svg" | first %}
<img
  src="{{ file.path }}"
  title="Flower image"
  alt="Image of a pink flower"
  height="100px"
  style="display: block; margin-left: auto; margin-right: 0;"
/>

Create a page to display all post categories with links.

<!-- pages/categories.md -->
---
layout: page
permalink: /categories/
title: Categories
---


<div id="archives">
{% assign sorted_categories = site.categories | sort %}
{% for category in sorted_categories %}
  <div class="archive-group">
    {% capture category_name %}{{ category | first }}{% endcapture %}
    <div id="{{ category_name | slugize }}"></div>
    <h3 class="category-head">{{ category_name }}</h3>
    <a name="{{ category_name | slugize }}"></a>
    {% for post in site.categories[category_name] %}
    <article class="archive-item">
      <h4><a href="{{ site.baseurl }}{{ post.url }}">{{ post.title }}</a></h4>
    </article>
    {% endfor %}
  </div>
{% endfor %}
</div>

Override the Minima theme’s custom head _includes/custom-head.html to include CSS assets (one common custom.css and then a loop to include from a variable named css that can be set in a file’s front matter).

<!-- _includes/custom-head.html -->

<link rel="stylesheet" href="/assets/css/custom.css">
{%- for css in page.css -%}
  <link rel="stylesheet" href="{{ css | relative_url }}">
{%- endfor -%}

Override the Minima theme’s custom sub-footer (i.e. before end of body closing tag) _includes/sub-footer.html to include JavaScript assets (from variable set in front matter).

<!-- _includes/sub-footer.html -->

{%- for js in page.js -%}
  <script src="{{ js | relative_url }}"></script>
{%- endfor -%}

Create posts

Jekyll posts must be named YEAR-MONTH-DAY-title.MARKUP. Create the post files under _posts/. Drafts can be created under _drafts.

Create a markdown post:

cat > "_posts/$(date +%F)-jekyll-example-post.md" <<<'---
title: Jekyll example post
categories: cheatsheet
---

# Jekyll example post

This is an example post.
'

Create an HTML post that avoids template interpretation. Add variables js and css in front matter to make the head and sub-footer in _includes/ insert them as CSS/JS includes.

cat > "_posts/$(date +%F)-jekyll-example-html-post.html" <<<'---
title: Jekyll example HTML post
js:
  - https://unpkg.com/[email protected]/dist/petite-vue.iife.js
  - /assets/jekyll-example/index.js
css:
  - /assets/jekyll-example/style.css
categories: example
---

<!-- avoid excerpt separator \n\n -->

{% raw %}

<h1>Jekyll example HTML post</h1>

{% endraw %}
'