Today I decided to add notes to my website using Jekyll. I thought it would be more convenient to write code snippets in markdown than in HTML and I already use GitHub to serve my website.

Installation

Ruby

# Update package list
sudo apt update

# Install Ruby and development tools
sudo apt install ruby-full build-essential zlib1g-dev

# Add Ruby gems configuration to zsh config file (change .zshrc to .bashrc when using bash)
echo '# Install Ruby Gems to ~/gems' >> ~/.zshrc
echo 'export GEM_HOME="$HOME/gems"' >> ~/.zshrc
echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

# Verify Ruby installation
ruby -v
gem -v

Jekyll

# Now install Jekyll
gem install jekyll bundler

# Create Gemfile (in my root)
echo 'source "https://rubygems.org"
gem "github-pages", group: :jekyll_plugins' > Gemfile

# Install dependencies
bundle install

# Run Jekyll locally
bundle exec jekyll serve

# Visit http://localhost:4000

Quick Jekyll Setup:

# In the website repo
mkdir _posts
mkdir _layouts

# Write posts as:
# _posts/2025-01-15-<title>.md

# Jekyll converts to:
# /2025/01/15/<title>.html

Some Confusions using Jekyll

Jakell is a site generator. It generates _site and what’s inside for me, so make sure that I don’t edit what’s there. It is good to differentiate source files and build output.

What I EDIT (source files):

my-website/
├── _config.yml
├── _layouts/
│   ├── default.html
│   └── post.html
├── _posts/
│   └── 2025-01-15-<title>.md   ← I edit this
├── notes/
│   └── index.html              ← I edit this
|── index.html
├── favicon.ico
└── images/

What Jekyll GENERATES (build output):

my-portfolio/
└── _site/                   ← Jekyll creates this automatically
    ├── notes/
    │   └── index.html       ← Generated from my notes/index.html
    ├── 2025/01/15/
    │   └── functional-programming/
    │       └── index.html   ← Generated from my markdown post
    ├── index.html
    └── ...

So the take away is _site is

  • Auto-generated by Jekyll - never edit files here
  • Deleted and rebuilt every time Jekyll runs
  • This is what gets served locally and deployed to GitHub Pages
  • Should be in .gitignore (don’t commit it to GitHub)

Given this in mind, the workflow should look like

  1. Edit my source files (notes/index.html, _posts/*.md, etc.)
  2. Jekyll builds and puts output in _site/
  3. Browser serves from _site/ locally
  4. GitHub Pages rebuilds _site/ automatically when I push
  5. I only commit source files, not _site/

I still haven’t gotten syntax highlight to work inside code blocks. I will continue tomorrow…

Side note on .gitignore

I added _site to the .gitignore file, but git still tracked files inside _site. It turns out that gitignore does not untrack files. It only prevents tracking new ones. I must have committed _site to the repository at some point and git will continue to track it even after I added it to .gitignore.

How to fix it

  1. Remove _site from tracking
    git rm -r --cached _site
    
    • –cached = remove from Git, not from your filesystem
    • -r = recursive
  2. Commit the change
    git commit -m "stop tracking _site"
    
  3. Verify
    git status