Jekyll _config.yml: The Complete Configuration Guide
Everything you need to know about Jekyll's _config.yml — global settings, build options, plugins, collections, front matter defaults, and real-world examples.
_config.yml is the single most important file in a Jekyll project. It controls everything: your site’s URL, which plugins run, how collections are defined, what files are excluded from builds, and any custom data you want available across every template. Understanding it thoroughly is essential for anyone building or customising a Jekyll site.
File location and format
_config.yml lives at the root of your Jekyll project:
my-jekyll-site/
├── _config.yml ← here
├── _posts/
├── _layouts/
├── _includes/
└── index.html
It uses YAML format — indented key-value pairs. Two spaces per indent level, no tabs.
Important: Jekyll reads _config.yml only at startup. If you change it while running jekyll serve, you must restart the server to see the changes take effect. Content changes in posts and pages hot-reload automatically; config changes do not.
Essential site settings
# Site identity
title: "JekyllHub"
description: "A marketplace for premium and free Jekyll themes."
# URLs — critical to get right
url: "https://jekyllhub.com" # your production domain with scheme
baseurl: "" # subdirectory, if any (e.g. "/blog")
# Contact
email: hello@jekyllhub.com
url vs baseurl
This distinction trips up many Jekyll users.
url is your site’s root domain: https://jekyllhub.com. It is used to construct absolute URLs (for RSS feeds, sitemaps, canonical tags).
baseurl is a subdirectory path if your site does not live at the root of the domain. For a site at https://username.github.io/my-project/, set baseurl: "/my-project". For a site at the root, leave it empty: baseurl: "".
In templates, always use the relative_url or absolute_url filters instead of hardcoding paths — they automatically prepend baseurl:
<a href="/about/">About</a>
<link rel="canonical" href="https://jekyllhub.com/tutorial/2026/06/22/jekyll-config-yml-guide/">
Build settings
# Build
source: . # where Jekyll reads files (default: current dir)
destination: _site # where Jekyll writes output (default: _site)
# Markdown
markdown: kramdown
highlighter: rouge # syntax highlighting engine
# Kramdown options
kramdown:
input: GFM # GitHub Flavoured Markdown
hard_wrap: false
syntax_highlighter: rouge
syntax_highlighter_opts:
block:
line_numbers: true
# Liquid
liquid:
error_mode: warn # warn | strict | lax
strict_filters: false
strict_variables: false
Plugins
List all plugins in the plugins key:
plugins:
- jekyll-feed # generates /feed.xml RSS feed
- jekyll-seo-tag # adds meta tags, OG tags, JSON-LD
- jekyll-sitemap # generates /sitemap.xml
- jekyll-paginate-v2 # pagination for posts
- jekyll-redirect-from # add redirects via front matter
- jekyll-archives # generates category and tag archive pages
Plugins must also be in your Gemfile:
group :jekyll_plugins do
gem "jekyll-feed"
gem "jekyll-seo-tag"
gem "jekyll-sitemap"
gem "jekyll-paginate-v2"
end
GitHub Pages note: GitHub Pages only supports a specific list of whitelisted plugins. If deploying to GitHub Pages, check the whitelist. For full plugin support, use Cloudflare Pages, Netlify, or Vercel with a build step.
Collections
Collections let you create custom content types beyond posts and pages:
collections:
themes:
output: true # generate individual pages for each item
permalink: /themes/:name/ # URL pattern
authors:
output: true
permalink: /authors/:name/
showcase:
output: false # data only, no individual pages
With this configuration, files in _themes/ generate pages at /themes/minimal-mistakes/, etc. Files in _showcase/ are available as site.showcase but do not generate pages.
Front matter defaults
Avoid repeating the same front matter on every post with defaults:
defaults:
# All posts get layout: post and author: Marcus Webb
- scope:
path: ""
type: posts
values:
layout: post
author: Marcus Webb
toc: true
featured: false
comments: true
# All pages get layout: page
- scope:
path: ""
type: pages
values:
layout: page
# Theme collection items get layout: theme
- scope:
path: ""
type: themes
values:
layout: theme
# Files in a specific directory
- scope:
path: "guides"
values:
layout: guide
sidebar: true
# A specific file
- scope:
path: "index.html"
values:
layout: home
Specificity rules: more specific scopes override less specific ones. A file-level front matter value always wins over any default.
Excluding and including files
By default, Jekyll excludes dotfiles, Gemfile, Gemfile.lock, node_modules, and a few others. Customise with:
# Exclude from build output
exclude:
- .sass-cache/
- .jekyll-cache/
- Gemfile
- Gemfile.lock
- node_modules/
- vendor/
- "*.sh"
- README.md
- package.json
- package-lock.json
- tools/
- CHANGELOG.md
# Include files that would otherwise be excluded
include:
- _redirects # Netlify/Cloudflare redirects file
- _headers # Cloudflare/Netlify headers file
- .htaccess # Apache config (dotfile, excluded by default)
Pagination
Using jekyll-paginate-v2:
pagination:
enabled: true
per_page: 12
permalink: "/page/:num/"
title: ":title - Page :num"
sort_field: "date"
sort_reverse: true
# Enable autopages for categories and tags
autopages:
enabled: true
categories:
enabled: true
permalink: "/category/:cat/"
layouts:
- "category.html"
tags:
enabled: false
SEO and analytics settings
Using jekyll-seo-tag:
# Used by jekyll-seo-tag
title: "JekyllHub"
tagline: "Find Your Perfect Jekyll Theme"
description: "Browse free and premium Jekyll themes for blogs, portfolios, and business sites."
url: "https://jekyllhub.com"
logo: /assets/images/logo.png
author:
name: Marcus Webb
email: marcus@jekyllhub.com
twitter: marcuswebb
twitter:
username: jekyllhub
card: summary_large_image
social:
name: JekyllHub
links:
- https://twitter.com/jekyllhub
- https://github.com/jekyllhub
# Analytics (custom keys — not built-in Jekyll)
google_analytics: "G-XXXXXXXXXX"
plausible_domain: "jekyllhub.com"
# Newsletter (custom)
sendy_url: "https://sendpress.org/s/subscribe"
sendy_list_id: "YOUR_LIST_ID"
Jekyll Feed settings
feed:
posts_limit: 20
excerpt_only: false
collections:
- posts
Sass/SCSS settings
sass:
sass_dir: _sass # where .scss partials live
style: compressed # compressed | expanded | nested | compact
load_paths:
- _sass
- node_modules # if using npm packages
Custom data available in all templates
Any key in _config.yml is available as site.keyname throughout all templates. Use this to store site-wide settings:
# Custom site settings
nav_links:
- title: Browse Themes
url: /themes/
- title: Blog
url: /blog/
- title: Showcase
url: /showcase/
social_links:
github: https://github.com/jekyllhub
twitter: https://twitter.com/jekyllhub
support_email: support@jekyllhub.com
theme_submission_url: /submit/
Access in templates:
{% for link in site.nav_links %}
<a href="{{ link.url }}">{{ link.title }}</a>
{% endfor %}
<a href="{{ site.social_links.github }}">GitHub</a>
Environment-specific configuration
Use multiple config files for different environments:
# _config.yml (base, committed to repo)
title: "JekyllHub"
url: "https://jekyllhub.com"
google_analytics: ""
# _config.development.yml (local overrides, not committed)
url: "http://localhost:4000"
google_analytics: ""
Run Jekyll with multiple configs — later files override earlier ones:
# Development
bundle exec jekyll serve --config _config.yml,_config.development.yml
# Production
JEKYLL_ENV=production bundle exec jekyll build
Serving options
Settings for jekyll serve:
# Local server
port: 4000
host: "127.0.0.1"
livereload: true # auto-refresh browser on changes
open_url: true # open browser automatically
# Show drafts during development
show_drafts: false # set to true or use --drafts flag
future: false # show posts with future dates
unpublished: false # show unpublished posts
Timezone
timezone: "Europe/London" # IANA timezone name
This affects how page.date is interpreted and how dates are formatted. Set it to your local timezone to avoid date-off-by-one issues.
Permalink structure
# For posts
permalink: /:categories/:year/:month/:day/:title/
# Common permalink styles:
permalink: pretty # /year/month/day/title/
permalink: date # /year/month/day/title.html
permalink: ordinal # /year/ordinal/title.html
permalink: weekdate # /year/week/short_day/title/
permalink: none # /title.html
A common setup for blogs:
permalink: /blog/:title/
This gives clean, category-free URLs like /blog/jekyll-front-matter-guide/.
Full example _config.yml
# ─── Site Identity ───────────────────────────────────────────────────────
title: "JekyllHub"
tagline: "Find Your Perfect Jekyll Theme"
description: "A marketplace for premium and free Jekyll themes — for blogs, portfolios, documentation, and business sites."
url: "https://jekyllhub.com"
baseurl: ""
email: hello@jekyllhub.com
author: "Marcus Webb"
logo: /assets/images/logo.png
# ─── Build ───────────────────────────────────────────────────────────────
timezone: "Europe/London"
markdown: kramdown
highlighter: rouge
permalink: /blog/:title/
kramdown:
input: GFM
syntax_highlighter: rouge
# ─── Plugins ─────────────────────────────────────────────────────────────
plugins:
- jekyll-feed
- jekyll-seo-tag
- jekyll-sitemap
- jekyll-paginate-v2
- jekyll-redirect-from
# ─── Collections ─────────────────────────────────────────────────────────
collections:
themes:
output: true
permalink: /themes/:name/
authors:
output: true
permalink: /authors/:name/
# ─── Defaults ────────────────────────────────────────────────────────────
defaults:
- scope:
path: ""
type: posts
values:
layout: post
toc: true
featured: false
- scope:
path: ""
type: pages
values:
layout: page
- scope:
path: ""
type: themes
values:
layout: theme
- scope:
path: ""
type: authors
values:
layout: author
# ─── Pagination ──────────────────────────────────────────────────────────
pagination:
enabled: true
per_page: 12
permalink: "/page/:num/"
sort_field: date
sort_reverse: true
# ─── Analytics ───────────────────────────────────────────────────────────
google_analytics: "G-XXXXXXXXXX"
# ─── Newsletter ──────────────────────────────────────────────────────────
sendy_url: "https://sendpress.org/s/subscribe"
sendy_list_id: ""
sendy_waitlist_id: ""
# ─── Exclude ─────────────────────────────────────────────────────────────
exclude:
- Gemfile
- Gemfile.lock
- node_modules/
- vendor/
- tools/
- package.json
- README.md
include:
- _redirects
- _headers
The _config.yml file is the control panel of your Jekyll site. Mastering it means being able to change almost any aspect of how Jekyll builds and serves your content without touching a single template file.