Jekyll site setup
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
PATHvariable 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 updatebefore 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.zversions in Gemfile tox.yin 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 %}
'