How to Migrate from WordPress to Jekyll Without Losing SEO
Migrate your WordPress site to Jekyll while preserving rankings — keep URLs intact, set up 301 redirects, transfer authority, and resubmit your sitemap correctly.
Migrating from WordPress to Jekyll can destroy your search rankings if done carelessly — or preserve them completely if done right. The difference is almost entirely about URLs and redirects. This guide focuses specifically on the SEO side of migration.
Why Migrations Hurt Rankings (And How to Avoid It)
When you migrate a site, Google typically sees:
- Broken URLs — old pages return 404, Google drops them from the index
- Changed URLs without redirects — link equity built up over years evaporates
- Missing content signals — metadata, structured data, and canonicals vanish
- Crawl errors — Google Search Console fills with errors, trust drops
All of these are avoidable with the right preparation.
Step 1: Audit Your Current Rankings Before You Touch Anything
Before migrating, document what you have to protect.
Export your current rankings:
- Open Google Search Console
- Go to Performance → Search results
- Export the full report (all queries, all pages)
- Save it — this is your baseline
Identify your top pages: Sort by impressions or clicks. The top 20 pages drive the majority of your traffic. These are the pages that absolutely must have working redirects.
Check your backlinks: Use Ahrefs, Moz, or the free Google Search Console Links report to export pages with inbound links. Any URL with external links pointing to it must either be preserved or redirected.
Step 2: Decide on a URL Strategy
This is the single most important SEO decision in your migration.
Option A: Match Your WordPress URL Structure (Safest)
WordPress defaults to /YYYY/MM/DD/post-title/. Set your Jekyll permalink to match:
# _config.yml
permalink: /:year/:month/:day/:title/
With matching URLs, you need zero redirects. Google sees no change. This is the safest option if your WordPress URLs are already clean.
Option B: Improve Your URL Structure (Riskier but Better Long-Term)
WordPress date-based URLs are not ideal for SEO — they signal post age and add unnecessary path segments. Cleaner URLs like /blog/post-title/ perform better.
# _config.yml
permalink: /blog/:title/
If you change URL structure: every old URL must have a 301 redirect to the new one. Skipping this step will cause ranking drops.
Option C: Keep WordPress Slugs, Drop the Date
permalink: /:title/
This is a good middle ground — shorter URLs than WordPress default, but slugs are unchanged so most existing links still work.
Step 3: Set Up 301 Redirects
301 redirects tell Google: “this content has permanently moved to a new URL.” They pass ~90-99% of link equity to the new destination.
Method A: jekyll-redirect-from Plugin
Add old URLs to each post’s front matter:
---
title: "My Post Title"
redirect_from:
- /2024/03/15/my-post-title/
- /2024/03/my-post-title/
- /?p=1234
---
Jekyll generates redirect pages at those URLs that immediately redirect to the current post URL.
Limitation: jekyll-redirect-from creates HTML redirect pages, not true HTTP 301 redirects. Google handles these well, but HTTP 301s via your hosting platform are more reliable.
Method B: Netlify Redirects (Recommended)
Create _redirects in your site root:
/2024/03/15/my-post-title/ /blog/my-post-title/ 301
/2024/03/20/another-post/ /blog/another-post/ 301
/?p=1234 /blog/my-post-title/ 301
/?p=5678 /blog/another-post/ 301
Netlify processes these as real HTTP 301s — the gold standard.
Method C: Cloudflare Pages Redirects
Create _redirects (same format as Netlify) or use _headers for more complex rules. Cloudflare processes these as HTTP 301s at the CDN level.
Method D: Match URLs Exactly (No Redirects Needed)
As mentioned in Step 2, the cleanest approach is matching your Jekyll permalink structure to WordPress. Then there are no redirects to manage.
Step 4: Preserve Your Metadata
WordPress stores titles, descriptions, and OG images in plugins like Yoast SEO or Rank Math. You need to transfer this to Jekyll front matter.
Export Yoast data: Many Jekyll importers pull Yoast SEO data automatically. Check your imported posts for:
---
title: "Exact title from Yoast"
description: "Exact meta description from Yoast"
image: /assets/images/og-image.jpg
---
If the importer didn’t pull this data, open your WordPress admin, go to each top post, and manually copy the Yoast title and description into the post’s front matter.
Install jekyll-seo-tag:
gem "jekyll-seo-tag"
Add {% seo %} to your <head>. This auto-generates all SEO tags from your front matter.
Step 5: Handle WordPress-Specific URL Patterns
WordPress generates several URL types that need attention:
Category URLs: WordPress creates /category/tech/, Jekyll creates /tech/ by default. Set up redirects or configure Jekyll to match:
# jekyll-archives config
permalinks:
category: /category/:name/
Tag URLs: Same issue — match WordPress’s /tag/name/ pattern:
permalinks:
tag: /tag/:name/
Author archives: WordPress creates /author/username/. Unless you replicate this, set up redirects to the homepage or about page.
Feed URL: WordPress feeds live at /feed/ or /?feed=rss2. Jekyll’s jekyll-feed plugin creates /feed.xml. Set up a redirect:
/feed/ /feed.xml 301
/feed.xml /feed.xml 200
Page URLs: WordPress pages often have trailing slashes (/about/). Make sure your Jekyll pages have matching permalinks:
---
permalink: /about/
---
Step 6: Migrate Your Sitemap
Before going live, have your new sitemap ready to submit.
Install jekyll-sitemap:
gem "jekyll-sitemap"
Your sitemap auto-generates at /sitemap.xml.
After going live:
- Open Google Search Console
- Go to Sitemaps
- Remove your old WordPress sitemap URL
- Submit the new
/sitemap.xml - Request indexing on your most important pages via URL Inspection
Step 7: Verify Structured Data Is Intact
WordPress plugins like Yoast add structured data (JSON-LD) automatically. On Jekyll, you add it manually.
In your _layouts/post.html:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": {{ page.title | jsonify }},
"description": {{ page.description | jsonify }},
"datePublished": "{{ page.date | date_to_xmlschema }}",
"dateModified": "{{ page.last_modified_at | default: page.date | date_to_xmlschema }}",
"author": {
"@type": "Person",
"name": {{ page.author | default: site.author | jsonify }}
}
}
</script>
Test with Google’s Rich Results Test before and after migration to verify no structured data was lost.
Step 8: The Migration Go-Live Sequence
Order matters. Do this exactly:
- Build and test Jekyll site locally — verify all pages render, no broken links
- Set up redirects on your hosting platform — before pointing DNS
- Deploy to your hosting platform — but keep WordPress live
- Test the new site at its staging URL — check 5-10 key pages manually
- Point DNS to the new host — this is when migration goes live
- Verify redirects are working — check old URLs return 301, not 404
- Submit new sitemap to Google Search Console
- Monitor Search Console for the next 2 weeks — watch for crawl errors and ranking changes
Step 9: Post-Migration Monitoring
In the 4 weeks after migration, check weekly:
Google Search Console → Coverage: Should show no significant increase in 404 errors. If you see new 404s, find the URLs and add redirects immediately.
Search Console → Performance: Compare impressions and clicks week over week. A small drop is normal (Google is re-indexing). A large sustained drop means redirects are missing.
Core Web Vitals: Jekyll sites typically score significantly better than WordPress. Confirm your scores improved in PageSpeed Insights.
Expected Timeline
| Week | What to Expect |
|---|---|
| 0–1 | Google discovers changes, some ranking fluctuation |
| 1–2 | Re-indexing, potential minor dip |
| 2–4 | Stabilisation, rankings return to pre-migration levels |
| 4–8 | Rankings often improve — Jekyll’s speed benefits kick in |
A well-executed migration should recover fully within 4 weeks and often improve rankings within 2–3 months as Google rewards the faster, cleaner site.
Migrating to Jekyll? Browse themes on JekyllHub to find the right design before you start — picking your theme first makes the technical migration easier to plan.
References
- Google Search Central: Site Move Guide
- Netlify Redirects Documentation
- jekyll-redirect-from Plugin
- Google Search Console Help
Preserving structured data during migration
WordPress plugins like Yoast SEO, RankMath, and Schema Pro add structured data (JSON-LD) to your pages — Article schema for posts, BreadcrumbList for navigation, and FAQPage for FAQ sections. This structured data powers rich results in Google Search: article bylines, FAQ dropdowns, breadcrumb trails in search snippets, and sitelinks search boxes.
After migrating to Jekyll, you need to re-implement this structured data without relying on a WordPress plugin. The most maintainable approach is a Jekyll include that generates JSON-LD for each page type. Create _includes/structured-data.html and build the appropriate schema based on page.layout:
For posts, generate an Article schema using page.title, page.date, page.author, page.description, and page.image (the post’s cover image). For the homepage, generate a WebSite schema with a SearchAction for your site search. For the About page, generate an Organization or Person schema with contact details. For FAQ pages, generate a FAQPage schema by looping through an _data/faq.yml file that contains questions and answers.
Test your structured data implementation with Google’s Rich Results Test before and after migration. Rich results that were appearing in search for your WordPress site — article dates, FAQ dropdowns — should be validated on your Jekyll site before you finalise the migration. Missing or malformed structured data will cost you the rich result enhancements over time.
Handling paginated archives after migration
WordPress automatically paginates category archives, tag archives, and the main blog listing when you have more posts than the configured “posts per page” setting. The paginated URLs (/category/jekyll/page/2/, /page/2/) may have accumulated inbound links and search ranking.
Jekyll’s pagination requires explicit configuration and differs in URL structure from WordPress. The jekyll-paginate-v2 plugin gives you the most control, allowing you to specify custom permalink patterns for paginated pages. Set the permalink to match your WordPress pagination URLs — /:num/ or /page/:num/ — rather than adopting a different pattern, which would require additional redirects.
For category and tag archive pagination specifically, WordPress uses /category/slug/page/2/ while Jekyll-archives generates different URL structures by default. Map your WordPress paginated archive URLs to the equivalent Jekyll-generated URLs and add redirects for any that differ. Paginated pages rarely accumulate significant inbound links (most links point to page 1), so the SEO impact of changing paginated URL structures is typically minor — but canonical tags on all paginated pages pointing to page 1 are worth adding regardless.
Internal linking audit post-migration
WordPress internal links often use absolute URLs (https://example.com/another-post/) rather than relative URLs. If your domain or URL structure changed during migration, these absolute links now point to incorrect destinations. A broken internal link wastes crawl budget and deprives the linked page of the PageRank signal the link would otherwise pass.
Run a full internal link audit after migration using a tool like Screaming Frog (crawl your site and export all internal links) or the Jekyll plugin html-proofer (checks that all internal links resolve to existing files at build time). For any broken internal links discovered, update the link in the Markdown source — do not rely on redirects to handle internal links, since the redirect adds an unnecessary HTTP round-trip for every internal navigation.
Post-migration is also a good time to improve your internal linking strategy beyond just fixing broken links. Identify your highest-authority pages (those with the most inbound links, or those ranking on page 1 for target keywords) and ensure they link to your other important pages. A well-linked internal architecture distributes authority throughout your site and helps search engines discover and index your content efficiently.
Long-term SEO maintenance after migration
The migration itself is a one-time project, but maintaining SEO performance after migration requires ongoing attention. The three most impactful ongoing tasks are monitoring for broken links, keeping content updated, and building new inbound links.
Broken links accumulate over time as external sites restructure their URLs, as you rename pages or update your site structure, and as external resources you link to disappear. A monthly Screaming Frog crawl or a monitoring service like Ahrefs Site Audit catches broken links before they affect user experience or crawl budget. Fix internal broken links in your Markdown sources; for external broken links, update to a working equivalent URL or remove the link.
Content freshness is a ranking factor for many query types. Posts that are two or three years old and have accumulated rankings may drop in search when competitors publish more recent content on the same topic. Update these posts periodically: refresh statistics, add newly relevant sections, and update the last_modified_at date in front matter (supported by the jekyll-last-modified-at plugin, which exposes the date in your templates and in your sitemap’s <lastmod> tag). Google uses lastmod dates from sitemaps to prioritise recrawling recently updated content.