Troubleshooting
The widget is fail-silent by design: when something is off it stays out of your visitors' way and leaves you one console breadcrumb. Here is what that breadcrumb usually means.
Why does the widget render nothing?
Check three things: the public site key in data-sw-key matches the key on your site's settings page, the page's origin is on the site's origin allowlist, and your account is active. The widget is fail-silent by design and never throws into your page; it leaves at most one console.warn breadcrumb. "StageWhisper could not load configuration." means the config fetch failed — usually a wrong key or an origin missing from the allowlist. "StageWhisper could not load." means the widget script itself was blocked, usually by CSP or the network. A paused or canceled account renders nothing with no console output at all.
Why is my Content Security Policy blocking the loader?
A strict policy blocks scripts it does not trust. Add your per-request nonce to the snippet and allow the StageWhisper CDN and API hosts in your script-src and connect-src directives. The Content Security Policy guide lists the exact directives to merge and where the nonce goes for each install variant.
See the Content Security Policy guide for the full directive list and nonce placement.
Why does the widget not load on localhost?
By default a site only accepts origins on its origin allowlist, and localhost is not one of them. Enable the localhost toggle on the site's settings page first — with it on, the widget loads during local development with no snippet changes.
What happens when I reach my plan quota?
Nothing visible. Past the quota, the widget still shows visitors the generic thank-you — submissions are acknowledged silently, and going over quota is never an end-user error. Responses past the limit are not stored, so upgrade your plan if you need every one.
Why is the widget showing stale config?
Widget config is cached for about two minutes, so a dashboard change can take that long to reach visitors. Wait for the window to pass and reload the page — no snippet change or redeploy needed.
Why does the loader look stale after a release?
loader.js is cached for five minutes, so a new widget release can take up to that long to reach every browser. As a support-only escape hatch you can append a ?v= release marker to the loader URL to bypass the cache, but normal installs must keep the stable URL so releases stay centrally controlled.
Why are SPA route changes not detected?
They are — the widget re-evaluates its URL rules on history changes, so client-side navigation is handled automatically with no re-init calls. Keep the loader on the shell page (your root index.html or app layout) rather than injecting it per route, and your rules will follow every navigation.