Managing Structured Content with Jekyll Collections
Learn how to use Jekyll Collections to manage custom content types like staff directories or portfolios, moving beyond the limitations of standard posts and pages.
29 Jul 2025, 02:15 UTC

The Problem: Beyond Posts and Pages
Standard Jekyll sites rely on _posts for chronological content and index.html files for static pages. When you need to manage a directory of team members, a portfolio of projects, or a library of documentation, using _posts forces you to fake dates, and using individual pages leads to repetitive HTML and difficult maintenance.
The solution is Jekyll Collections. Collections allow you to define custom content types that behave like posts (supporting Front Matter and templates) but reside in their own dedicated namespaces. This enables you to treat content as a database that you can loop through, filter, and style consistently across your site.
Defining a Custom Collection
To implement a collection, you must register it in your configuration and create a corresponding directory. For this example, we will create a _staff collection to manage employee profiles.
Step 1: Configuration
Add the collection name to your _config.yml file. You can define it as a simple string or a detailed object to control how the files are rendered.
# _config.yml
collections:
staff:
output: true
permalink: /team/:path/
Key Parameters:
output: true: Tells Jekyll to generate a standalone HTML page for every file in the collection. Set this tofalseif the collection is only meant to provide data for a list page.permalink: Defines the URL structure.:pathacts as a placeholder for the filename.
Step 2: Content Creation
Create a directory named _staff (the underscore is mandatory) in your root folder. Add Markdown files with Front Matter to define specific attributes.
# _staff/jane-doe.md
---
name: "Jane Doe"
role: "Lead Engineer"
email: "[contact removed]"
---
Jane has ten years of experience in distributed systems.
Step 3: Rendering the Collection
Access the collection in your Liquid templates using the site.collections object or the shorthand site.collection_name. Use a loop to generate a directory page.
<ul>
{% for member in site.staff %}
<li>
<a href="{{ member.url }}">{{ member.name }}</a> — {{ member.role }}
</li>
{% endfor %}
</ul>
Comparison: Collections vs. Data Files
It is common to confuse Collections with Data files (_data/). Use the table below to decide which to use:
| Feature | Collections (_staff/) |
Data Files (_data/) |
|---|---|---|
| Individual URLs | Yes (if output: true) | No |
| Front Matter | Supported | Not applicable (YAML/JSON) |
| Content Body | Markdown/HTML supported | Key-value pairs only |
| Use Case | Profiles, Portfolio, Docs | Site settings, Navigation links |
Limitations and Common Pitfalls
Build Performance
Jekyll processes every file in a collection during the site generation phase. If you have thousands of entries in a collection, your build times will increase linearly. For extremely large datasets, consider using a headless CMS or an external API.
Filtering and Querying
Jekyll does not have a database query language. To filter a collection (e.g., showing only "Engineers"), you must use the Liquid where filter or an if statement inside the loop:
{% assign engineers = site.staff | where: "role", "Lead Engineer" %}
{% for eng in engineers %}
{{ eng.name }}
{% endfor %}
The "Missing Page" 404
A frequent error occurs when output is set to false in _config.yml, but the developer attempts to link to {{ member.url }}. In this state, the metadata exists in Liquid, but no physical HTML file is created, resulting in a 404 error upon clicking the link.
Verification and Rollback
To verify the implementation:
- Run
jekyll servefrom your terminal. - Navigate to the permalink defined in your config (e.g.,
/team/jane-doe/). - Check the browser source to ensure the Front Matter variables (like
name) are rendering correctly.
Rollback:
To remove a collection, delete the _collection_name directory and remove the entry from the collections block in _config.yml. Restart the Jekyll server to clear the internal metadata cache.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.