Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/aryanjasala/staging-guard/archive/refs/heads/main.zipStaging Guard
Stop staging copies from emailing real customers or showing up in Google, and color the admin bar so nobody edits the wrong copy.
Staging Guard with the email log" width="880">
Every agency has a staging story: a copy of the live database goes to staging and emails every customer, Google indexes it, or someone spends an hour editing it thinking it was live. Staging Guard prevents all three on every copy that is not production, and does nothing on the live site.
Features
- Email: blocked, or sent to one test address with the real recipients in the subject. Cc and Bcc stripped
- Always deliver to: addresses and whole domains that still get email, so the team can test real flows
- Email log of the last 50 stopped emails, with bodies only if you turn that on
- Search engines:
X-Robots-Tagheader,noindex, nofollowmeta tag, a blocking robots.txt, no sitemap - Admin bar colored by environment, and
[Staging]at the start of every browser tab title - Production lock: mark the live site once, and every database copy on another domain counts as staging
- Site Health check that warns when email could still reach real people
Install
- Download
staging-guard.zipfrom the latest release. - In WordPress, go to Plugins > Add New Plugin > Upload Plugin, choose the zip and activate it.
Or with WP-CLI:
wp plugin install https://github.com/aryanjasala/staging-guard/releases/latest/download/staging-guard.zip --activate
Needs WordPress 6.6+ and PHP 7.4+. To try it first, the Try in WordPress Playground badge opens a throwaway WordPress in your browser with the plugin and some demo content.
Quick look
Pin the email behavior per environment in wp-config.php, so a database copy cannot change it:
define( 'STAGING_GUARD_MAIL_MODE', 'redirect' ); // block, redirect or allow
define( 'STAGING_GUARD_REDIRECT_TO', 'qa@example.com' );
define( 'STAGING_GUARD_ALLOWLIST', '@youragency.com' );
It decides a copy is not live from WP_ENVIRONMENT_TYPE when that is set, otherwise from the production lock: a hash of the live domain, which survives the search-replace step of a migration.
Screenshots
![]() The coloured admin bar on a staging copy |
Documentation
| Doc | What it covers |
|---|---|
| Reference | Environment detection, constants, the filter and WP-CLI |
| Development | Local setup, commands and tests |
| Contributing | Pull requests, required checks and PR titles |
| Releasing | How merged pull requests become releases |
| Security | Reporting a vulnerability |
| readme.txt | What WordPress.org shows, with the FAQ and changelog |
Project structure
staging-guard.php plugin header and PSR-4 autoloader
src/
├── Plugin.php creates the services, guards load only when not production
├── Settings.php the settings option and allowlist parsing
├── Environment.php environment detection and the production lock
├── Mail/
│ ├── Guard.php who an email may reach
│ └── Log.php the stopped email list
├── Search/Robots.php noindex header and tag, robots.txt, sitemaps
├── Admin/ settings screen, admin bar and tab titles
├── Health/SiteHealth.php the Site Health check
└── Cli/Command.php wp staging-guard
tests/
├── Unit/ PHPUnit
└── e2e/ Playwright specs and the Docker site
.wordpress-org/ screenshots
docs/ reference, development, contributing, releasing
License
GPL-2.0-or-later © Aryan Jasala
