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 🙏

© 2025 – Pkg Stats / Ryan Hefner

payload-wordpress-migrator

v0.0.21

Published

A PayloadCMS plugin for WordPress migration - migrate and manage WordPress content directly in your Payload admin dashboard

Readme

Payload WordPress Migrator Plugin

A comprehensive PayloadCMS plugin for WordPress migration - migrate and manage WordPress content directly in your Payload admin dashboard with a powerful React-based interface.

🚀 Features

  • 📊 Interactive Migration Dashboard: Real-time progress tracking with a modern React interface
  • 🔄 WordPress API Integration: Secure REST API connectivity with application password authentication
  • 📋 Smart Job Management: Create, monitor, pause, resume, and retry migration jobs
  • 🎯 Content Type Discovery: Automatic detection of posts, pages, media, categories, and custom post types
  • 🔗 Advanced Field Mapping: Visual field mapping interface with dot-notation support
  • 🖼️ Intelligent Media Migration: Auto-import featured images and content media with duplicate detection
  • 🧱 Gutenberg to Lexical: Convert WordPress blocks to PayloadCMS Lexical format
  • Performance Optimized: Configurable batch processing with background job execution
  • 🔄 Resume & Retry: Intelligent job recovery with progress preservation
  • 🔒 Production Ready: Comprehensive error handling and SSL certificate management

📦 Installation

# npm
npm install payload-wordpress-migrator

# yarn
yarn add payload-wordpress-migrator

# pnpm
pnpm add payload-wordpress-migrator

🚀 Quick Start

Basic Setup

Add the plugin to your Payload config:

import { buildConfig } from 'payload'
import { payloadWordPressMigrator } from 'payload-wordpress-migrator'

export default buildConfig({
  // ... your existing config
  plugins: [
    payloadWordPressMigrator({
      wpSiteUrl: process.env.WORDPRESS_API_URL,
      wpUsername: process.env.WORDPRESS_USERNAME,
      wpPassword: process.env.WORDPRESS_APP_PASSWORD,
      collections: {
        posts: { wpPostType: 'post', enableBlocks: true },
        pages: { wpPostType: 'page', enableBlocks: true },
        media: { wpPostType: 'media' },
      },
      enableMediaDownload: true,
      migrationBatchSize: 25,
    }),
  ],
})

Environment Variables

Add these to your .env file:

WORDPRESS_API_URL=https://your-wordpress-site.com
WORDPRESS_USERNAME=your-username
WORDPRESS_APP_PASSWORD=your-application-password

WordPress Setup

Application Password Setup

  1. In WordPress admin, go to UsersProfile
  2. Scroll down to Application Passwords
  3. Enter a name (e.g., "Payload Migration")
  4. Click Add New Application Password
  5. Copy the generated password (save it securely)
  6. Use this password as WORDPRESS_APP_PASSWORD

REST API Requirements

  • WordPress 5.6+ (for Application Passwords)
  • REST API enabled (default in most installations)
  • User with appropriate permissions for content access

Configuration Options

type PayloadWordPressMigratorConfig = {
  // WordPress Connection
  wpSiteUrl?: string // WordPress site URL
  wpUsername?: string // WordPress username
  wpPassword?: string // WordPress application password

  // Collection Configuration
  collections?: Partial<Record<CollectionSlug, WordPressCollectionMapping>>

  // Plugin Control
  disabled?: boolean // Disable plugin functionality
  disableDashboard?: boolean // Disable dashboard UI

  // Performance Settings
  migrationBatchSize?: number // Batch size (default: 10)
  enableAutoSync?: boolean // Auto-sync on startup

  // Media Migration
  enableMediaDownload?: boolean // Download actual files (default: false)
  maxMediaFileSize?: number // Max file size in bytes (default: 10MB)
  allowedMediaTypes?: string[] // Allowed MIME types
  allowSelfSignedCerts?: boolean // Allow self-signed SSL (dev only)
}

type WordPressCollectionMapping = {
  wpPostType: string // WordPress content type
  fieldMapping?: Record<string, string> // Custom field mapping
  enableBlocks?: boolean // Convert Gutenberg blocks
  customFields?: string[] // ACF field names to migrate
  importContentMedia?: boolean // Auto-import content images
}

📋 Plugin Architecture

The plugin creates the following collections and components in your PayloadCMS instance:

Collections Added

  1. wordpress-migration: Core collection for managing migration jobs

    • Job configuration and status tracking
    • Progress monitoring with detailed logs
    • Built-in dashboard interface
  2. Enhanced Target Collections: Automatically adds WordPress metadata fields to configured collections:

    • migratedFromWordPress.wpPostId: Original WordPress post ID
    • migratedFromWordPress.wpPostType: WordPress content type
    • migratedFromWordPress.migrationDate: Migration timestamp

UI Components

  • Migration Dashboard: React-based interface with real-time updates
  • WordPress Site Configuration: Secure credential management with localStorage persistence
  • Content Type Selector: Dynamic dropdown populated from WordPress API discovery
  • Field Mapping Interface: Visual field mapping with source/destination field analysis
  • Job Monitor: Live progress tracking with success/failure metrics

API Endpoints

The plugin adds these endpoints to your PayloadCMS API:

POST   /api/wordpress/test-connection      # Test WordPress connectivity
GET    /api/wordpress/migration-summary    # Dashboard data with caching
POST   /api/wordpress/discover-content     # Content type discovery
GET    /api/wordpress/migration-jobs       # Job status retrieval
POST   /api/wordpress/migration-jobs       # Start migration jobs
PUT    /api/wordpress/migration-jobs       # Pause/resume jobs
DELETE /api/wordpress/migration-jobs       # Delete jobs
POST   /api/wordpress/content-fields       # Analyze WordPress fields
GET    /api/collections/:slug/fields       # Analyze PayloadCMS fields

🎯 Content Migration Features

Supported Content Types

| Content Type | Features | Notes | | --------------------- | ------------------------------------------------------- | --------------------------------- | | Posts | ✅ Content, metadata, categories, tags, featured images | Full Gutenberg block conversion | | Pages | ✅ Content, metadata, featured images, custom fields | Hierarchical structure support | | Media | ✅ File downloads, metadata, alt text, captions | MIME type filtering & size limits | | Categories | ✅ Names, descriptions, hierarchy, counts | Taxonomy relationships | | Tags | ✅ Names, descriptions, post associations | Tag cloud support | | Users | ✅ User data, roles, capabilities, avatars | Permission mapping | | Custom Post Types | ✅ Auto-discovery, custom fields, metadata | ACF integration |

Advanced Content Processing

  • HTML to Lexical Conversion: Sophisticated converter handles complex HTML structures
  • Gutenberg Block Processing: Converts blocks to PayloadCMS block format
  • ACF Field Migration: Automatic Advanced Custom Fields detection and migration
  • Media Auto-Import: Scans content for WordPress media URLs and imports automatically
  • Relationship Preservation: Maintains post-category, post-tag, and other relationships

🖼️ Media Migration

Migration Modes

The plugin supports two modes for media migration:

  1. Metadata Only (default): Migrates media titles, descriptions, alt text, and URLs
  2. Full File Migration: Downloads files from WordPress and uploads them to PayloadCMS

Enabling Media File Migration

payloadWordPressMigrator({
  enableMediaDownload: true, // Enable file downloads
  maxMediaFileSize: 50 * 1024 * 1024, // 50MB limit
  allowedMediaTypes: [
    'image/jpeg',
    'image/png',
    'image/gif',
    'image/webp',
    'application/pdf',
    'video/mp4',
  ],
  allowSelfSignedCerts: true, // For development only
})

Auto-Import Features

Featured Image Auto-Import

  • Automatically detects and imports featured images using WordPress _embed data
  • Fallback support when _embed data is unavailable
  • Creates PayloadCMS media records with actual file downloads
  • Links imported media to posts/pages via featuredImage field

Content Media Auto-Import

  • Scans HTML content for WordPress media URLs (wp-content/uploads)
  • Downloads and imports images referenced in post/page content
  • Preserves alt text and title attributes
  • Smart duplicate detection to avoid re-importing existing files

MediaBlock Conversion

When migrating content with enableMediaDownload: true, the plugin now converts HTML <img> tags to proper PayloadCMS MediaBlocks:

  • HTML Images → MediaBlocks: Converts inline images to structured MediaBlock components
  • Media Import Integration: Automatically downloads and links media files to MediaBlocks
  • Rich Editor Support: MediaBlocks display properly in PayloadCMS Lexical editor
  • Frontend Rendering: Works seamlessly with PayloadCMS RichText component
  • Metadata Preservation: Maintains alt text, titles, and dimensions for accessibility

Configuration Example

collections: {
  posts: {
    wpPostType: 'post',
    importContentMedia: true,    // Enable content media auto-import
  },
  media: {
    wpPostType: 'media'         // Required for media storage
  }
},
enableMediaDownload: true       // Required for auto-import

Migration Workflow Options

  1. Recommended: Migrate posts/pages only - media will be auto-imported
  2. Alternative: Migrate media first, then posts/pages (avoids duplicates)

Performance Considerations

  • Files processed in configurable batches to prevent memory issues
  • Large files streamed to minimize memory usage
  • Failed downloads don't stop the entire migration process
  • Media auto-import runs in parallel for optimal performance
  • Smart duplicate detection prevents re-importing existing media

🔧 Advanced Configuration

Complete Configuration Example

import { buildConfig } from 'payload'
import { payloadWordPressMigrator } from 'payload-wordpress-migrator'

export default buildConfig({
  plugins: [
    payloadWordPressMigrator({
      // WordPress Connection
      wpSiteUrl: process.env.WORDPRESS_API_URL,
      wpUsername: process.env.WORDPRESS_USERNAME,
      wpPassword: process.env.WORDPRESS_APP_PASSWORD,

      // Collection Configuration
      collections: {
        posts: {
          wpPostType: 'post',
          enableBlocks: true,
          importContentMedia: true,
          customFields: ['_yoast_wpseo_title', '_yoast_wpseo_metadesc'],
          fieldMapping: {
            'title.rendered': 'title',
            'content.rendered': 'content',
            'excerpt.rendered': 'excerpt',
          },
        },
        pages: {
          wpPostType: 'page',
          enableBlocks: true,
          importContentMedia: true,
          disableHtmlConversion: false, // Enable HTML to Lexical conversion
        },
        media: {
          wpPostType: 'media',
        },
        categories: {
          wpPostType: 'category',
        },
        products: {
          // Custom post type example
          wpPostType: 'product',
          enableBlocks: false,
          customFields: ['_price', '_stock_status', '_featured'],
        },
      },

      // Performance & Batch Settings
      migrationBatchSize: 25,
      enableAutoSync: false,

      // Media Configuration
      enableMediaDownload: true,
      maxMediaFileSize: 50 * 1024 * 1024, // 50MB
      allowedMediaTypes: [
        'image/jpeg',
        'image/png',
        'image/gif',
        'image/webp',
        'image/svg+xml',
        'application/pdf',
        'video/mp4',
        'video/webm',
        'audio/mpeg',
      ],

      // Development Settings
      allowSelfSignedCerts: process.env.NODE_ENV === 'development',

      // Plugin Control
      disabled: false,
      disableDashboard: false,
    }),
  ],
})

Field Mapping Configuration

The plugin supports sophisticated field mapping with dot notation:

fieldMapping: {
  // WordPress field path → PayloadCMS field path
  'title.rendered': 'title',
  'content.rendered': 'content',
  'meta._yoast_wpseo_title': 'seo.title',
  'acf.hero_image': 'hero.image',
  'custom_field_name': 'mappedField'
}

🎛️ Migration Dashboard

The plugin provides a comprehensive React-based dashboard accessible at /admin/collections/wordpress-migration:

Dashboard Features

  • Site Configuration: Secure WordPress credentials management
  • Content Discovery: Automatic scan and analysis of available content
  • Job Creation: Visual job setup with field mapping interface
  • Real-time Monitoring: Live progress updates with success/failure metrics
  • Job Controls: Start, pause, resume, retry operations
  • Error Reporting: Detailed logs and error analysis

Dashboard Screenshots

The interface includes:

  1. Configuration Panel: WordPress site setup and testing
  2. Content Overview: Discovered content types with item counts
  3. Job Management: Active and completed migration jobs
  4. Progress Tracking: Visual progress bars with detailed statistics
  5. Log Viewer: Real-time migration logs and error reporting

🛠️ Development & Extension

Plugin Structure

src/
├── components/                 # React UI components
│   ├── MigrationDashboardClient.tsx    # Main dashboard
│   ├── ContentTypeSelect.tsx           # Content type picker
│   ├── FieldMappingConfiguration.tsx   # Field mapper
│   └── SimpleFieldMapping.tsx         # Simple mapping UI
├── utils/
│   ├── wordpressApi.ts                # WordPress API client
│   └── htmlToLexicalConverter.ts      # Content conversion
└── index.ts                           # Plugin entry point

Custom Field Transformations

Extend the plugin with custom field transformations:

// In your plugin configuration
const customTransform = (wpItem: any, contentType: string) => {
  // Custom transformation logic
  return transformedData
}

Error Handling

The plugin provides comprehensive error handling:

  • Connection Errors: WordPress API connectivity issues
  • Authentication Errors: Invalid credentials or permissions
  • Content Errors: Malformed content or missing fields
  • Media Errors: Download failures or file size limits
  • Database Errors: PayloadCMS creation failures

📊 Migration Best Practices

Pre-Migration Checklist

  1. ✅ WordPress Setup

    • Generate application password
    • Verify REST API access
    • Check user permissions
    • Test SSL certificate
  2. ✅ PayloadCMS Configuration

    • Configure target collections
    • Set up field mappings
    • Test media collection setup
    • Verify storage configuration
  3. ✅ Content Analysis

    • Run content discovery scan
    • Review field mapping options
    • Identify custom post types
    • Plan migration sequence

Migration Strategy

Recommended Migration Order:

  1. Categories & Tags (establishes taxonomy)
  2. Media Files (creates media library)
  3. Pages (static content first)
  4. Posts (blog content with relationships)
  5. Users (author information)
  6. Custom Post Types (specialized content)

Performance Optimization:

  • Start with smaller batch sizes (10-25) for initial testing
  • Increase batch size (50-100) for production migrations
  • Monitor memory usage during large media migrations
  • Use resume functionality for interrupted migrations

Troubleshooting Common Issues

Collection Configuration Required

Error: "The following path cannot be queried: migratedFromWordPress"

Solution: Ensure all target collections are configured in plugin options:

collections: {
  posts: { wpPostType: 'post' },
  pages: { wpPostType: 'page' },
  media: { wpPostType: 'media' }, // Required for media migration
}

Media Migration Issues

Error: "MIME type not allowed" or "File too large"

Solution: Adjust media configuration:

allowedMediaTypes: ['image/jpeg', 'image/png', /* add more types */],
maxMediaFileSize: 50 * 1024 * 1024, // Increase size limit

SSL Certificate Errors

Error: "self-signed certificate" in development

Solution: Enable self-signed certificates for development:

allowSelfSignedCerts: process.env.NODE_ENV === 'development'

🔧 Technical Requirements

  • Node.js: ^18.20.2 || >=20.9.0
  • PayloadCMS: ^3.29.0
  • Package Manager: pnpm ^9 || ^10
  • WordPress: 5.6+ with REST API enabled
  • Memory: 512MB+ recommended for media migrations
  • Storage: Adequate space for media file imports

📈 Performance Considerations

  • Batch Processing: Configurable batch sizes prevent memory overflow
  • Background Jobs: Non-blocking migration execution
  • Progress Persistence: Resume interrupted migrations
  • Memory Management: Efficient file streaming for large media
  • Cache Management: Intelligent caching with invalidation
  • Parallel Processing: Concurrent media imports for optimal speed

🤝 Contributing

We welcome contributions! Areas for enhancement:

  • Additional content type support
  • Enhanced field mapping UI
  • Performance optimizations
  • Advanced content transformations
  • Integration tests
  • Documentation improvements

📝 License

MIT License - see LICENSE file for details.

🎯 Roadmap

  • [ ] WordPress multisite support
  • [ ] Advanced Custom Fields Pro support
  • [ ] WooCommerce product migration
  • [ ] Automated testing suite
  • [ ] Docker development environment
  • [ ] Migration templates and presets
  • [ ] Webhook integration for real-time sync

Author: Igor Abdulovic at Brightscout

Repository: GitHub

Issues: GitHub Issues