npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@teagantb/payload-wordpress-migration

v1.0.3

Published

WordPress to Payload CMS migration plugin - Migrate posts, media, and content from WordPress to Payload CMS

Readme

Payload WordPress Migration Plugin

A comprehensive plugin for migrating content from WordPress to Payload CMS. This plugin enables seamless migration of posts, media, categories, authors, and SEO metadata from WordPress to Payload CMS.

Features

  • 📝 Post Migration: Migrate WordPress posts with full content preservation
  • 🖼️ Media Handling: Automatic image download and upload to Payload media collection
  • 🏷️ Categories & Authors: Automatic creation of categories and authors/users
  • 🌐 Multi-locale Support: Detect and migrate content in multiple languages (en/vi)
  • 🔍 SEO Migration: Preserve SEO metadata from Rank Math and Yoast SEO
  • 🎨 Block Conversion: Convert WordPress blocks to Lexical editor or CMS blocks
  • 📊 Admin UI: User-friendly interface for migration management
  • 🔄 Batch Processing: Process multiple posts in batches

Installation

npm install @teagantb/payload-wordpress-migration
# or
pnpm add @teagantb/payload-wordpress-migration
# or
yarn add @teagantb/payload-wordpress-migration

Quick Start

1. Add Plugin to Config

import { wordpressMigration } from '@teagantb/payload-wordpress-migration'
import { buildConfig } from 'payload'

export default buildConfig({
  plugins: [
    wordpressMigration({
      collections: {
        posts: 'posts',
        categories: 'categories',
        media: 'media',
        users: 'users',
      },
      enableAdminUI: true,
      adminRoute: '/migrate-xml',
    }),
  ],
  // ... rest of config
})

2. Ensure Required Collections Exist

Your Payload config should have these collections:

  • posts: With title, slug, content (richText), category, authors, heroImage, meta fields
  • categories: With title, slug fields
  • media: With upload configuration
  • users: With auth enabled

3. Use Admin UI

  1. Start your Payload server: pnpm dev
  2. Navigate to /admin/migrate-xml in your browser
  3. Upload WordPress XML export file
  4. Configure migration options
  5. Click "Start Migration"

Configuration Options

interface WordPressMigrationPluginOptions {
  /** Block type mappings (WordPress → Payload CMS) */
  blockMappings?: {
    youtube?: string
    video?: string
    videopress?: string
    gallery?: string
    button?: string
    media?: string
    banner?: string
    columns?: string
  }

  /** Collection name mappings */
  collections?: {
    posts?: string
    categories?: string
    media?: string
    users?: string
  }

  /** Enable admin UI (default: true) */
  enableAdminUI?: boolean

  /** Admin UI route path (default: '/migrate-xml') */
  adminRoute?: string
}

Programmatic Usage

Migrate from XML File

import { migrate } from '@teagantb/payload-wordpress-migration'
import { getPayload } from 'payload'
import config from '@payload-config'

const payload = await getPayload({ config })

const stats = await migrate(payload, {
  xmlFilePath: './wordpress-export.xml',
  batchSize: 10,
  skipImages: false,
  continueOnError: true,
})

console.log(`Migrated ${stats.successfulPosts}/${stats.totalPosts} posts`)

Migrate from WordPress API

const stats = await migrate(payload, {
  wpApiUrl: 'https://example.com/wp-json/wp/v2',
  wpCredentials: {
    username: 'user',
    password: 'app-password',
  },
  batchSize: 10,
})

Migrate with Mock Data (Testing)

const stats = await migrate(payload, {
  useMock: true,
  batchSize: 5,
})

Migration Options

interface MigrationOptions {
  /** Use mock data instead of fetching from WordPress */
  useMock?: boolean

  /** WordPress API endpoint */
  wpApiUrl?: string

  /** WordPress API credentials */
  wpCredentials?: {
    username: string
    password: string
  }

  /** Path to WordPress XML export file */
  xmlFilePath?: string

  /** XML content as string (Cloudflare Workers compatible) */
  xmlContent?: string

  /** Batch size for processing posts */
  batchSize?: number

  /** Dry run (don't actually create posts) */
  dryRun?: boolean

  /** Skip image uploads */
  skipImages?: boolean

  /** Continue on errors */
  continueOnError?: boolean
}

Block Conversion

The plugin automatically converts WordPress blocks:

Lexical-Supported Blocks

  • Paragraphs
  • Headings
  • Lists
  • Quotes
  • Tables
  • Code blocks

CMS Blocks

  • Gallery → galleryBlock
  • YouTube → youtubeBlock
  • Video → videoBlock
  • VideoPress → videopressBlock
  • Buttons → buttonBlock
  • Columns → columnsBlock

You need to define these blocks in your Payload config. Block slugs can be customized via blockMappings option.

Supported WordPress Features

  • ✅ WordPress Block Editor (Gutenberg)
  • ✅ Classic Editor HTML
  • ✅ Featured Images
  • ✅ Categories and Tags
  • ✅ Authors
  • ✅ SEO Metadata (Rank Math, Yoast SEO)
  • ✅ Multi-language (WPML, Polylang detection)
  • ✅ Media attachments

Migration Statistics

After migration, you'll receive statistics:

interface MigrationStats {
  totalPosts: number
  successfulPosts: number
  failedPosts: number
  totalChunks: number
  totalImages: number
  totalErrors: number
  processingTime: number // milliseconds
}

Requirements

  • Payload CMS 3.37.0 or higher
  • Node.js 18.20.2 or higher
  • Required collections: posts, categories, media, users

Development

# Install dependencies
pnpm install

# Run dev environment
pnpm dev

# Build plugin
pnpm build

# Run tests
pnpm test

License

MIT

Support

For issues and questions, please open an issue on GitHub.