Jekyll Collections: The Complete Guide
Learn how Jekyll collections work — create custom content types, configure output, use front matter defaults, and build filtered collection pages.
Collections are one of Jekyll’s most powerful features — and one of the most underused. They let you create custom content types beyond posts and pages: products, team members, themes, recipes, portfolio items, or anything you need. This guide covers everything.
What Are Collections?
Jekyll has three built-in content types: posts, pages, and data. Collections let you create your own.
A collection is a folder of Markdown files (prefixed with _) that Jekyll processes as a group. Each file in the collection becomes a document with its own URL and template.
Examples of what people build with collections:
_themes/— a theme marketplace (like this site)_products/— an e-commerce catalogue_team/— staff or contributor profiles_courses/— educational content modules_recipes/— a cookbook
Creating a Collection
Step 1: Declare the Collection in _config.yml
# _config.yml
collections:
projects:
output: true
permalink: /projects/:name/
output: true— generates a dedicated page for each documentpermalink— controls the URL structure
Step 2: Create the Collection Folder
Create a folder named with an underscore prefix: _projects/
Step 3: Add Documents
Create Markdown files in _projects/:
<!-- _projects/my-app.md -->
---
title: "My App"
description: "A mobile app for tracking habits."
year: 2026
status: "live"
url: "https://myapp.com"
image: /assets/images/projects/my-app.jpg
---
My App is a cross-platform habit tracker built with React Native...
Each file gets a URL based on your permalink setting: /projects/my-app/
Collection Configuration Options
collections:
projects:
output: true # Generate a page for each document
permalink: /projects/:name/ # URL pattern
sort_by: year # Default sort field
order: # Explicit ordering (optional)
- my-featured-project.md
- another-project.md
Permalink Variables
| Variable | Value |
|---|---|
:name |
Filename without extension |
:title |
title from front matter (falls back to :name) |
:path |
Path relative to collection folder |
:output_ext |
Output file extension (.html) |
:categories |
Front matter categories joined by / |
Front Matter Defaults for Collections
Avoid repeating common front matter in every document using defaults:
# _config.yml
defaults:
- scope:
path: ""
type: "projects"
values:
layout: "project"
author: "Your Name"
published: true
Now every document in _projects/ automatically gets layout: project and author: Your Name without you writing it in each file.
Accessing Collections in Templates
List All Documents in a Collection
{% for project in site.projects %}
<article>
<a href="{{ project.url }}">{{ project.title }}</a>
<p>{{ project.description }}</p>
</article>
{% endfor %}
Sort and Filter
<!-- Sort by year, newest first -->
{% assign sorted_projects = site.projects | sort: "year" | reverse %}
{% for project in sorted_projects %}
...
{% endfor %}
<!-- Filter by status -->
{% assign live_projects = site.projects | where: "status", "live" %}
{% for project in live_projects %}
...
{% endfor %}
<!-- Filter by multiple values -->
{% assign featured = site.projects | where_exp: "item", "item.featured == true" %}
Group by a Field
{% assign by_year = site.projects | group_by: "year" %}
{% for group in by_year %}
<h2>{{ group.name }}</h2>
{% for project in group.items %}
<p>{{ project.title }}</p>
{% endfor %}
{% endfor %}
Building a Collection Index Page
Create projects.md (or _pages/projects.md) with a layout that lists all projects:
---
layout: collection-index
title: Projects
permalink: /projects/
---
In _layouts/collection-index.html:
---
layout: default
---
<h1>{{ page.title }}</h1>
<div class="projects-grid">
{% assign projects = site.projects | sort: "year" | reverse %}
{% for project in projects %}
{% include project-card.html project=project %}
{% endfor %}
</div>
{{ content }}
Collection Document Templates
Create _layouts/project.html for individual project pages:
---
layout: default
---
<article class="project">
<header>
<h1>{{ page.title }}</h1>
{% if page.description %}
<p class="lead">{{ page.description }}</p>
{% endif %}
{% if page.url %}
<a href="{{ page.url }}" class="btn" target="_blank">Visit Project →</a>
{% endif %}
</header>
{% if page.image %}
<img src="{{ page.image }}" alt="{{ page.title }}" class="project-image">
{% endif %}
<div class="project-content">
{{ content }}
</div>
<footer class="project-meta">
<span>Year: {{ page.year }}</span>
<span>Status: {{ page.status }}</span>
</footer>
</article>
Collections Without Output Pages
Sometimes you want a collection just for data — not individual pages. Set output: false:
collections:
team:
output: false
Now site.team gives you access to all team members in your templates, but no individual URLs are generated. Great for team pages, testimonials, and similar content.
<!-- In your about page template -->
<div class="team-grid">
{% for member in site.team %}
<div class="team-card">
<img src="{{ member.avatar }}" alt="{{ member.name }}">
<h3>{{ member.name }}</h3>
<p>{{ member.role }}</p>
</div>
{% endfor %}
</div>
Collections vs Posts vs Data Files
| Feature | Posts | Collections | Data Files |
|---|---|---|---|
| Chronological ordering | Built-in | Manual | N/A |
| Individual pages | Yes | Optional | No |
| Liquid access | site.posts |
site.collection_name |
site.data.filename |
| Front matter | Yes | Yes | No (YAML/JSON/CSV) |
| Drafts | Yes | No | No |
| Best for | Blog posts | Custom content types | Configuration, simple lists |
Real-World Example: A Team Directory
# _config.yml
collections:
team:
output: false
defaults:
- scope:
type: "team"
values:
layout: "team-member"
<!-- _team/sarah-jones.md -->
---
name: Sarah Jones
role: Lead Developer
avatar: /assets/images/team/sarah.jpg
github: sarahjones
twitter: sarahjones
---
Sarah has 10 years of experience building Jekyll themes and static sites.
<!-- In _pages/about.md -->
{% for member in site.team %}
<div class="team-card">
<img src="{{ member.avatar }}" alt="{{ member.name }}">
<h3>{{ member.name }}</h3>
<p class="role">{{ member.role }}</p>
{{ member.content }}
{% if member.github %}
<a href="https://github.com/{{ member.github }}">GitHub</a>
{% endif %}
</div>
{% endfor %}
Collections are the building block behind theme directories (like this one), product catalogues, and any site that needs to manage structured content at scale.
Explore Jekyll themes on JekyllHub — our entire theme collection is built on Jekyll collections.