Home Blog How to Migrate from WordPress to Jekyll (Complete Guide)
Tutorial

How to Migrate from WordPress to Jekyll (Complete Guide)

Step-by-step guide to migrating your WordPress blog or site to Jekyll — export your content, convert posts, set up redirects, and deploy to GitHub Pages.

How to Migrate from WordPress to Jekyll (Complete Guide)

Moving from WordPress to Jekyll is one of the most common migrations in the static site world — and for good reason. Jekyll sites are faster, cheaper to host, more secure, and far simpler to maintain. This guide walks through every step of the migration.


Why Migrate from WordPress to Jekyll?

WordPress powers 43% of the web, but it comes with real costs:

  • Hosting: WordPress needs a PHP/MySQL server — minimum $5–15/month
  • Maintenance: Core, theme, and plugin updates are constant
  • Security: WordPress is the most targeted CMS on the internet
  • Performance: Even with caching, WordPress is slower than a static site

Jekyll produces plain HTML files that you can host free on GitHub Pages, Netlify, or Cloudflare Pages. There are no databases, no PHP, and nothing to patch.


Before You Start: What You Need

  • Your WordPress admin credentials
  • Basic comfort with the command line
  • Git installed locally
  • Ruby and Jekyll installed (see how to install Jekyll)

Step 1: Export Your WordPress Content

In WordPress Admin, go to Tools → Export.

Select All Content and click Download Export File. You will get an .xml file — this contains all your posts, pages, categories, tags, and metadata.


Step 2: Convert WordPress Export to Jekyll Posts

Use the official Jekyll importer:

gem install jekyll-import hpricot open_uri_redirections

Then run:

ruby -r rubygems -e 'require "jekyll-import";
  JekyllImport::Importers::WordpressDotCom.run({
    "source" => "wordpress-export.xml",
    "no_fetch_images" => false,
    "assets_folder" => "assets/images"
  })'

This creates a _posts/ folder with all your WordPress posts converted to Markdown files, preserving titles, dates, categories, and tags.


Step 3: Review and Clean Up the Imported Posts

The importer does a good job but you will need to review:

Front matter — Posts will have front matter like:

---
layout: post
title: "My Post Title"
date: 2024-03-15 12:00:00 +0000
categories:
  - Tech
tags:
  - jekyll
---

This is correct. You may want to add a description: field for SEO.

Images — If you set no_fetch_images: false, images will be downloaded to assets/images/. Check that the paths in your posts match where the files landed.

HTML vs Markdown — The importer converts to HTML, not Markdown. Posts will still render correctly, but you may want to clean them up for readability. Tools like Pandoc can convert HTML to Markdown:

pandoc -f html -t markdown post.html -o post.md

Shortcodes — WordPress shortcodes like [gallery] or [caption] will not convert automatically. Search your posts for [ and fix them manually.


Step 4: Set Up Your Jekyll Site

Create a new Jekyll site or pick a theme from JekyllHub:

jekyll new my-site
cd my-site

Copy your converted _posts/ folder into the new site:

cp -r /path/to/imported/_posts/* _posts/

Step 5: Migrate Your Categories and Tags

Jekyll handles categories and tags in front matter. If the importer created a _categories/ or _tags/ folder, check that the naming matches your post front matter.

To generate tag and category archive pages, add the jekyll-archives plugin:

# Gemfile
gem "jekyll-archives"
# _config.yml
jekyll-archives:
  enabled:
    - categories
    - tags
  layouts:
    category: archive-taxonomy
    tag: archive-taxonomy

Step 6: Set Up Redirects From Old WordPress URLs

WordPress uses URLs like /2024/03/my-post/ or /?p=123. Jekyll’s default URL structure is /year/month/day/title/. You need redirects so old links and search rankings don’t break.

Option A: Jekyll redirect-from plugin

gem "jekyll-redirect-from"

Add the old URL to each post’s front matter:

redirect_from:
  - /2024/03/15/my-post/
  - /?p=1234

Option B: Netlify redirects

If deploying to Netlify, create a _redirects file:

/2024/03/15/my-post/  /blog/my-post/  301
/?p=1234             /blog/my-post/  301

Option C: Match WordPress URL structure

Set your Jekyll permalink to match WordPress:

# _config.yml
permalink: /:year/:month/:day/:title/

This preserves your old URLs with no redirects needed.


Step 7: Migrate Your WordPress Pages

The importer also creates pages in a _pages/ folder (or at the root level). Review:

  • about.md
  • contact.md
  • Any custom pages

Make sure each has correct front matter and a layout assigned.


Step 8: Handle WordPress Comments

Jekyll does not have a built-in comment system. Your options:

  • Disqus — easiest to migrate (Disqus can import WordPress comment exports)
  • Giscus — uses GitHub Discussions, free and privacy-friendly
  • Utterances — GitHub Issues-based, simple to set up
  • No comments — many blogs that migrate to Jekyll simply drop comments

For Giscus, add to your post layout:

<script src="https://giscus.app/client.js"
  data-repo="username/repo"
  data-repo-id="YOUR_REPO_ID"
  data-category="Comments"
  data-category-id="YOUR_CATEGORY_ID"
  data-mapping="pathname"
  data-theme="light"
  crossorigin="anonymous"
  async>
</script>

Step 9: Migrate Your WordPress Menu

WordPress menus become simple YAML in Jekyll. In _data/navigation.yml:

main:
  - title: "Home"
    url: /
  - title: "Blog"
    url: /blog/
  - title: "About"
    url: /about/
  - title: "Contact"
    url: /contact/

Then in your header template:


{% for item in site.data.navigation.main %}
  <a href="{{ item.url }}">{{ item.title }}</a>
{% endfor %}


Step 10: Deploy to GitHub Pages

  1. Create a new GitHub repository
  2. Push your Jekyll site to the main branch
  3. In the repo Settings → Pages, set Source to GitHub Actions
  4. GitHub will detect your Jekyll site and deploy automatically

Your site is now live at https://username.github.io/repo-name/.

For a custom domain, add a CNAME file to your repo root:

yourdomain.com

Then point your domain’s DNS to GitHub Pages.


After Migration: SEO Checklist

  • Submit new sitemap to Google Search Console: yourdomain.com/sitemap.xml (generated by jekyll-sitemap plugin)
  • Remove WordPress site from Google’s index only after confirming redirects are working
  • Check 301 redirects — verify old URLs redirect to new URLs with a tool like httpstatus.io
  • Update internal links — search posts for your old domain name and update to relative links
  • Add structured data — use jekyll-seo-tag for automatic Open Graph and Twitter Card meta tags

Common Migration Pitfalls

Encoding issues — WordPress content sometimes contains smart quotes and em dashes in Windows-1252 encoding. If you see garbled characters, open affected files and save as UTF-8.

Broken image paths — Double-check all image paths after migration. Use bundle exec jekyll build and check the output for 404s.

Date format — Jekyll requires YYYY-MM-DD dates. WordPress exports use a different format — the importer handles this, but check a few posts to be sure.


Ready to Pick a Jekyll Theme?

One of the best parts of migrating to Jekyll is choosing a clean, modern theme. Browse the collection at JekyllHub — filter by blog, portfolio, or documentation themes with live demos.

Handling media files in the migration

WordPress stores media in a wp-content/uploads/ directory organised by year and month. These files need to move to your Jekyll assets/images/ directory, and the URLs referencing them in your exported content need to be updated to match the new paths.

The cleanest approach is a two-step process: first, download all media files from your WordPress media library (WordPress admin → Media → Library, or via FTP access to your server’s wp-content/uploads/ directory); second, run a find-and-replace across your exported Markdown files to update image URLs from the WordPress format to your Jekyll asset path.

If your WordPress site had many images and you want to continue serving them from the same domain (to avoid breaking image URLs embedded elsewhere on the web), consider setting up a redirect in your new Jekyll host that maps /wp-content/uploads/* to your new assets path. This single redirect rule preserves all image URLs that appear in other websites, social media posts, or email newsletters that referenced your WordPress images.

For large media libraries, evaluate whether all images need to move to your Jekyll repository. Images add to repository size and slow down git clone operations. A practical alternative: keep the original WordPress media files hosted on a separate storage service (Amazon S3, Cloudflare R2, or even your old WordPress host’s media directory) and serve them from there while transitioning your content to Jekyll. Once you have updated internal links to the new asset paths, you can migrate the actual files on your own schedule.

URL structure changes are the highest-risk aspect of a WordPress to Jekyll migration from an SEO perspective. WordPress default URLs often contain date components (/2023/12/10/post-title/) that you may want to remove in Jekyll. Category archive URLs may differ. Custom permalink structures may not translate directly.

Map every significant WordPress URL to its Jekyll equivalent before launching the migrated site. A spreadsheet with old URL and new URL for your top 50 posts (by search traffic) is the minimum. Configure permanent (301) redirects in your Jekyll host’s _redirects file (Netlify and Cloudflare Pages) or netlify.toml/vercel.json for the full mapping. Go live with the redirects in place on day one — every day of 404 errors on previously-ranking URLs costs you rankings.

Submit a change of address in Google Search Console after migration if you are also changing domains (for example, from olddomain.com to newdomain.com). The change of address tool signals to Google that the site has moved and helps transfer ranking signals more quickly than Google would detect organically. If you are keeping the same domain and just changing the CMS, the redirect mapping is sufficient.

Post-migration quality assurance checklist

A systematic quality check before fully redirecting traffic to your Jekyll site prevents discovering problems after launch, when fixing them has SEO and user experience consequences.

Run html-proofer against your built _site/ directory to check all internal links and image references. Any 404 errors or missing images in the output are problems to fix before going live. Check that your sitemap is generated and correctly lists all migrated posts. Verify that RSS feed is present at /feed.xml and contains the correct content. Test the search functionality if your theme includes it.

Load five representative posts in a browser and compare them against the original WordPress versions: check that all images render correctly, all headings are properly formatted, all code blocks are highlighted, and no Markdown conversion artefacts appear in the content (stray asterisks, malformed links, encoding errors in special characters). Fix any issues in the source Markdown files before proceeding.

Test on mobile and check performance in Lighthouse. The migration is an opportunity to start fresh with a well-optimised Jekyll theme — if your new site scores below 85 in Lighthouse performance, investigate the theme choice or image optimisation before redirecting traffic.

Run the migration over a weekend and monitor Google Search Console’s Coverage and Performance reports in the week following launch. A healthy migration shows stable or growing coverage and no significant drop in search impressions. Any unusual coverage errors or impression drops warrant investigation before they compound.

Share LinkedIn