Developer docs
WordPress plugin
The DeploySeal plugin for WordPress and WooCommerce renders the widget tag in the <head> of the public site with the environment's key, a declared environment label, a build marker and its own installer stamp (data-ds-installer) — and nothing else. It does not change your pages, your checkout or your data; it exists so that the readiness report can prove which environment and which build your testers were on, and, with an API key, which plugins and themes were installed. It never loads on the login page, loads in wp-admin only if you ask it to, and is open source under the MIT licence.
<script src="https://cdn.deployseal.com/ds-widget.js" data-ds-site-key="ls_••••••••••••••••••••••••••••••••••••" data-ds-environment="staging" data-ds-build="7.1.2+twentytwentyfive-1.5+a1b2c3d" data-ds-installer="wordpress-plugin/1.0.0" async ></script>
Requirements
| Supported | Notes | |
|---|---|---|
| WordPress | 6.0 or newer | Verified end to end on 7.1.2 |
| PHP | 7.4 or newer | Checked on 7.4, 8.1 and 8.3 |
| WooCommerce | Optional | HPOS-compatible; verified with 11.1.2 |
| Multisite | Supported | Network or per-site activation; settings per site |
One zip for every supported version: deployseal-<version>.zip on the releases page. The plugin will also be listed in the WordPress.org plugin directory; until then the releases page is the one place to download from. Source, build scripts and the end-to-end test that drives a real WordPress and WooCommerce in Docker are in the same repository.
Install
- Download deployseal-<version>.zip from the releases page.
- In wp-admin open Plugins → Add New → Upload Plugin, choose the zip and click Install Now. If you deploy files instead, unzip it so that wp-content/plugins/deployseal/deployseal.php exists.
- Click Activate. On a multisite network you can network-activate it; every site still gets its own settings and its own environment key.
- Open Settings → DeploySeal (or the Settings link on the plugin's row).
Configure
The settings page reads paste key, save, confirm: Essentials (the two settings every site needs), a What this site will send panel, and two folded sections, Advanced and Platform inventory, that open by themselves as soon as anything in them is set. Follow the steps once per site.
- In DeploySeal, open your site and create an environment for this WordPress site (for example Staging or Production).
- Copy the environment's public key (it starts with ls_) into the Site key box. Use one key per environment, never one key for everything: a staging copy of the site gets its own.
- In that environment, register the exact origins listed under Origins to register. Matching is exact: scheme, host and port must all agree.
- Tick Enabled, click Save, then open the site once and confirm the environment shows as Live in DeploySeal. If you had pasted a DeploySeal snippet into the theme or a header plugin, remove it now.
Settings
| Setting | What it does |
|---|---|
| Site keydefault: empty | The public key of the DeploySeal environment this site is (ls_…; older ds_ keys still work) — not a secret, because it only works from the environment's registered origins. |
| Enableddefault: off | The master switch: nothing is rendered on the site while it is off. |
| Environment labeldefault: guessed from the Site Address | Under Advanced. The label this site declares itself as (lower-case letters, digits and hyphens, up to 32 characters); it is a declaration, not an identifier, and left empty it falls back to the guess — staging when the host contains staging, uat, test, dev, qa, sandbox, preprod or localhost, otherwise production. |
| Build marker sourcedefault: Automatic | Under Advanced. Automatic uses the DEPLOYSEAL_BUILD constant when wp-config.php defines one, otherwise the WordPress version plus the active theme and its version (7.1.2+twentytwentyfive-1.5), plus the short git SHA when the SHA file can be read. The other options are WordPress + theme version only, Git SHA only (emits nothing when the file cannot be read) and Manual. |
| Git SHA file pathdefault: empty | A file holding the deployed commit SHA (7–40 hex characters on its first line) that your deploy pipeline writes; relative paths resolve from the WordPress root, and wp-content/build-sha.txt is a good place. |
| Manual build markerdefault: empty | Used only when the source is Manual: one token, no spaces, up to 64 characters, changed by hand on every deployment. |
| Also load in the admin areadefault: off | Adds the tag to wp-admin as well, for the rare case where testers need to pin issues in the administration area. The login page never loads the widget, whatever this is set to. |
| API basedefault: https://api.deployseal.com | Where the platform inventory is posted. Leave it as it is unless you self-host DeploySeal. |
| DeploySeal API keydefault: empty | Under Platform inventory. An organisation API key with the Write scope, used only to send the inventory, server to server. A secret: the page never shows it again, an empty box on Save keeps it, and Remove the stored API key deletes it. |
| Send inventory on a scheduledefault: off | Sends the platform inventory every six hours through WP-Cron. Send inventory now works without it. |
Multisite
Settings are stored per site. Network-activate the plugin once, then open Settings → DeploySeal on each site and paste that site's own environment key. Because a DeploySeal environment is one origin list and one key, a network with three sites wants three environments and three keys; each site's Origins to register lists its own address.
What this site will send
This panel is the plugin's statement of fact: what it will emit, computed from the settings as saved. Compare it with the environment in DeploySeal before you rely on either.
- Origins to register — the Site Address and, when it differs, the WordPress Address from Settings → General, as scheme://host[:port]. Register each one exactly as printed. If visitors reach the site on another scheme, host or port, register that too.
- Declared environment label — the label the tag will carry, and the value guessed from the Site Address, so you can see whether your setting or the guess is in force.
- Build marker emitted right now — the exact marker and its source, with the SHA file's resolved path and found and readable or missing or not a valid SHA. This is the value to copy verbatim into the campaign's release identifier.
- Versions — WordPress, the active theme, WooCommerce when it is active, and the plugin.
- Tag that will be rendered — the script tag byte for byte, with a note when the plugin is not yet enabled, so what you see here is what a view-source on the site will show.
Build marker
The build marker answers which code was under test. The readiness report compares the campaign's declared release identifier with the markers observed while testers were on the site: confirmed when one observed marker equals the identifier (case-insensitively) or one is a prefix of the other and the shorter is at least 7 characters — so a short SHA confirms a full one; mismatch when markers were seen and none match; unverified when an identifier was declared but no marker was ever seen. Two or more distinct markers in one campaign raise an amber testing spans N deployments flag.
- Prefer the commit. The simplest hook is one line your deploy writes into wp-config.php: DEPLOYSEAL_BUILD wins over everything else in the default source, and a campaign can then declare the short or the full SHA.
- Or a SHA file. Point Git SHA file path at a file the deploy writes; the marker becomes 7.1.2+twentytwentyfive-1.5+a1b2c3d, or the SHA alone with Git SHA only.
- Otherwise the versions. Without either, the default is the WordPress version plus the active theme and its version — honest, but unchanged between deployments of the same code base, so two deploys a week apart look the same to the report.
- Copy it verbatim. Prefix rules run from the start of the string, so a1b2c3d will not confirm 7.1.2+twentytwentyfive-1.5+a1b2c3d. Declare in the campaign exactly what the settings page shows under Build marker emitted right now.
- One token, no whitespace, at most 64 characters, stable for the life of a deployment and different on every deployment. The snippet placeholder REPLACE-WITH-BUILD-MARKER is never emitted.
The constant
// wp-config.php — written by your deploy pipeline define( 'DEPLOYSEAL_BUILD', 'a1b2c3d4e5f60718293a4b5c6d7e8f9012345678' );
The SHA file
# wp-content/build-sha.txt — written by your deploy pipeline, first line only a1b2c3d4e5f60718293a4b5c6d7e8f9012345678
First line only, 7–40 hex characters; anything else counts as unreadable. Relative paths resolve from the WordPress root. Write the constant or the file as part of the same deploy that copies the code, so the two can never drift.
Origins
Every widget request carries the browser's Origin header, and the API accepts it only if it exactly matches one of the environment's allowed origins: scheme://host[:port], compared case-insensitively after trimming one trailing slash. No wildcards, no subdomain matching, no port or scheme normalisation — https://staging.example.com, http://staging.example.com and https://www.staging.example.com are three different origins. That exactness is what makes the public key safe to ship in HTML.
- An environment is its allowed-origins list — it has no hostname field. The plugin derives the site's origins for you; register them as printed rather than typing them from memory.
- A site reached both with and without www, or through a staging host and a preview host, answers on more than one origin: register each.
- In production an environment with no allowed origins rejects every widget call — the dashboard warns you until you add one.
Platform inventory
“Which plugins, at which versions, were installed when this was tested” is release evidence only the site itself can provide. With an organisation API key (Write scope) stored under Platform inventory, the plugin sends DeploySeal every installed plugin and theme with its version and whether it is active, must-use plugins, the WordPress and PHP versions — WooCommerce and its extensions included — and the build marker in force. The readiness report prints the inventory current at the campaign's testing window and diffs it against the previous sealed version.
{
"platform": "wordpress",
"platformVersion": "7.1.2",
"buildMarker": "7.1.2+twentytwentyfive-1.5+a1b2c3d",
"capturedAt": "2026-09-24T06:00:00.000Z",
"items": [
{ "systemName": "core:wordpress", "name": "WordPress", "version": "7.1.2", "enabled": true },
{ "systemName": "plugin:woocommerce/woocommerce.php", "name": "WooCommerce", "version": "11.1.2", "enabled": true },
{ "systemName": "theme:twentytwentyfive", "name": "Twenty Twenty-Five", "version": "1.5", "enabled": true },
…
]
}- When: the Send inventory now button (the result — HTTP 201 with the count, or 200 already on record when nothing changed — is shown on the page), and every six hours through WP-Cron when Send inventory on a schedule is on.
- How: server to server, never from the browser, to POST /api/v1/sites/{site key}/inventory with the API key as a bearer token. Resending an unchanged list does not grow the record.
- What never leaves the site: settings, users, customers and orders. The inventory is optional: the plugin works fully without an API key.
Troubleshooting
The environment still says Not seen
Work through these in order. Origin mismatch — compare the origins under Origins to register with the environment's allowed-origins list character by character; scheme, host and port must all agree. Plugin not enabled — Enabled must be ticked on Settings → DeploySeal. A page cache — a caching plugin or host cache may still serve pages rendered before you enabled the plugin; purge it once. Key from the wrong environment — a key pasted from Production into a Staging site sends every heartbeat to Production; the site page then shows the mismatch warning below rather than a verified Staging. Only admin pages loaded — the tag is on the public site, not in wp-admin; open a public page once, or turn on Also load in the admin area.
Amber label-mismatch warning on the site page
The label the site declared (Environment label, or the guess when it is empty) does not match the name of the environment the key belongs to. Either the key is in the wrong site, or the guess is wrong for a host that does not look like staging — set the label explicitly under Advanced, or rename the environment. The evidence still lands where the key points; the warning exists to catch a wrong mapping before a campaign relies on it.
The build marker never changes between deployments
Without DEPLOYSEAL_BUILD or a readable SHA file the marker is the WordPress and theme versions, which stay the same across most deployments — so the report cannot tell one deploy from the next. The settings page shows the SHA file's resolved path and whether it was found and readable. Have the deploy write the commit into wp-config.php or the file.
The tag appears twice in the page source
Another install path is also present — a pasted snippet in the theme's header, a header-and-footer plugin, or a tag manager. The tag whose loader executes configures the widget and the second mount is ignored, so nothing breaks — but the two can disagree about the label or the build marker, and the evidence goes to whichever ran. Because the plugin's tag carries data-ds-installer and a pasted snippet does not, the site page shows Two install paths are live on this environment when both are seen within a day. Remove the other one and let the plugin be the only source.
An optimisation plugin rewrites or delays the tag
The plugin enqueues the loader as the script handle deployseal-widget. If a performance plugin combines, defers until interaction or moves scripts to the footer, exclude that handle (or cdn.deployseal.com) from it: the loader must stay a separate async tag in <head>.
Ready to install? Create the environment and copy its key from the site page.
Open your sitesNot on WordPress? The widget reference covers the plain script tag, and the nopCommerce plugin the other platform install path; all of them obey the same contract to the byte.