How to Change Your Jekyll Theme (Without Losing Content)
A safe, step-by-step guide to switching Jekyll themes — including how to migrate your posts, preserve your SEO, and avoid common pitfalls when changing themes.
Changing a Jekyll theme is straightforward if you follow the right steps. The key is understanding what belongs to the theme and what belongs to your content — so you can swap one without touching the other.
Before You Start: Back Up Your Site
Always create a git commit (or branch) before changing themes:
git checkout -b backup-before-theme-change
git add .
git commit -m "Backup before switching theme"
git checkout main
This gives you a safe rollback point.
Step 1: Audit Your Current Content
Identify what will need to migrate:
ls _posts/ # Your blog posts — always portable
ls _pages/ # Static pages — usually portable
ls _data/ # Data files — check if theme-specific
ls _includes/ # Custom includes — may need rewriting
ls _layouts/ # Custom layouts — may need rewriting
Your _posts/ content is always safe — Jekyll’s post format is universal. The files most likely to break are custom layouts and includes that reference theme-specific variables.
Step 2: Note Your Front Matter Defaults
Check _config.yml for any theme-specific settings:
# These are Minimal Mistakes specific — won't work in other themes
defaults:
- scope:
path: ""
type: posts
values:
layout: "single" # Theme-specific layout name
author_profile: true # Theme-specific variable
sidebar:
nav: "docs" # Theme-specific sidebar
Write down any settings like these — you will need to find the equivalent in your new theme.
Step 3: Choose Your New Theme
Browse all Jekyll themes and pick one that matches your content type:
- Blog → Chirpy, Minimal Mistakes, Clean Blog
- Portfolio → al-folio, Hydejack
- Documentation → Just the Docs
- Personal → Hyde, Lanyon, Huxpro
Check that the new theme supports the layouts your posts use.
Step 4: Install the New Theme
For gem-based themes
Update Gemfile:
# Remove old theme
# gem "minima"
# Add new theme
gem "jekyll-theme-chirpy"
Update _config.yml:
# Remove old theme
# theme: minima
# Add new theme
theme: jekyll-theme-chirpy
Run:
bundle update
bundle exec jekyll serve
For GitHub-hosted themes
# _config.yml
remote_theme: cotes2020/jekyll-theme-chirpy
Step 5: Fix Broken Layouts
After switching, some posts may show errors like Layout 'single' does not exist. This means your posts use a layout name from the old theme.
Update the layout: field in affected posts, or set a default in _config.yml:
defaults:
- scope:
path: ""
type: posts
values:
layout: "post" # Use the new theme's post layout name
Step 6: Migrate Custom Pages
Static pages in _pages/ may reference old theme layouts. Check each one and update the layout: front matter to match the new theme’s available layouts.
Step 7: Preserve Your SEO
When changing themes, protect your existing SEO signals:
Keep the same URLs. Your post URLs are controlled by permalink in _config.yml, not the theme. Make sure this doesn’t change:
permalink: /:year/:month/:day/:title/
Keep your meta descriptions. Make sure the new theme uses jekyll-seo-tag or equivalent to render your post description fields.
Keep your sitemap. Add jekyll-sitemap to your Gemfile if the new theme doesn’t include it:
gem "jekyll-sitemap"
Step 8: Rebuild and Review
bundle exec jekyll clean
bundle exec jekyll serve --livereload
Check:
- Homepage renders correctly
- All posts are accessible
- Images load properly
- Navigation works
- Mobile layout looks correct
Common Issues When Changing Themes
| Issue | Cause | Fix |
|---|---|---|
| Posts show wrong layout | Old layout name in front matter | Update layout: or set defaults in _config.yml |
| Images broken | Different asset path convention | Check baseurl and image paths |
| Styles look wrong | Old SCSS overrides conflict | Remove or update assets/css/main.scss |
| Navigation missing | Old _data/navigation.yml format |
Check new theme’s navigation format |
References
Understanding what belongs to your theme vs your content
The most important mental model for changing themes without losing content is knowing the boundary between “theme files” and “content files.” This distinction determines what safely moves to a new theme and what needs to be migrated.
Content you own — always portable:
_posts/— your blog posts in Markdown. These work with any theme._pages/— your static pages. These may needlayout:front matter updated but content is portable._data/— data files that contain your site’s data (team members, navigation, FAQs). These are portable though the new theme may use different data file structures.assets/images/— your images. Always portable.
Theme files — replace with new theme’s versions:
_layouts/— page templates. The new theme provides these. Delete any theme-specific layouts unless you have custom ones._includes/— header, footer, navigation. New theme provides these. Delete old ones._sass/— styles. New theme provides these unless you have custom partials to preserve.
The grey area: custom layouts and includes you built yourself (not from the old theme). These need to be migrated or rewritten for the new theme’s conventions.
Handling custom CSS from the old theme
If you have added custom CSS to override or extend your old theme, those overrides may conflict with the new theme’s styles. Three approaches:
Start fresh. Delete assets/css/custom.scss and rebuild your customisations from scratch against the new theme. More work upfront but a cleaner result.
Carry over selectors carefully. Copy your custom CSS but prefix each rule with a check in your browser’s DevTools — does the selector still match elements in the new theme? Class names differ between themes. .post-header in one theme might be .post__header or .entry-header in another.
Use CSS custom property overrides. If the new theme uses CSS custom properties (variables) for colours and spacing, you can override just those variables without touching component-level selectors:
/* assets/css/custom.scss */
:root {
--color-primary: #7c3aed; /* Override brand colour */
--font-size-base: 1.0625rem; /* Override base font size */
}
This is the cleanest approach when the new theme supports it.
Migrating front matter field by field
Different themes use different front matter field names for the same concepts. When switching, map your old fields to the new theme’s expected fields.
Common differences:
| Concept | Minima | Minimal Mistakes | Chirpy |
|---|---|---|---|
| Featured image | image |
header.image |
image |
| Author | author |
author |
author |
| Sidebar | n/a | sidebar.nav |
category auto |
| Comments | n/a | comments: true |
comments: true |
| Layout | post |
single |
post |
If you are switching from Minimal Mistakes (which uses layout: single for posts) to another theme, the most efficient fix is a front matter default:
# _config.yml
defaults:
- scope:
type: posts
values:
layout: post # New theme's post layout name
This applies to all posts without editing individual files. Post-specific front matter that overrides the default still works correctly.
Testing the new theme locally before deploying
Never switch themes directly in production. Test locally first:
# Clean any cached files from the old theme
bundle exec jekyll clean
# Install new theme gem
bundle install
# Start local server
bundle exec jekyll serve --livereload
Work through a systematic review rather than just glancing at the homepage:
Open your most complex post — one with images, code blocks, and tags. Check that all elements render correctly with the new theme. Check a page with a sidebar or special layout. Check mobile at 375px width. Check that pagination works if your blog uses it. Try the search if the new theme includes search.
Keep a list of anything that looks wrong. Most issues are fixable with small CSS overrides or front matter adjustments.
Preserving permalink structure during theme changes
A common mistake when changing themes is accidentally changing your URL structure. If your old _config.yml had:
permalink: /:title/
And the new theme’s example config uses:
permalink: /:year/:month/:day/:title/
Copying the example config verbatim would change all your post URLs. Every inbound link from other sites, social media, and search results would break.
Always keep your permalink setting from your old config, or explicitly map from old URLs to new ones with a _redirects file (Netlify) or .htaccess (Apache).
If you do need to change your permalink structure — perhaps to something more SEO-friendly — set up redirects first, deploy the new structure, and then submit your updated sitemap to Google Search Console to expedite reindexing.
Removing the old theme cleanly
Once the new theme is working, clean up the old theme’s files:
# Remove old gem
bundle remove jekyll-theme-minima
# Remove any theme files you copied to your project
# (layouts, includes, sass files from the old theme)
rm -rf _layouts/minima/
Check your Gemfile and _config.yml for any remaining references to the old theme. Run bundle exec jekyll build to confirm there are no missing layout errors.
When to consider building a custom theme instead
If you find yourself fighting the new theme — overriding half its CSS, patching its layouts, working around its feature set — it may be faster to build a minimal custom theme from scratch. This is especially true if you need a design that no existing theme supports well, or if the existing theme has many features you do not need (which slow your builds and add complexity).
The build a Jekyll theme from scratch guide covers this path in detail. Many experienced Jekyll users settle on a minimal custom base theme and build incrementally rather than adopting a feature-heavy third-party theme and fighting its opinions.
Browse Jekyll themes on JekyllHub to find your next theme — filter by category, features, and visual style to find the best match before committing to a migration.
Switching a Jekyll theme is much less risky than switching a database-driven CMS theme because your content — the Markdown files in _posts/ — is completely decoupled from the theme. The theme controls how content looks; the content itself never changes. With a clean backup, a methodical testing process, and attention to front matter conventions, most theme switches complete in an afternoon.
Dealing with theme gem version pinning
When you install a gem-based theme, Bundler pins the exact version in Gemfile.lock. This means your theme will not auto-update when a new version is released — you have to explicitly run bundle update theme-name to upgrade. This is intentional: automatic updates could break your site.
Check for theme updates periodically with:
bundle outdated
Review the theme’s changelog before upgrading to understand what changed. Major version bumps often require _config.yml changes or updated front matter conventions.
If you want to stay on the latest version without manually running bundle update, pin to a major version with a range in your Gemfile:
gem "minimal-mistakes-jekyll", "~> 4.0"
The ~> 4.0 constraint allows minor and patch updates (4.1, 4.2, 4.x) but not major version changes (5.0). This balances automatic security and bugfix updates against breaking change protection.
Changing a Jekyll theme is an investment of a few hours — far less than switching CMS platforms would be. Your content remains intact throughout, and the result is a site that looks and performs exactly as the new theme promises. Browse JekyllHub’s full theme collection with filters for category, features, and dark mode support to find the right next theme before you start.
Keeping your content portable for future theme changes
The single most important practice for long-term Jekyll flexibility is keeping your content completely decoupled from your theme. This means storing all content-level front matter in your post files (title, description, author, date, tags) and resisting the temptation to use theme-specific front matter fields as structural decisions.
For example, some themes use layout: single while others use layout: post. When you use a theme-specific layout name in your post front matter, you are coupling your content to that theme. Instead, use Jekyll’s front matter defaults in _config.yml to apply the correct layout based on the content type, and keep individual post files layout-agnostic wherever possible.
Similarly, avoid placing theme-specific sidebar or widget configuration inside post front matter. If a theme uses sidebar: true to show a sidebar on individual posts, set that as a default in _config.yml rather than adding it to each post file. When you switch themes, you update one place rather than editing every post.
The payoff: when a better theme appears, or when your site’s visual needs change, the migration is a configuration task rather than a content-editing marathon. Every hour spent keeping content portable is multiplied by the number of posts you have written. Start the habit early, and theme changes will always be an afternoon of work rather than a week-long project.