How Do You Modularize a Jekyll Theme After Cloning It?
Cloned Your Jekyll Theme? Now It’s Time to Make It Modular
Most Jekyll themes — especially free or starter ones — come with tightly coupled layout files. They're meant to work fast, not scale. Once you've cloned the theme and detached from upstream, it’s the perfect time to restructure everything into reusable modules.
This guide shows you how to break apart your cloned Jekyll theme into flexible, maintainable components.
Why Modularization Matters
- Improves reusability across different layout types (pages, posts, docs)
- Makes maintenance easier: update a header once, apply it everywhere
- Supports multilingual structure and conditional logic
- Prepares the site for dynamic plugin-powered layouts
Step 1: Audit Your Layout Structure
Open the _layouts/ directory. You’ll likely find a small number of files like:
default.htmlpost.htmlpage.html
Inside each, you'll often see big blocks of raw HTML — headers, footers, menus, footnotes, etc. These should be moved to includes.
Step 2: Create Modular Includes
Common Includes to Extract
_includes/head.html— meta tags, SEO, favicon_includes/header.html— logo, nav menu, site title_includes/footer.html— copyright, scripts, closing tags_includes/sidebar.html— optional for blog/doc layouts_includes/post-card.html— reusable snippet for listing posts
How to Use Them
Edit your layout file (e.g. default.html):
{% raw %}
<!DOCTYPE html>
<html lang="en">
<head>
{% include head.html %}
</head>
<body>
{% include header.html %}
<main>
{{ content }}
</main>
{% include footer.html %}
</body>
</html>
{% endraw %}
Step 3: Break Large Sections into Slots
Jekyll supports nested includes and even parameter passing. You can split components into “slots” — reusable templates with flexible content.
Example: Section Include with Parameters
{% raw %}
{% include section.html
title="Why Modular Jekyll Wins"
body="Reusable includes save you hours of duplication." %}
{% endraw %}
And in _includes/section.html:
{% raw %}
<section class="info-block">
<h2>{{ include.title }}</h2>
<p>{{ include.body }}</p>
</section>
{% endraw %}
This makes your templates highly composable — a major upgrade from hardcoded blocks.
Step 4: Restructure Posts, Pages, and Data
Use Custom Collections
Instead of cramming everything into _posts, create logical groups using _collections:
collections:
tutorials:
output: true
docs:
output: true
Use YAML Data Files
Move global config, menus, team bios, or testimonials into _data files:
_data/team.yml
_data/navigation.yml
Then use them with:
{% raw %}
{% for person in site.data.team %}
<p>{{ person.name }} — {{ person.role }}</p>
{% endfor %}
{% endraw %}
Step 5: Add Conditional Logic for Flexibility
Customize how includes behave based on page types or front matter flags:
{% raw %}
{% if page.sidebar %}
{% include sidebar.html %}
{% endif %}
{% endraw %}
This enables layout reuse across blogs, landing pages, and documentation.
Step 6: Modularize CSS and Assets
Move your styles into SCSS partials under _sass/. Then use:
@import "base";
@import "layout";
@import "components/buttons";
This also lets you inject custom styles per layout or section.
Step 7: Maintain a Style Guide or Component Preview Page
It helps to maintain a hidden page with previews of all your components:
_pages/styleguide.html
Use it to test includes like cards, sections, buttons, banners, etc. It’s like having your own mini design system.
Conclusion: Fork, Clone, Then Modularize
Forking is the fast start. Cloning gives you freedom. Modularization is the next step in making your Jekyll site truly scalable.
Whether you’re building a blog, documentation hub, or full marketing site — modular Jekyll themes reduce repetition, improve maintainability, and make it easier for teams to contribute.
Once you've modularized your cloned theme, you're no longer just customizing — you're architecting.