Jekyll Build Notes: Layers 1–4
Jekyll From Zero to Production (Minima‑first)
Layers 1–4: Core mechanics → structure → navigation → production hardening
DataInsideData.com build notes (project-ready, workshop-friendly)
Intent: This document captures the exact, repeatable process used to build DataInsideData.com on Minima, with safe overrides and production hygiene, while staying teachable and migration-friendly for a future move to Minimal Mistakes.
Executive summary (what you get by following this)
By the end of Layer 4 you’ll have:
- A clean local dev loop that matches production styling
- Clear information architecture (header nav + footer utilities)
- Safe, minimal theme overrides (footer/head + custom CSS)
- SEO + discovery endpoints:
/sitemap.xml,/feed.xml,/robots.txt - Pagination that scales (and won’t surprise you later)
- A branch/PR workflow that integrates with your private→public deploy pipeline (If you chose to go in that direction.)
Layer 1 — Core Jekyll mechanics
What Jekyll is
Jekyll is a static site generator. It compiles content into static assets:
- HTML
- CSS
- JavaScript
- XML (feed/sitemap)
There is no runtime database or request-time backend. Hosting becomes simple: serve static files.
The local build loop
bundle install # only when Gemfile changes
bundle exec jekyll serve # execute build
What jekyll serve does:
- Builds the site into
_site/ - Starts a local server (typically
http://localhost:4000) - Watches for file changes and rebuilds automatically
Important: changing _config.yml requires a restart. That’s expected.
Front matter (why it exists)
Front matter connects content to structure. Without it, Jekyll may treat a file as a raw asset and skip layout/Liquid processing.
Example listing page:
---
layout: home
title: Posts
permalink: /blog/
---
Layer 2 — Structure, layouts, defaults, and “theme resolution”
Rendering hierarchy (critical concept)
Jekyll resolves files in this order:
- Your repo (site source)
- Theme gem (Minima)
- Fallback behavior
If you create a file in your repo with the same path + filename as a theme file, your version wins automatically.
Why _includes, _layouts, _sass may be “missing”
When using a gem theme, those directories live inside the theme gem. You only create them when you need an override.
This keeps your repo:
- smaller
- cleaner
- upgrade-safe
Defaults in _config.yml (remove repetition)
Use defaults to prevent repeated front matter across many files:
defaults:
- scope:
path: ""
type: posts
values:
layout: post
- scope:
path: ""
type: pages
values:
layout: page
Benefit: less copy/paste, fewer mistakes, easier scaling.
Layer 3 — Pages, home vs blog, navigation
One canonical homepage
Your homepage is defined by index.md / index.markdown at /.
Example:
---
layout: home
title: ""
permalink: /
---
Rule:
One homepage. Avoid creating multiple pages that compete for
/.
Blog index page
Create a dedicated post listing page at /blog/:
---
layout: home
title: Posts
list_title: Recent & relevant
permalink: /blog/
---
Navigation control (Minima)
Header navigation is controlled explicitly with header_pages:
header_pages:
- start-here.markdown
- blog.markdown
- projects/projects.markdown
- about.markdown
- contact/contact.markdown
Notes:
- In Minima, the site title links to
/(so a separate “Home” item is optional). - Keep the header lean and move “utility links” into the footer.
First safe override: footer
First override introduced:
_includes/footer.html
Why footer is a safe first override:
- low coupling
- easy to test visually
- minimal risk during upgrades
Rule of thumb:
Override edges (footer/meta) before the spine (header/layouts).
Layer 4 — Business + production hardening (Minima → future‑proof)
4.0 Goals
Layer 4 makes the site:
- business-friendly (clear nav + legal links)
- production-friendly (SEO, sitemap, robots)
- maintainable (minimal overrides)
- upgrade-friendly (future Minimal Mistakes)
4.1 Information architecture
Header nav (primary actions)
Keep header nav lean:
- Posts
- Projects
- About
- Contact
Footer (utility + legal)
Move these to footer:
- Archive
- Sitemap
- RSS
- Privacy Policy
- Terms of Use
Why:
- archive/sitemap/RSS are secondary
- legal links belong in the footer on most professional sites
4.2 Plugins (SEO + discovery)
Enable:
plugins:
- jekyll-feed
- jekyll-seo-tag
- jekyll-sitemap
What they do:
jekyll-feed→/feed.xmljekyll-seo-tag→ consistent SEO/meta via% seo %jekyll-sitemap→/sitemap.xml
4.3 Excerpts + listing pages
Show excerpts on listing pages:
minima:
show_excerpts: true
Then add per-post front matter excerpts:
excerpt: "One sentence that sells the post."
Rule of thumb (DID style):
- 1 sentence
- clear value
- ~120–180 characters
4.4 Pagination (scales when content grows)
Config:
paginate: 5
paginate_path: "/blog/page:num/"
Pagination typically requires jekyll-paginate.
Gemfile
gem "jekyll-paginate"
_config.ym
plugins:
- jekyll-paginate
4.5 Safe head + custom CSS strategy
Override:
_includes/head.html
and load custom CSS after Minima’s main.css:
<link rel="stylesheet" href="/assets/main.css">
<link rel="stylesheet" href="/assets/css/custom.css">
Custom CSS file:
assets/css/custom.css
Principle:
Don’t fork the theme. Layer over it.
4.6 robots.txt + verifications
Add robots.txt at repo root:
User-agent: *
Allow: /
Sitemap: https://datainsidedata.com/sitemap.xml
Verify locally:
/sitemap.xml/feed.xml/robots.txt
4.7 URL stability: renames + redirects
If you rename a post after it’s been generated or shared, use redirect_from:
redirect_from:
- /blog/2026/01/11/old-slug.html
- /2026/01/11/old-slug.html
Optional: add jekyll-redirect-from for safer refactors:
plugins:
- jekyll-redirect-from
4.8 Standardize permalinks (recommended next)
To make all post URLs consistently live under /blog/, add:
permalink: /blog/:year/:month/:day/:title:output_ext
This reduces accidental 404s and keeps URLs predictable.
Repo “Flex” plan: branch/PR workflow with deploy confidence
What you’re protecting
- Private repo: source of truth (Jekyll source)
- Public repo: compiled output only
- GitHub Actions builds private → pushes into public → Pages serves from
gh-pages
Safe PR workflow
- Create a branch:
feat/*orchore/* - Commit small, logical changes
- Open PR (describe what/why + local test notes)
- Merge to main
- CI builds + deploys automatically
Pre-merge checklist
bundle exec jekyll clean && bundle exec jekyll serve- verify:
/home works/blog/and/blog/page2/(if applicable)/archive//sitemap.xml,/feed.xml,/robots.txt
Diagrams you can paste into draw.io
Diagram A — Build + deploy flow (copy/paste text diagram)
Paste into a draw.io text box and convert into shapes manually:
[Private Repo: datainsidedata-website]
| (PR merge to main)
v
[GitHub Actions: build Jekyll]
|
v
[Build Artifact: _site/]
|
v
[Public Repo: did-site-public (gh-pages branch)]
|
v
[GitHub Pages + CNAME: datainsidedata.com]
Diagram B — Theme override resolution (copy/paste)
Request for: _includes/footer.html
|
v
Check your repo first:
if exists: use YOUR file
else: use THEME file (minima gem)
Diagram C — Mermaid (use as a reference for draw.io)
flowchart LR
A[Private Repo: datainsidedata-website] --> B[GitHub Actions Build]
B --> C[_site/ build artifact]
C --> D[Public Repo: did-site-public (gh-pages)]
D --> E[GitHub Pages + CNAME]
E --> F[datainsidedata.com]
subgraph RES["Theme resolution rule"]
R1[Your repo files] --> R2[Theme gem files] --> R3[Fallback]
end
Reusable project template (for future projects)
Create one file per project under _projects/.
---
layout: page
title: "Project Name"
status: "Active | Paused | Archived"
tags: [architecture, devops, security]
---
## Overview
What this is and why it exists.
## Architecture
Key components and data flow.
## Security + privacy
Threat model, secrets handling, least privilege.
## CI/CD
Branching strategy, automation, deploy pipeline.
## Lessons learned
What broke, what you fixed, what you’d do differently.