Moving Beyond Posts: Organizing Structured Content with Jekyll Collections
Stop forcing non-chronological data into _posts. Learn how to use Jekyll Collections to create structured content types like team directories or product catalogs.
25 Oct 2025, 05:10 UTC

The Flat-File Content Wall
Most Jekyll users start with the default _posts directory. It works perfectly for chronological updates, but the system breaks down when you need to manage content that isn't a "post." If you are trying to build a team directory, a product catalog, or a library of documentation, forcing that data into _posts leads to messy date-based filenames and awkward filtering logic in your templates.
The solution is Collections. Collections allow you to define custom content types with their own dedicated directories, metadata schemas, and layouts, treating them as first-class objects in your site's data model rather than just a folder of files.
Defining Custom Content Types
A collection is essentially a named group of documents. To create one, you must register it in your _config.yml file. This tells the Jekyll generator to look for a specific directory (prefixed with an underscore) and process the files inside as part of that collection.
For example, if you are building a site for a consultancy, you might want a _members collection. In your _config.yml, you would add:
collections:
members:
output: true
The output: true setting is critical; it tells Jekyll to generate individual HTML pages for every file in that collection. If set to false, the collection exists only as data that you can loop through on other pages, but the members won't have their own URLs.
Implementing a Member Directory
Once defined, Jekyll expects a directory named _members/ in your root folder. Each file in this folder should contain YAML front matter to define its attributes.
Step 1: Create the Content
Create a file at _members/jane-doe.md:
---
layout: member-profile
name: Jane Doe
role: Senior Architect
expertise: Cloud Infrastructure
---
Jane has over ten years of experience in distributed systems...Step 2: Render the List
To display these members on a "Team" page, use the site.members object (Jekyll automatically creates a shortcut for collections) combined with Liquid filters to organize the data.
<ul>
{% assign sorted_members = site.members | sort: 'name' %}
{% for member in sorted_members %}
<li>
<a href="{{ member.url }}">{{ member.name }}</a> — {{ member.role }}
</li>
{% endfor %}
</ul>Performance Trade-offs and Limitations
While collections are powerful, they are not a replacement for a database. Because Jekyll is a static site generator, every single document in every collection is processed during the build phase.
- Build Time Inflation: As your collections grow into the hundreds or thousands of files, you will notice a significant increase in the time it takes to run
jekyll build. - Liquid Processing Overhead: Performing complex filtering (like using the
wherefilter on multiple large collections) happens at build time. If your logic is too complex, your local development server may lag. - Static Nature: Any change to a member's role or a product's price requires a commit and a full site rebuild.
Verification and Testing
To verify your collection is working correctly, run your site locally using bundle exec jekyll serve. Check for the following:
- URL Accessibility: Navigate to
/members/jane-doe/. If you get a 404, check thatoutput: trueis set in_config.yml. - Data Integrity: Ensure the
site.membersloop is rendering the correct names and roles from the front matter. - Build Logs: Check the terminal output for any YAML parsing errors in your custom collection files.
If you need to remove a collection, delete the entry from _config.yml and delete the corresponding _folder. Since this changes the site structure, you will need to clear your _site directory to ensure no orphaned HTML files remain.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.