Beyond the Blog: Organizing Custom Content with Jekyll Collections
Stop forcing everything into the /_posts folder. Learn how to use Jekyll Collections to create custom content types for portfolios, docs, and more with tailored permalinks.
24 Oct 2025, 10:41 UTC

The Problem with the /_posts Folder
Most Jekyll users start with the default /_posts directory. It works perfectly for chronological content, but it fails the moment you need a different organizational logic. If you are building a portfolio of projects, a directory of team members, or a set of product documentation, forcing that content into a blog format leads to messy categories and awkward URLs.
The solution is Collections. Instead of treating every piece of content as a "post," Collections allow you to define custom content types with their own directories, permalink structures, and metadata logic.
Defining Your Custom Content Type
A Collection is essentially a designated folder that Jekyll treats as a group of documents rather than static pages. To create one, you must first register it in your _config.yml file. This tells Jekyll to look for a specific folder (prefixed with an underscore) and process the files inside it as part of a named group.
Configuration Example
To create a "projects" collection, add the following to your _config.yml:
collections:
projects:
output: true
permalink: /portfolio/:title
The output: true setting is critical; without it, Jekyll will process the files for use in loops (like a list of projects), but it won't generate individual HTML pages for each project. The permalink setting ensures your URLs look like /portfolio/my-cool-app instead of the default /projects/my-cool-app.html.
Structuring and Accessing Collection Data
Once configured, create a folder named /_projects in your root directory. Any Markdown file placed here becomes part of the projects collection. You can use Front Matter to add specific metadata that wouldn't make sense in a standard blog post, such as tech_stack or completion_date.
Example Project File (/_projects/alpha-app.md)
---
layout: project
title: "Alpha App"
tech_stack: ["Ruby", "React"]
completion_date: 2023-05-12
---
This project focused on optimizing API latency...
To display these items on a page, you use the site.collections object in Liquid. This allows you to iterate through the custom group separately from your blog posts.
Generating a Project Gallery
Run this Liquid loop in any HTML file (like index.html) to list your projects:
<ul>
{% for project in site.projects %}
<li>
<a href="{{ project.url }}">{{ project.title }}</a>
— {{ project.tech_stack | join: ", " }}
</li>
{% endfor %}
</ul>
The Build-Time Trade-off
Because Jekyll is a static site generator, Collections are processed entirely at build time. This introduces a specific limitation: there are no dynamic queries. If you want to filter your projects by a specific technology (e.g., only showing "React" projects), you must do this using Liquid if statements inside your loop.
Additionally, be mindful of scale. Since Jekyll regenerates the site based on these files, a collection with hundreds of entries combined with complex Liquid filters can noticeably increase your build times. If your content grows to thousands of entries, a static collection may become a bottleneck during deployment.
Verification and Testing
To verify your collection is working correctly:
- Run
bundle exec jekyll servefrom your terminal. - Navigate to the permalink defined in your config (e.g.,
localhost:4000/portfolio/alpha-app). - Check the browser console or page source to ensure the Liquid loop rendered the expected number of items.
Rollback: If the site fails to build or URLs are incorrect, remove the collection entry from _config.yml and delete the /_collection-name folder to return to the default state.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.