Key takeaways
- Use your host’s staging tool if your plan includes one. If not, use a plugin such as WP STAGING, whose free version clones to a subfolder and keeps push-to-live for Pro. Build the copy by hand only if you’re comfortable with databases and WP-CLI.
- WordPress’s ‘Discourage search engines’ setting doesn’t stop anyone from opening the site. Password-protect the copy. Don’t also block it in robots.txt, because that stops Google from reading a noindex tag.
- A clone keeps live payment keys, outgoing email, cron jobs and webhooks. Switch gateways to sandbox mode and turn off outgoing mail before anyone places a test order.
- Kinsta’s docs warn that a full database push can lose purchases, comments, sign-ups and new content added since the copy was made. For plugin updates, test on staging and then run the same update on live.
Most hosts and plugins can copy a WordPress site to a staging URL in a few minutes. The problems come afterwards. Anyone who finds the copy can open it. It still holds your live payment keys and email settings. And pushing it back to live can erase every order, comment and sign-up that came in while you were testing.
This guide covers the three ways to create the copy, the four things to lock down before you test on it, and how to deploy back without overwriting live data. Before you start, take a fresh backup of the live site and make sure you can actually restore that WordPress backup. Staging is for testing. It doesn’t replace a backup.
Which staging method fits your site
Use your host’s tool if your plan has one. If it doesn’t, or the tool fails on your site, use a plugin. Build a copy by hand when you need full control or nothing else works. That order comes up again and again in practitioner threads, and it also matches how much can go wrong with each method.
| Method | Access you need | Good fit | Watch out for |
|---|---|---|---|
| Host staging tool | Hosting dashboard login | Managed WordPress plans that include staging | Only on some plans. Can fail on individual sites. Resources and caching may differ from live. |
| Staging plugin | WordPress admin | Shared hosting without a staging button | Runs on your live site’s disk, PHP and database. Push to live is often a paid feature. |
| Manual copy | SSH or file manager, plus database access | Developers who want a separate database and subdomain | Slowest method, and the easiest to get wrong. A careless search-replace breaks settings. |
How to create the staging copy
With your host’s staging tool
Look in the hosting dashboard for “Staging”, “Environments” or “Clone”. On Kinsta, for example, you go to Sites, open the live environment and choose Create new environment, then pick the clone option. Most hosts put the copy on its own subdomain and connect it to a separate database for you, so this is the quickest route.
If the tool fails on one site but works on others, try a plugin instead of running the same clone again. Repeating a clone without changing anything usually fails the same way.
With a staging plugin
With WP STAGING’s free version, go to WP Staging, then Staging Sites, then Create New Staging Site. Give it a name and start the clone. The copy lives in a subfolder of your domain, such as /development. By default its tables sit in your existing database under a separate prefix.
That shared database keeps the copy separate in software, but not physically. Subdomain clones, a separate database and pushing to live are Pro features. Long-time users say this kind of plugin works best on small, clean sites, and that large sites sometimes need a manual search-replace after the clone.
By hand
- Create a subdomain such as
staging.example.comin your hosting panel. - Copy the WordPress files into the subdomain’s folder, including all of
wp-content. - Export the live database. Create a new, empty database with its own user, and import the export into it. Don’t reuse the production database credentials.
- Edit the staging
wp-config.phpso it points at the new database and labels the environment:define( 'DB_NAME', 'example_staging' ); define( 'DB_USER', 'staging_user' ); define( 'WP_ENVIRONMENT_TYPE', 'staging' ); - Replace the live URL with the staging URL using a tool that understands serialized data. Run it once with
--dry-runto preview the changes, then run it again without that flag to apply them:wp search-replace 'https://example.com' 'https://staging.example.com' --skip-columns=guid --dry-run - Password-protect the subdomain before anyone else logs in.
Step 5 is where most hand-built copies break. WordPress stores some settings as serialized PHP, and the stored value includes each string’s length. If you swap a URL in phpMyAdmin, the length no longer matches and widgets or options stop loading. WordPress’s migration handbook also says to leave the guid column alone. If those IDs change, feed readers can show old posts as new.
Lock the copy down before you test anything
A fresh clone is a working copy of your live site. It can do anything live can do: send email, charge cards and fire webhooks. Make these four changes before anyone uses it.
Put a password in front of it. WordPress’s own documentation says that Settings → Reading → “Discourage search engines from indexing this site” asks search engines not to index the site. It doesn’t stop anyone from visiting it. Real access control means server-level password protection (basic auth), which shows a login prompt before WordPress even loads. Our guide to adding password protection to a site covers the options. Don’t also disallow the copy in robots.txt. Google’s documentation says a crawler blocked by robots.txt can’t read a noindex tag, and the blocked URL can still show up in search results.
Switch payments to sandbox. Set every payment gateway to test or sandbox mode. WooCommerce’s documentation says test orders can trigger order emails and appear in analytics like real orders, and that other integrations may not be able to tell them apart from real ones.
Stop outgoing mail and integrations. Turn off outgoing email on the copy. If you send mail through an SMTP provider’s API, remove or change the API key there too, because some plugins that block WordPress mail don’t stop mail sent through the provider. Check webhooks to fulfillment, accounting and CRM tools. In one wordpress.org support thread, a copied database still had live API and webhook access.
Handle WooCommerce Subscriptions. Subscriptions decides it’s on a staging site by comparing the current URL with the URL it stored when it was first activated. So activate it on live before you clone, then check the mode under WooCommerce → Status. In staging mode it skips payments and subscription emails, but scheduled renewals and events still run. Make sure the live site answers on only one URL. If it works on both www and non-www, Subscriptions can mistake the live site for staging.
Setting WP_ENVIRONMENT_TYPE to staging helps too, but only as a label. WordPress recognizes local, development, staging and production, and plugins can read the value. That tells everyone which site they’re looking at. It doesn’t stop a plugin that ignores the label from sending mail.
What a working staging copy looks like
Open the homepage, a post, a product page and the login screen. Every page should load on the staging address, with the same theme, plugins and content as live. Click the main menu and two links inside page content. If any of them opens the live domain, the search-replace missed something.
On a store, place one order in sandbox mode and take it through to the thank-you page. Then check the live order list. It should not have gained an order. Your inbox should get the test email only if you redirected mail to yourself. No customer address should receive it.
Then test the actual change. Do one thing at a time, in this order: core, then theme, then plugins. That way, when something breaks, you know which change caused it. For store updates, WooCommerce’s update guide lists what to check: product pages, cart, checkout, payments, shipping, taxes, order emails and any extensions you rely on.
When the clone fails: the usual causes
The clone stalls partway or times out. The site is too big for the PHP execution time limit, or a large table such as orders or analytics logs is slowing it down. Ask your host to raise the limit, or lower the plugin’s batch size. You can leave out log tables, but don’t leave out anything your test needs.
A memory error. In one wordpress.org support thread, a clone failed because WordPress’s own memory limit was 40 MB even though PHP allowed 256 MB. Adding define( 'WP_MEMORY_LIMIT', '256M' ); to wp-config.php raises WordPress’s limit.
The copy redirects to live, or every page except the homepage returns 404. Check the siteurl and home values in the copy’s options table. Then go to Settings → Permalinks and click Save Changes. Next, look at .htaccess or the Nginx config, then at caching, SSL, redirect and security plugins.
A blank page or “critical error” after a clone that reported success. Turn on debug logging and read wp-content/debug.log. It usually names a theme or plugin file. Make sure the copy runs the same PHP version as live before you start deactivating plugins.
The plugin can’t use a separate database. WP STAGING can’t create the database itself. Create it first, and give its user the CREATE, INSERT and ALTER privileges.
How to move tested changes to live without losing orders
A full database push replaces data. It doesn’t merge it. Kinsta’s push documentation warns that a full push can lose purchases, comments, new content, sign-ups and forum posts added since you made the staging copy. On r/woocommerce, one store owner reported duplicated and reset order numbers after pushing from host staging. WordPress has no built-in way to merge two databases that have both changed, so the safe approach is to pick the method that fits the kind of change.
| Change you tested | How to deploy it |
|---|---|
| Plugin, theme or core update | Don’t push anything. Run the same update on live, then recheck. |
| Theme files or custom code | Push files only. |
| A new plugin or a settings change | Install it or change the setting on live by hand. Files don’t carry database settings. |
| A redesign with new pages | Pause content edits on live, push only the tables you’ve named, and never push orders, users or comments. |
A files-only push has its own limit. Kinsta notes that pushing files doesn’t create a new plugin’s database tables, and dashboard settings are usually stored in the database. Avoid the opposite mistake too: don’t push the whole database just to carry over one setting.
If you push database tables to a store, first find out where the store keeps its orders. Stores using High-Performance Order Storage keep orders in their own wc_orders tables. Older stores keep them in wp_posts and wp_postmeta, mixed in with your pages. If you can’t name every table a push will overwrite, don’t run it.
For updates, the test-then-repeat approach is the simplest safe option on a busy site, because it never touches the live database. If you would rather hand the update cycle off, the plugin updates and maintenance page explains how SiteSelf reviews, applies and checks updates on request.
Four checks on the live site after a deploy
- Search visibility. Open Settings → Reading on live and make sure “Discourage search engines” is unticked. That setting is stored in the database, so a push can bring it over from staging and leave production hidden from search.
- Protections. Kinsta says
.htpasswdfiles and some bot-protection settings don’t transfer in a push. Check that live still has the protections it had before. - Money paths. Make sure the gateways are back in live mode on production. Run through checkout up to the payment step, and confirm today’s orders are still in the order list.
- Links and redirects. Click the menu, a few in-content links and any redirects you rely on. None should point at the staging address.
Once the work ships, delete the staging copy or lock it away. An unmaintained clone of your site is another login page for attackers to find, and it falls further out of date every week. If something did go wrong, restore the backup you took before the deploy instead of editing live tables under pressure. Our guide to restoring WordPress from backup covers that.
Frequently asked questions
Can I create a WordPress staging site for free?
Often, yes. Many hosting plans include staging, WP STAGING’s free version makes subfolder clones, and you can always build one by hand. What free options usually leave out is the push back to live. With WP STAGING, that’s a Pro feature.
Should staging be on a subdomain or a subfolder?
Both work. A subdomain keeps the copy’s address and rewrite rules separate from live. A subfolder copy can clash with the root .htaccess rules and cause wp-admin problems. Neither is clearly safer. Choose the one your tool supports and protect it the same way.
How do I refresh a staging site that has gone stale?
Use your host’s pull, refresh or clone-from-production option, or make a new clone with the plugin. Staging doesn’t update itself when live changes. Refreshing replaces whatever is on the copy, so export any unfinished work first. Refresh just before your final test, not weeks earlier.
Do I need staging for simple content edits?
Usually not. Text and image changes are easier to make on live, and WordPress keeps post revisions so you can roll them back. Staging is for updates, design changes, new plugins and anything that touches checkout.
Can I test checkout on a local copy instead?
You can test layout and code locally. Checkout is different. Payment gateways, webhooks, email and SSL usually need a public URL to behave like they do on live, so test them on online staging with the gateway in sandbox mode.
Can deleting a staging site break the live site?
It shouldn’t if the copy uses its own database. Plugin staging that shares the live database deserves more care. One r/Wordpress user reported a live “Error establishing a database connection” after deleting a staging site made with a one-click installer, although the cause was never confirmed. Take a backup before you delete.