Home Blog Jekyll Collections: The Complete Guide
Tutorial

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.

Jekyll Collections: The Complete Guide

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 document
  • permalink — 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
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.

Share LinkedIn