Developing locally, and on staging
Everything else in this guide assumes a hostname we know about. Do it on http://localhost:3000 unprepared and you get a confusing half-working state, so here is the whole story.
What the check actually does: browser POSTs carry an Origin header, we reduce it to its hostname (the scheme and port are discarded) and allow it if that hostname exactly equals one of your registered domains, or is a subdomain of one. So the string to care about is:
location.hostname // exactly this string is what we allow-list — // the scheme and the port are not part of the checkOption A: a subdomain of a domain you have already registered
Section titled “Option A: a subdomain of a domain you have already registered”Prefer this one. Point a name under your real domain at your own machine and browse there instead of localhost:
# /etc/hosts (Windows: C:\Windows\System32\drivers\etc\hosts)127.0.0.1 dev.example.comhttp://dev.example.com:3000 resolves to hostname dev.example.com, which your existing example.com entry already covers. Subdomains are automatic, and the port is irrelevant. Nothing to ask us for, and nothing to remember to remove afterwards.
It is also the more faithful rehearsal. localhost is a single-label hostname with no registrable domain, so the widget's cookie carrier silently does nothing there and only localStorage is written. A plain-localhost run therefore cannot exercise the basket → confirmation hop the way production does. On dev.example.com both carriers work.
Option B: register the dev hostname
Section titled “Option B: register the dev hostname”If Option A is not workable, add the hostname to your registered domains: dashboard → Settings → Allowed domains, or ask us. Write it exactly as location.hostname reports it (localhost, 127.0.0.1, dev.local) with no scheme, no port, no path. A staging storefront is the same job: register its hostname and it behaves like production.
What is the same locally, and what is not
Section titled “What is the same locally, and what is not”| The bundle and the API | Identical. You develop against production: there is no sandbox environment we hand out today. data-api exists for GWP-supervised testing only. Do not set it. |
|---|---|
| HTTP instead of HTTPS | Fine. Cookies are simply written without the Secure attribute. |
| Ports | Ignored by the origin check. :3000, :8080 and :443 are the same hostname. |
| Page detection | Your live patterns, matched on the pathname only, so http://dev.example.com:3000/cart derives basket exactly as production does (page registration). |
| Offers | Your live offers. A local basket shows the same gifts a real shopper would see. |
document.cookie on plain localhost | Carries no gwp_* keys: there is no registrable domain, so the cookie half of verify step 6 is expected to be empty there. The localStorage half still holds. |
| Reporting | Once the hostname is registered, your test impressions, selections and clickouts are recorded against your real store. Expect your own testing to appear in your dashboard figures. |
| The claim leg | Real. A claim click posts a real click-out and sends you to the partner's live redemption URL. Treat a local "test claim" as a real one. |
While you are testing, gwp_shows will spend your frequency caps like any shopper's. Clear it from both localStorage and cookies to reset them (troubleshooting).
Where next
Section titled “Where next”- Verify and troubleshoot — the checks to run once the hostname resolves.
- Config, CSP and device storage — the full list of
gwp_*keys you will be clearing.