How to set up a WordPress staging site
A staging site is a private copy of your site at its own address, for trying changes before visitors see them. Use your host's staging tool if there is one, a plugin if not, or copy the site to a subdomain by hand. Then stop the copy from emailing customers or taking payments.
- By
- WP Ministry
- Published
- Tested on
- WordPress 7.1.3, PHP 8.3.35
In short
- A staging site is a copy made at one moment. It is a place to test, not a backup.
- Your host's own staging tool is the least work. A plugin or a hand-made copy on a subdomain does the same job.
- A copy holds your real customers and your real settings. Stop its email and put its payment gateways in test mode before you try anything.
- Keep the copy behind a password. The search engine setting in WordPress is only a request.
- Pushing the staging database to the live site replaces everything that arrived since the copy was made, orders included.
- Send files from staging to live. Repeat changes to settings on the live site by hand.
A staging site is a private copy of your site: the same files and the same database, at a different address that only you can open. You apply an update, try a new plugin or change the design there first. If something breaks, it breaks where no visitor or customer sees it.
The copy is taken at one moment. From then on the two sites drift apart: the live site keeps receiving orders, comments and edits, and the copy does not. That is why a staging site is not a backup, and why sending changes back to the live site needs care.
Three ways to get one
| Way | Good when | Sending changes back |
|---|---|---|
| Your host's staging tool | Your hosting plan includes one | Usually a push from the host's control panel |
| A staging plugin | Your host has no staging tool | By hand, or with the plugin's paid version |
| By hand on a subdomain | You have SSH access and are comfortable on a command line | By hand |
Your host's staging tool
Start here. A host's tool makes the copy for you, gives it an address, and can usually refresh it from the live site and push it back. Look for "staging" in your hosting control panel or in your host's documentation.
Before you rely on it, find out three things from that documentation: whether the copy is hidden from search engines, whether it can still send email, and what a push to live overwrites. Do not assume a host's copy is quiet. It may email customers and take payments like any other copy, so the section on keeping the copy private applies to it too.
A staging plugin
WP STAGING is a staging plugin in the WordPress.org directory. Its free version clones the whole site into a subfolder of the live one, such as example.com/staging-site. Its listing says only administrators can open the clone, and that it handles the no-index setting for search engines.
The paid version adds a clone on a subdomain or in a separate database, and a push from staging back to live. With the free version you carry changes back yourself.
A clone made by a plugin lives on the same server as the live site. It takes about as much disk space again, so check what your plan allows first. Make the clone at a quiet hour, because copying a large site uses the server's resources while it runs.
By hand on a subdomain
This needs SSH access and WP-CLI. The steps are for a single site, not a multisite network. The addresses and names below are examples.
Step 1: Create the subdomain and an empty database
In your hosting control panel, add a subdomain such as
staging.example.comwith its own folder, switch HTTPS on for it, and create a new database with its own user.Step 2: Copy the files
Copy everything in the live site's folder into the subdomain's folder, hidden files such as
.htaccessincluded.Step 3: Export the live database
Run this in the live site's folder. It writes the whole database to one file. The
~/puts that file in your account's home folder and not in the site's folder, where anyone could download it.bashwp db export ~/live-copy.sqlStep 4: Point the copy at the new database
Run these in the staging folder. They change the copy's
wp-config.phpand nothing else. The last line prints the database name, so you can see it is the new one.bashwp config set DB_NAME staging_database wp config set DB_USER staging_user wp config set DB_PASSWORD 'staging-password' wp config get DB_NAMEStep 5: Import the export into the new database
Still in the staging folder:
bashwp db import ~/live-copy.sqlStep 6: Change the address everywhere in the database
Use your addresses exactly as they appear under Settings, then General. Add
--dry-runto the end first to see what would change without changing it. The command handles the serialized data that a plain find and replace would break, and--skip-columns=guidleaves alone a column WordPress says must not change.bashwp search-replace 'https://example.com' 'https://staging.example.com' --skip-columns=guidStep 7: Mark the copy as staging
WordPress knows four environment types: local, development, staging and production. A site that is not told otherwise counts as production. Plugins and themes can read the type and behave differently on a copy.
bashwp config set WP_ENVIRONMENT_TYPE stagingStep 8: Delete the export file
live-copy.sqlholds everything in your database. Remove it from the server once the copy works.
If the copy's wp-config.php defines WP_HOME or WP_SITEURL, change those to the staging address too. They override what is in the database.
Log in at the staging address with your usual username and password.
Keep the copy private and quiet
A fresh copy behaves like the live site. It has the same customers, the same email settings and the same payment keys. Deal with these before you test anything.
- Search engines. Go to Settings, then Reading, and tick "Discourage search engines from indexing this site". WordPress's documentation is plain that this does not block access and that it is up to search engines to honor it.
- A password. Because that setting is only a request, put the copy behind a password as well. Look in your hosting control panel for a way to password-protect a folder or a subdomain, or ask your host.
- Email. The copy will email real people: order notices, password resets, form replies. Install a plugin that stops outgoing mail, such as the free Disable Emails, on the copy only. It stops mail sent through WordPress's own mail function. A plugin that talks to a mail service directly is not stopped, so remove that service's key or password from the copy as well.
- Payments. Switch every payment gateway on the copy to its test or sandbox mode. A copy left with live keys takes real money for test orders.
- Everything else that sends data out. Disconnect the copy from your newsletter service, CRM, stock or shipping system and analytics, so that test orders and test sign-ups do not reach them.
The copy also holds your customers' personal data. Give access to as few people as the live site, and delete the copy when you have finished.
Test on a fresh copy
A copy that is weeks old no longer matches the live site, and a test on it proves less. Refresh or recreate it before each round of work. A host's tool usually has a way to do this, a plugin makes a new clone, and by hand you repeat the export and import.
Then do the work as you would on the live site. Apply updates one at a time, as how to safely update WordPress describes. If a new plugin breaks something, the copy is the place to find the plugin conflict. On a store, place a test order through the whole checkout.
On the Business plan, our update service tests updates on a staging copy first, before they reach the live site.
Send changes back without losing orders
The staging database is as old as the copy. If you push it to the live site, it replaces the live database, and everything that arrived in between is gone: orders, new customers, comments, form entries, posts written since. Hosts' own instructions warn about this.
So treat the two halves of the site differently.
- Files go from staging to live. A plugin or theme update, a template edit and custom code are all files. Push files only, if your host's tool offers that choice. For an update, you can also repeat it on the live site now that you have seen it work.
- Settings and content are repeated by hand. Changes made in the dashboard are stored in the database. Keep notes while you work on staging, then make the same changes on the live site.
- Push the database only when nothing can have arrived. On a site with no orders, comments, sign-ups or stored form entries, and with nobody editing since the copy was made, a full push is safe. Refresh the copy, do the work and push in one sitting.
Some hosts' tools can push chosen database tables. Use that only if you know which tables hold your change, and leave out the tables for orders and users.
Take a backup of the live site before any push, even if your host says it takes one for you. Afterwards, empty the cache and look at the live site as you did on staging.
Common questions
The staging address keeps sending me to the live site. Why?
The live address is still stored somewhere. Run the wp search-replace command again with --dry-run to see whether any rows still hold it. Then look in the copy's wp-config.php for WP_HOME and WP_SITEURL, and in its .htaccess for a rule that names the live domain.
Should I keep the staging site running all the time?
There is no need. An unused copy goes out of date, takes up space and is one more place holding customer data. Make it when you have something to test and remove it afterwards.
Will subscriptions renew twice if I copy a store?
WooCommerce Subscriptions guards against that. It records the address where it was first activated, and on a copy at a different address it switches off automatic payments and subscription emails. Other subscription and membership plugins may not, so check each one's documentation before you copy the store.
Can I test on the live site if I am careful?
For a small change on a site where a broken page costs little, people do. Take a backup first and pick a quiet hour. For a store, a membership site or a major update, a staging copy is worth the extra step.

