📝 Introduction

Jekyll is a static site generator. Your site becomes fast, secure, and easy to host. This guide walks you through moving from WordPress to Jekyll with beginner-friendly steps and copy–paste commands. You will:

  • Back up your WordPress site (safety first).
  • Export posts and pages and convert them to Markdown.
  • Move images and update links.
  • Keep your existing URLs with redirects and permalinks.
  • Add SEO features and deploy.

🧭 What you will migrate

  • Posts & Pages: Converted to Markdown with front matter (title, date, tags).
  • Media: Images and files from wp-content/uploads.
  • Permalinks: Keep existing paths or create redirects.
  • Menus/Widgets: Recreate via Jekyll layouts/partials.
  • Comments: Optional via static-friendly services (or omit).

🛟 Back up WordPress (database & files)

Why: You need a safe snapshot before changing anything.

# If you have shell access to your WordPress host
# 1) Export database (MySQL/MariaDB)
mysqldump -u USER -p DBNAME > wordpress-backup.sql

# 2) Archive wp-content (themes, plugins, uploads)
tar czf wp-content-backup.tgz wp-content
No shell access? Use your host’s backup tools or WordPress backup plugins to download a full backup.

🧰 Choose a migration path

PathHow it worksProsCons
WordPress XML → Jekyll Importer (Ruby) Export XML from WP; convert to Markdown via jekyll-import. Reliable, keeps dates/metadata. Requires Ruby tooling.
WordPress “Jekyll Exporter” plugin Generates a ready-to-run Jekyll site. Very simple if it works on your WP version. Plugin may be outdated; manual fixes likely.
Export to Markdown (Node/Python tools) Converts content + media to Markdown folders. Good control over structure. More steps to wire into Jekyll.

🏗️ Create your new Jekyll site

What it does: Sets up a clean Jekyll project you will import content into.

# Prerequisites (Linux/macOS; on Windows use RubyInstaller + DevKit)
gem install bundler jekyll

# Create a new site
jekyll new mysite
cd mysite

# Use bundler to install gems from the Gemfile
bundle install

Optional: choose a theme (e.g., minima default) or set a remote theme later.


📥 Import and convert content

Option A — WordPress XML via jekyll-import (recommended)

  1. In WordPress, go to Tools → Export → export All content to an XML file (e.g., wordpress.xml).
  2. In your Jekyll project folder, run:
bundle add jekyll-import
bundle install

# Run the importer (interactive Ruby script)
ruby -rubygems -e 'require "jekyll-import";
JekyllImport::Importers::WordPressDotCom.run({
  "source" => "wordpress.xml",
  "no_fetch_images" => true,  # we will move media separately
  "assets_folder" => "assets/uploads"
})'

What it does: Converts posts/pages into _posts/ and top-level Markdown files, with YAML front matter. Media links will still point to WordPress for now.

Option B — WordPress “Jekyll Exporter” plugin

  1. Install and run the plugin in WordPress to download a zip.
  2. Unzip into your Jekyll project, then run bundle install.

Option C — Export to Markdown (alternative tools)

Use a Markdown exporter (Node/Python) to create a content/ folder, then move files into _posts/_pages and add front matter as needed.


🖼️ Move media and fix image links

Goal: Serve images from your static Jekyll site, not from the old WordPress install.

# Copy your WordPress uploads locally, keeping year/month structure
# From your backup or server: wp-content/uploads/...
mkdir -p assets/uploads
# Example: copy the folder into your Jekyll project
# rsync -av wp-content/uploads/ assets/uploads/   # or drag-and-drop

Update links in Markdown:

# Replace absolute WP URLs with local paths (adjust your domain)
# macOS (BSD sed): use -E and backup extension
sed -E -i '' 's~https?://(www\.)?yourwpdomain\.tld/wp-content/uploads~{{ site.baseurl }}/assets/uploads~g' \
  $(git ls-files '*.md' '*.markdown' 2>/dev/null)

# Linux (GNU sed)
sed -E -i 's~https?://(www\.)?yourwpdomain\.tld/wp-content/uploads~{{ site.baseurl }}/assets/uploads~g' \
  $(git ls-files '*.md' '*.markdown' 2>/dev/null)
Note: If you don’t use site.baseurl, replace it with just /assets/uploads.


📈 Add SEO, feeds, and sitemap

Install common plugins and basic metadata:

bundle add jekyll-feed jekyll-sitemap
# _config.yml
title: "My Site"
url: "https://example.com"
description: "Short site description"
plugins:
  - jekyll-feed
  - jekyll-sitemap
  - jekyll-redirect-from

# Optional but useful
markdown: kramdown
theme: minima   # or your chosen theme

Create robots.txt and ensure your theme outputs <meta name="description"> and Open Graph tags (or add includes).


🧪 Test locally

bundle exec jekyll serve
# Open http://127.0.0.1:4000  (or http://localhost:4000)
  • Click through posts/pages; check images and internal links.
  • Validate a few old URLs to ensure they still work or redirect correctly.

🚀 Deploy (GitHub Pages / Netlify)

GitHub Pages (user/site repo)

# Initialize repo and push
git init
git add .
git commit -m "Initial Jekyll site"
git branch -M main
git remote add origin https://github.com/USER/REPO.git
git push -u origin main

# In repo settings, enable GitHub Pages (from main branch /root or /docs)

Netlify (drag-and-drop or CI)

# Netlify build settings (example)
# Build command: bundle exec jekyll build
# Publish directory: _site

Set your custom domain and HTTPS in your hosting provider.


📋 Common tasks (copy & paste)

# Bulk set front matter layout for all posts (example via ripgrep + sd)
# Install rg (ripgrep) and sd (https://github.com/chmln/sd) if needed
rg --files -g "_posts/**/*.md" -0 | xargs -0 -I{} sd '^---\n' '---\nlayout: post\n' {}

# Find posts still linking to old domain
rg -n "https?://(www\.)?yourwpdomain\.tld" _posts _pages 2>/dev/null

# Rename files to Jekyll post naming (YYYY-MM-DD-title.md)
# Example for one file
mv "my old post.md" "2023-11-20-my-old-post.md"

# Add categories/tags to a single post
# (Open the file and edit YAML)
# ---
# title: "..."
# date: 2023-11-20
# categories: [news]
# tags: [release, jekyll]
# ---

🛠 Troubleshooting

Images not loading.
Check that files exist under assets/uploads/ and your Markdown paths match. Try absolute paths (/assets/uploads/…) if baseurl is empty.

Broken internal links.
Your old slugs or categories may differ. Add redirect_from entries or adjust permalink patterns.

Build fails on GitHub Pages.
Only approved plugins are allowed. Remove unsupported plugins or build via GitHub Actions/Netlify and publish the generated _site.

Code blocks or shortcodes look wrong.
Replace WordPress shortcodes with Markdown or Liquid includes. For oEmbed content, use plain links or custom includes.

Missing special characters after conversion.
Ensure files are UTF-8 and front matter is valid YAML (three dashes on top/bottom).


📚 Resources & further reading