How-toAugust 26, 2026 9 min read

    How to Move a WordPress Site From Staging to Live

    The copying is routine; the URL rewrite is what breaks sites. Here is why find-and-replace corrupts page-builder layouts, the two URL forms most tools miss, and the safe order to migrate in.

    By WP MegaManager Team

    Moving a WordPress site from staging to live means copying two things — the database and the files — and then rewriting every reference to the old domain so the new one works. The copying is routine. The rewrite is where migrations break, and the reason is not obvious: WordPress stores some of its most important settings in a format that records the length of every value, so a plain find-and-replace corrupts them silently.

    This guide covers what actually breaks, why, and the safe order to do it in.

    What a staging-to-live migration involves

    PartWhat movesRisk
    DatabasePosts, pages, options, widget config, builder layoutsHigh — this is where URLs hide
    FilesThemes, plugins, uploadsLow — a straight copy
    Domain rewriteEvery stored occurrence of the staging URLHighest
    Live site's own dataOrders, form entries, new users since the forkDestroyed unless preserved

    That last row is the one people discover too late. A staging build is a snapshot of the site as it was when the fork happened. Everything the live site collected since then — orders, form submissions, comments, new registrations — is not in that snapshot. Pushing staging over live deletes it. A shop is rarely a safe candidate for a full push.

    Why find-and-replace corrupts WordPress sites

    WordPress stores widget settings, theme mods, and page-builder layouts as PHP-serialized data. Serialization writes the byte length of every string alongside it:

    s:29:"https://staging.example.com/"
    

    The 29 is a promise: the next value is exactly 29 bytes. Replace staging.example.com with example.com using a text editor or a SQL REPLACE() and you get:

    s:29:"https://example.com/"
    

    The string is now 21 bytes, but the record still claims 29. PHP's unserialize() refuses the whole structure and returns false. WordPress receives nothing where it expected an array of settings, and falls back to defaults.

    This is why Divi and Elementor modules come back blank after a manual migration. The layout was not deleted; it became unreadable. The same failure hits widget areas, theme customizer settings, and any plugin storing arrays in wp_options.

    A correct rewrite decodes the structure, replaces inside it, and re-encodes — so the lengths are recalculated rather than invalidated.

    Two forms people miss

    Even a serialization-aware replace fails if it only looks for the plain URL. Two other encodings appear in real databases:

    • JSON-escaped — page builders storing layouts as JSON write https:\/\/staging.example.com. The forward slashes are escaped, so a search for https:// never matches.
    • Protocol-relative//staging.example.com/image.jpg, common in theme options and hard-coded asset paths.

    Both need handling in the same pass.

    Methods compared

    MethodSerialization-safeEffortGood for
    Export/import via phpMyAdmin + text editorNoHighNothing — this is the one that breaks builders
    SQL REPLACE() queryNoLowPlain text only, never options
    WP-CLI search-replaceYesMediumDevelopers with SSH access
    Migration plugin (Duplicator, All-in-One WP Migration)UsuallyMediumOne-off single-site moves
    Management platform with transferYesLowAgencies moving sites regularly

    If you have shell access, wp search-replace 'staging.example.com' 'example.com' --all-tables is the reliable free answer — WP-CLI handles serialized data correctly. Add --dry-run first to see the count before committing.

    The safe order

    1. Back up the live site first, not the staging one. The destination is the thing you can lose. A migration that fails before this step has changed nothing; one that fails after it is recoverable. Everything else in this list is reversible only because of this backup.
    2. Check what live has collected. Orders since the fork, form entries, new users. If any exist, decide explicitly whether they are being discarded or need to be merged back afterwards.
    3. Copy the database and files from staging.
    4. Rewrite URLs with a serialization-aware tool, covering the plain, JSON-escaped and protocol-relative forms.
    5. Preserve anything the live site must keep — licence keys, analytics IDs, SMTP credentials, and any plugin paired to the live domain. These live in wp_options and will be overwritten by the staging copy unless you snapshot and restore them.
    6. Flush caches and permalinks. Visit Settings → Permalinks and save once; object and page caches should be cleared at the same time.
    7. Verify before announcing. See the checklist below.

    Post-migration checklist

    • Home page, a blog post, and one page built with your page builder — all rendering correctly
    • Widget areas and menus populated, not empty
    • Media library images loading (broken thumbnails mean the uploads path or URL rewrite missed something)
    • Contact form submitting and delivering
    • Checkout completing, if it is a shop
    • site_url and home in Settings → General pointing at the live domain
    • No staging URLs left: search the database for the old domain and expect zero rows
    • Search Console: the live domain still indexed, no sudden noindex (staging sites usually carry Discourage search engines — this setting migrates with the database and will de-index a live site overnight)

    That last one deserves its own warning. The single most common post-migration disaster is not a broken layout — it is the staging site's "discourage search engines" flag arriving with the database. Check Settings → Reading immediately.

    Frequently asked questions

    Can I just copy the wp-content folder? No. Content, settings, menus and layouts live in the database, not in files. Files alone move themes and uploads and nothing else.

    Does the live site keep its SSL certificate? Yes — certificates are attached to the domain and server, not to the WordPress database, so they are unaffected by a migration.

    What if the two sites use different table prefixes? Most migration tools do not translate prefixes. Match them before migrating, or you will get a database WordPress cannot read.

    How do I undo a migration that went wrong? Restore the backup of the live site taken in step 1. This is the only reliable undo, and it is why that step is first.

    Doing this regularly

    If you rebuild client sites on staging as a matter of course, the manual version of this gets expensive — and every manual run is another chance to skip the backup.

    WP MegaManager's site transfer runs the whole sequence in a fixed order: it backs up the destination first, copies the source, then rewrites the URLs with a serialization-aware pass that handles the escaped and protocol-relative forms too. The destination keeps its own connection to the platform rather than inheriting the source's identity, and undo is a normal restore from the destination's backups. The full procedure is documented in Transferring a site.

    Manage all your WordPress sites from one dashboard

    Bulk updates, cloud backups, uptime monitoring, security and AI automation — in one place.

    Start Free Beta