skills/wordpress-migration-best-practices/SKILL.md
Best practices for migrating content out of WordPress. Use when asked to "migrate from WordPress", "export WordPress content", "move off WordPress", "WordPress migration strategy", or "extract WordPress data". Covers XML export, site mirroring, plugin-specific content, and migration planning.
npx skillsauth add koolamusic/wpmigrate-skills wordpress-migration-best-practicesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Comprehensive guide for extracting and migrating content from WordPress sites. Covers multiple extraction strategies, their trade-offs, and best practices for handling WordPress-specific content like custom plugins, WooCommerce, forms, and media.
Reference these guidelines when:
The built-in WordPress export tool. Go to WP Admin → Tools → Export to generate an XML file containing posts, pages, comments, categories, tags, and custom post types.
What you get:
What you don't get:
Best for: Simple blogs and content-focused sites with standard posts/pages.
Usage:
# Parse the WXR XML export with a script
python3 scripts/parse-wxr.py wordpress-export.xml --output ./content/
# Or use wp-cli if you have server access
wp export --dir=./exports/ --post_type=post,page
Key considerations:
[shortcode] text unless the plugin is activeClone the entire rendered site as static HTML files. This captures exactly what visitors see, including all rendered plugin output, theme styling, and dynamic content.
What you get:
What you don't get:
Best for: Sites with heavy theme customization or page builder content where the rendered output is more reliable than the raw database content.
Usage:
# HTTrack — full mirror
httrack "https://example.com" -O ./mirror \
--mirror --robots=0 --depth=10
# wget — alternative approach
wget --mirror --convert-links --adjust-extension \
--page-requisites --no-parent https://example.com
Key considerations:
/embed/ variants, print versions, AMP pagesrobots.txt — some important pages may be blocked from crawlerswp-content/uploads/ are organized by YYYY/MM/ — preserve this structureUse both XML export AND site mirroring together. The XML export gives you structured content with metadata; the mirror gives you rendered output and media files.
Workflow:
If you have server/hosting access, query the WordPress MySQL database directly.
Key tables:
| Table | Content |
|-------|---------|
| wp_posts | All content (posts, pages, revisions, attachments) |
| wp_postmeta | Custom fields, featured images, plugin data |
| wp_terms / wp_term_taxonomy | Categories, tags, custom taxonomies |
| wp_comments | Comments with metadata |
| wp_options | Site settings, widget configs, plugin settings |
| wp_usermeta | User profile data |
Usage:
-- Export all published posts
SELECT ID, post_title, post_content, post_date, post_name, post_type
FROM wp_posts
WHERE post_status = 'publish'
AND post_type IN ('post', 'page')
ORDER BY post_date DESC;
-- Get post metadata (featured images, custom fields)
SELECT p.post_title, pm.meta_key, pm.meta_value
FROM wp_posts p
JOIN wp_postmeta pm ON p.ID = pm.post_id
WHERE p.post_status = 'publish';
Best for: Large sites where the XML export times out, or when you need access to plugin-specific database tables.
WooCommerce stores products, orders, and customer data in custom post types and meta tables.
Content to extract:
wp_posts where post_type = 'product'wp_postmetaproduct_cat_product_image_gallery metapost_type = 'product_variation'Not typically migrated:
Best practice: Export products to CSV using WooCommerce's built-in exporter (WP Admin → Products → Export), then transform to the target platform's format.
Form plugins store form definitions and submissions differently:
wpcf7_contact_form post type. Submissions are emailed, not stored in DB by default (unless using Flamingo plugin).wp_gf_form table, entries in wp_gf_entry. Export entries from Forms → Import/Export.wpforms post type (serialized data). Entries in wp_wpforms_entries.Best practice: Export form submissions as CSV. Recreate form structures manually on the new platform — form definitions rarely migrate cleanly between systems.
Page builder content is the hardest to migrate because it's stored as:
[vc_row][vc_column][vc_column_text]Content[/vc_column_text][/vc_column][/vc_row]_elementor_data field[et_pb_section][et_pb_row]...Best practice: Use site mirroring to capture the rendered output. The raw shortcode/JSON data is only useful if migrating to another WordPress site with the same page builder installed.
Cleanup required (from mirrored HTML):
SEO plugins store metadata in wp_postmeta:
| Meta Key (Yoast) | Meta Key (Rank Math) | Content |
|-------------------|---------------------|---------|
| _yoast_wpseo_title | rank_math_title | Custom page title |
| _yoast_wpseo_metadesc | rank_math_description | Meta description |
| _yoast_wpseo_focuskw | rank_math_focus_keyword | Focus keyword |
| _yoast_wpseo_canonical | rank_math_canonical_url | Canonical URL |
Best practice: Export SEO metadata early in the migration. Losing meta descriptions and custom titles impacts search rankings. Map these to your new platform's SEO fields.
wp_posts with their registered post_type slugwp_postmeta with field names as meta_keyacf-field-group post typefield_name_0_subfield, field_name_1_subfieldBest practice: Map ACF fields to your new platform's equivalent (frontmatter fields, structured content types, etc.). Document the field mapping before starting migration.
YYYY/MM/. Keep this or create a clear mapping?resize=800,600&ssl=1 to image URLs. Remove these for static hostingdata-src, not src. Always check data-src first-150x150, -300x200, etc.). Decide whether to keep these or regenerate for your new platform# Find all media references in exported content
grep -roh 'wp-content/uploads/[^"'"'"' ]*' content/ | sort -u > media-inventory.txt
# Download all referenced media
while read url; do
wget -x -nH "https://example.com/$url" -P ./media/
done < media-inventory.txt
Maintaining existing URLs prevents broken links from search engines and external sites.
Common WordPress permalink structures:
| WordPress Setting | URL Pattern | Example |
|-------------------|-------------|---------|
| Day and name | /:year/:month/:day/:title/ | /2024/01/15/my-post/ |
| Month and name | /:year/:month/:title/ | /2024/01/my-post/ |
| Post name | /:title/ | /my-post/ |
| Custom | varies | /blog/:title/ |
Best practices:
/feed/ to your new RSS feed URL/wp-content/uploads/ paths if you reorganize mediadevelopment
Migrate WordPress content to Jekyll. Use when asked to "convert WordPress to Jekyll", "migrate WP to Jekyll", "set up Jekyll from WordPress", "WordPress to static site", or "export WordPress to markdown". Covers content extraction, format conversion, Jekyll architecture setup, and deployment.
development
# WordPress-to-Jekyll Migration Playbook A reusable guide for migrating a WordPress site (via static HTML clone) to Jekyll 4.4 + Tailwind CSS 3.4, deployed on Netlify. Based on the migration of [andrewmiracle.com](https://andrewmiracle.com) — 429 static HTML pages spanning 2012–2025, converted to a fully themed Jekyll site with dark mode, digital garden features, password-protected projects, and RSS feeds. **Source:** 429 WordPress pages scraped to static HTML **Target:** Jekyll 4.4.1 + Tailwi
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------