Beyond Posts: Organizing Structured Data with Jekyll Collections
Stop forcing everything into _posts. Learn how to use Jekyll Collections to create structured, custom content types like project portfolios or staff directories.
19 May 2026, 01:04 UTC

The Problem with Flat Content Structures
Most Jekyll sites start with a simple split: _posts for chronological updates and index.md for static pages. However, as a site grows, you often encounter content that doesn't fit either mold. A portfolio of projects, a directory of team members, or a library of technical documentation doesn't belong in a blog feed, but it still requires a consistent layout and metadata.
The solution is Jekyll Collections. Instead of hacking together nested folders or relying on complex data files, Collections allow you to define custom content types that behave like posts—complete with Front Matter and individual URLs—but remain logically separated from your blog.
Defining Your Custom Content Type
To implement a collection, you must first register it in your _config.yml file. This tells Jekyll to look for a specific directory and treat its contents as a structured group.
# _config.yml
collections:
projects:
output: true
The output: true setting is a critical decision point. When set to true, Jekyll generates a standalone HTML page for every file in the collection. When set to false, the collection acts as a hidden data source, accessible only via Liquid templates on other pages.
Structuring the Filesystem
Once registered, create a directory at the root of your project starting with an underscore that matches your collection name. For example, if your collection is named projects, create a folder named _projects/.
Inside this folder, create Markdown files with Front Matter. This allows you to attach specific attributes to each item, such as a project's technology stack or a team member's job title:
---
layout: project
title: "Cloud Migration Tool"
tech_stack: ["Ruby", "AWS"]
completion_date: 2023-05-12
---
This project focused on automating the migration of legacy databases...Retrieving and Filtering Collection Data
Collections are exposed to your Liquid templates through the site.collections object. You can iterate through them using a for loop, and use Liquid filters to sort or filter the content based on the Front Matter you defined.
Example: A Filtered Project Gallery
To display only projects that use "Ruby," you can use the where filter. Run this code within any HTML file in your site:
<ul>
{% assign ruby_projects = site.projects | where: "tech_stack", "Ruby" %}
{% for project in ruby_projects %}
<li>
<a href="{{ project.url }}">{{ project.title }}</a>
</li>
{% endfor %}
</ul>Expected Result: Jekyll will scan the _projects folder, identify files where the tech_stack array contains "Ruby," and generate a list of links to those specific pages.
Performance and Architectural Trade-offs
While Collections provide powerful organization, they introduce specific overhead:
- Build Time: Because Jekyll processes every file in a collection during the build phase, very large collections (hundreds of files) can significantly slow down site generation.
- Lack of Relations: Collections are flat. If you need to link a "Project" to a specific "Team Member," you must do this manually by adding a unique ID in the Front Matter of both files and matching them via a Liquid loop.
- Refactoring Cost: Renaming a collection is a destructive change. You must rename the directory, update
_config.yml, and find-and-replace every Liquid reference tosite.collection_nameacross your entire project.
Verifying Your Implementation
To ensure your collection is working correctly, follow these checks:
- Check the Build: Run
bundle exec jekyll serve. If you see errors regarding missing layouts, ensure you created a layout file in_layouts/that matches thelayout:key in your collection's Front Matter. - Inspect the URL: If
output: trueis set, navigate to/projects/your-file-name/to confirm the page is being rendered. - Debug the Object: Use
{{ site.projects | size }}in a template to verify that Jekyll is detecting the correct number of files in your directory.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.