Beta Help us perfect WordPress content migration. Apply for Early Access →
migro.dev / docs

Migro Documentation

Everything you need to set up and use Migro for your WordPress staging workflow — from installation to Pro features and troubleshooting.

v1.x Requires WP 5.6+ · PHP 7.4+

Introduction

Migro is a developer-focused WordPress plugin that changes how you move content between environments. Traditional workflows force you to migrate entire sites — which risks data loss on the live site. Migro lets you select and migrate specific posts, pages, media, and all metadata between environments, bypassing full-site deployments entirely.

Hybrid architecture

Migro uses a hybrid approach: it reads target environment data through a secure database connection while authenticating operations natively via the WordPress REST API and Application Passwords.

Installation

01

Download the Plugin

Download the free version directly from the WordPress plugin repository, or use your Migro Pro ZIP file from your license email.

02

Install on both sites

Migro needs to be active on both environments — your staging site and your production site. Install and activate it on each one.

03

Activate

Go to WordPress Admin → Plugins → Add New → Upload Plugin. Install and activate. The Migro menu will appear under Tools → Content Migration.

Requirements

  • WordPress: 5.6 or higher (required for native Application Passwords)
  • PHP: 7.4 or higher
  • cURL: Your source site must support cURL to send requests
  • Database access: You need the database credentials of your remote environment

Generating Application Passwords

To securely transport content, Migro requires an Application Password on the target site (e.g., production).

  1. Log in to your remote target site directly.
  2. Go to Users → Profile (or edit your admin user).
  3. Scroll down to the Application Passwords section.
  4. In the "New Application Password Name" field, type something like Migro Staging.
  5. Click Add New Application Password.

Save your password immediately

WordPress shows the generated password (e.g. xxxx xxxx xxxx xxxx xxxx xxxx) only once. Copy and store it before closing the screen.

Configuring Connections

On your local/staging site, go to Tools → Content Migration → Connection tab and fill in:

  • Site URL: Full URL of your remote site (e.g. https://production.com)
  • Database Host: Usually localhost, 127.0.0.1, or a host provided by your hosting provider
  • Database Name: The remote site's database name
  • Database Username / Password: Database credentials (not your WordPress login)
  • API Username: Your WordPress admin username on the remote site
  • Application Password: The 24-character password generated in the previous step

Click Test Connection. Once verified, the connection is saved automatically for future use.

Local by WP Engine + Production Server

A common workflow is running your staging environment in Local by WP Engine and pushing content to a live production server. Migro supports this directly.

01

Install Migro on both sites

Install and activate Migro on your Local site and on your production server.

02

Create an Application Password on production

Log into your live production site, go to Users → Profile → Application Passwords, and generate a password for Migro. Save it immediately — it is only shown once.

03

Get your production database credentials

Your hosting provider's control panel (cPanel, Kinsta, WP Engine, Cloudways, etc.) has your database host, name, and credentials. The host is usually localhost or a hostname like mysql.yourhost.com.

04

Configure the connection in Local

On your Local site, go to Migro → Settings → Connection and enter your production server's Site URL, database credentials, and Application Password. Click Test Connection to verify.

Local MySQL socket

Local by WP Engine uses a MySQL socket instead of a standard host. If another site needs to connect to your Local site (pulling from Local instead of pushing to it), paste the socket path from the Database tab in the Local app into the Database Host field. It looks like:

Local socket path
/Users/username/Library/Application Support/Local/run/xyz/mysql/mysqld.sock

Migrating Content

After a successful connection, navigate to the Migration tab in the Migro plugin.

  1. Select a saved connection from the dropdown.
  2. Choose direction: Remote → Local or local publishing.
  3. Click Load Content — a list of all available posts and pages appears.
  4. Use checkboxes to select the specific items to migrate.
  5. Configure conflict resolution and media options.
  6. Click Start Migration.

Migro handles everything automatically, including source URL replacement to match your target domain.

Conflict Resolution

When Migro finds that an item already exists on the destination site, it uses the conflict resolution strategy you selected.

Migro identifies "the same item" by a sync key — a unique identifier stored in post meta that tracks an item across environments regardless of its post ID. This means renaming or moving a post does not break the connection between environments.

  • Overwrite (Recommended): Replaces the existing item with the incoming version. All metadata and images are updated. Use this when you want the destination to match the source exactly.
  • Skip: Leaves the existing item untouched. Use this when you want to deploy only new content.

Media Deduplication

Migro automatically scans post content and featured images for media files to transfer.

With Migrate associated media and Deduplication enabled, Migro downloads images into the WordPress Media Library and hashes them (MD5). If an image was already migrated, Migro skips the re-upload and correctly re-maps the URL — preventing duplicate media clutter.

Backups & Restore

When you enable Create Backup in the migration options, Migro saves a snapshot of any content that is about to be overwritten. These snapshots let you undo a migration if something went wrong.

Viewing backups

Go to Migro → Backups. Each backup shows the post title and type, the date and time it was created, and which migration created it.

Restoring a backup

Click Restore next to any backup to roll that item back to the saved version. The current version is overwritten with the backup.

Deleting backups

Click Delete to remove a backup you no longer need. Backups older than 30 days are cleaned up automatically.

Logs

Every migration is recorded. Go to Migro → Logs to see the full history. Each log entry shows:

  • The post title and type
  • The migration direction (Pull or Push)
  • The result: Success, Skipped, or Error
  • A timestamp
  • Any error message if the migration failed

Logs are kept for 30 days by default. You can change the retention period in Migro → Settings → Logs.

Pro Features

The free version is limited to 10 migrations/month covering standard posts and pages. Professional and Business plans unlock the complete developer toolkit.

ACF & Yoast SEO

Pro includes full bridging of Advanced Custom Fields and Yoast SEO data. Migro scans for ACF relationship fields, galleries, repeater arrays, and all Yoast metadata options (focus keyword, title, indexing rules) and mirrors them accurately across environments.

Taxonomies & Custom Post Types

In addition to standard categories and tags, Migro Pro bridges Custom Post Types and Custom Taxonomies natively. It evaluates parent-child taxonomy trees to ensure category relationships never break during migration.

Quick Migrate

Quick Migrate adds a one-click migration link directly to your post and page lists. Hover over any item and click Push to Production (or Pull from Staging, depending on your environment) to deploy that single item with your default settings — without opening the full migration interface.

When editing a post in the Gutenberg block editor, a Migro panel appears in the right sidebar. Click the button there to migrate the current post without leaving the editor. The label always reflects the right direction based on which environment you are on.

Page Builder Support

When migrating content built with a page builder, layout styles need to be regenerated on the destination site. Migro handles this automatically after each migration — no configuration needed. It detects which builders are active and triggers the right cache rebuild for each.

  • Elementor: Regenerates the Elementor CSS cache for migrated posts
  • Divi: Triggers a Divi CSS rebuild
  • Beaver Builder: Refreshes the builder cache
  • WPBakery: Updates shortcode rendering
  • Oxygen Builder: Regenerates CSS assets
  • Bricks Builder: Regenerates builder assets
  • Thrive Architect: Triggers content regeneration

What Gets Migrated

Free version (all plans)

  • Post title, slug, content, and excerpt
  • Post status (published, draft, scheduled)
  • Post date and modified date
  • Author attribution
  • Featured image
  • All images embedded in the post content
  • Post meta (all key-value pairs)
  • Categories and tags (with full hierarchy)
  • Parent-child relationships for hierarchical post types
  • Comment status and ping status

Pro adds

  • Custom Post Types: Any registered CPT, including WooCommerce Products, portfolio items, events, and anything else
  • Advanced Custom Fields: All ACF Free and ACF Pro field types — repeaters, flexible content, image fields, gallery fields, and relationship fields
  • Yoast SEO: Meta titles, meta descriptions, focus keywords, canonical URLs, OpenGraph data, Twitter Card data, and schema markup
  • WooCommerce Products: Pricing, SKU, stock status, weight, dimensions, product images and galleries, attributes, and product variations
  • Custom Taxonomies: Any taxonomy registered by themes or plugins
  • Page Builder CSS: Auto-regenerated on the destination after each migration

Settings Reference

Go to Migro → Settings. All settings are visible to site admins only.

Environment

  • Site Environment — Staging or Production. Tells Migro what role this site plays and controls Quick Migrate button labels.

Migration defaults

  • Default Conflict Strategy — Pre-selected conflict resolution for new migrations. Default: Overwrite.
  • Quick Migrate Conflict — Conflict strategy used by Quick Migrate. Default: Overwrite.

Logs

  • Log Retention (days) — How long migration logs are kept before automatic cleanup. Default: 30 days.

Advanced

  • Request Timeout — Time to wait for remote responses before failing. Default: 30 seconds.
  • SSL Verification — Verify SSL certificates on remote requests. Only disable for local development.

Developer Hooks & Filters

Migro exposes filters and actions so you can extend or customize its behavior from your theme or a custom plugin.

Filters

filters
// Add or remove supported post types
add_filter( 'migro_supported_post_types', function( $post_types ) {
    $post_types[] = 'my_custom_type';
    return $post_types;
});

// Override which migration engine class is used
add_filter( 'migro_migration_engine_class', function( $class ) {
    return 'My_Custom_Engine';
});

// Disable SSL verification (local development only)
add_filter( 'migro_ssl_verify', '__return_false' );

// Change the admin menu title
add_filter( 'migro_admin_menu_title', function() {
    return 'Deploy Content';
});

// Modify the features list shown in the UI
add_filter( 'migro_migration_features', function( $features ) {
    $features[] = 'my_feature';
    return $features;
});

Actions

actions
// Runs after the plugin activates
add_action( 'migro_plugin_activation', function( $plugin_basename ) {
    // your code here
});

// Runs after the plugin deactivates
add_action( 'migro_plugin_deactivation', function() {
    // your code here
});

// Register additional classes or extensions
add_action( 'migro_load_extensions', function( $plugin ) {
    // register your extension
});

// Register custom REST API endpoints
add_action( 'migro_register_rest_endpoints', function() {
    // register_rest_route(...)
});

// Add steps to the setup wizard
add_action( 'migro_setup_wizard_after_welcome', function( $step ) {
    // render additional wizard content
});

AJAX endpoints

These endpoints are available for custom integrations. All require a valid nonce and edit_posts capability.

  • migro_test_connection — Test database and API connectivity
  • migro_load_content — Load available posts from the remote or local site
  • migro_start — Begin a migration
  • migro_get_logs — Fetch migration log entries
  • migro_get_post_types — Get available post types
  • migro_quick_migrate — Trigger a Quick Migrate for a single post
  • migro_get_backups — List available backups
  • migro_restore_backup — Restore a backup
  • migro_delete_backup — Delete a backup

Troubleshooting

Connection issues

  • Database connection failed: Re-verify your database host, username, password, and port. Ensure your database server's firewall allows remote connections from your local/staging IP.
  • REST API connection failed: Confirm the Site URL includes https:// or http://. Application passwords require WordPress 5.6+ with SSL enabled on standard setups.

Migration issues

  • Images not migrating: Ensure the source site is accessible via public HTTP and the target site's wp-content/uploads/ directory has write permissions (755).
  • Missing content blocks: Use Overwrite (not Skip) for existing articles to ensure content is updated.

Debug Mode

To enable granular logging, add the following to your wp-config.php:

wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

Check /wp-content/debug.log for API calls and database SQL execution from Migro.

Still stuck?

Email us at support@migro.dev with your debug log attached. Pro users get priority response.

FAQ

Do I need to install Migro on both sites?

Yes. Migro needs to be active on both the staging and production site.

Does Migro work with multisite?

Migro is designed for single-site installations. Multisite support is not currently available.

What happens to images that already exist on the destination?

Migro uses MD5 hashing to detect duplicate images. If an identical image is already in the destination's Media Library, Migro links to the existing attachment instead of uploading a copy.

Can I migrate from production to staging?

Yes. Pull and Push work in both directions. You can pull content from production into staging just as easily as pushing from staging to production.

Will migrating a post update its URL on the destination?

Migro preserves the original slug. The URL on the destination will match the URL on the source site, unless the permalink structure differs between environments.

Does Migro migrate users?

No. User accounts are not migrated. If a post author does not exist on the destination, the post is assigned to the admin who ran the migration.

Is my database password stored securely?

Database passwords are encrypted before being saved to the WordPress options table. They are never stored or transmitted in plain text.

What if the migration fails halfway through?

Each item is migrated independently. If one item fails, the others continue. The Logs page shows exactly which items succeeded, which were skipped, and which failed with an error message.

Does Migro handle WooCommerce product variations?

Yes. Variable products and all their variations are fully migrated including pricing, stock, attributes, and images. This requires the Pro version.

Can I use Migro with a staging environment on a different server?

Yes, as long as you have the remote site's database credentials and can create an Application Password on that site.

Question not answered?

Email us at support@migro.dev. Pro users get priority response.