Skip to content
GWP Book a demo

Verify and troubleshoot

Do this in a real browser on a real basket page.

You can test the whole path with no code change at all: open your basket page, open DevTools → Console, and paste this. It loads the real production bundle with verbose logging on.

(() => {
window.GWP_DEBUG = true; // verbose boot logging
const s = document.createElement("script");
s.async = true;
s.src = "https://cdn.gwpingenuity.com/w.js";
s.setAttribute("data-site", "YOUR_SITE_KEY");
document.body.appendChild(s);
})();

Every line is prefixed [GWP debug]. This only works on a page where the tag is not already installed. The loader boots once per document, so a second copy is a no-op.

  1. The bundle loads. DevTools → Network, filter w.js. Expect 200 from cdn.gwpingenuity.com. A CSP violation in the Console instead means Content Security Policy.

  2. Config resolves. Filter v1/config. Expect 200 and a body whose config.pageType is "basket" and whose config.offers is non-empty.

    • "config": null → wrong, unknown or paused site key, or a kill switch.
    • pageType absent → your basket URL is not in the patterns (page registration).
    • offers: [] → nothing live is assigned to you yet; talk to us.
  3. The widget mounted. In the Console:

    document.querySelectorAll("[data-gwp-widget]").length // → 1

    That element is our shadow host. In the Elements panel it shows a #shadow-root (closed). One is correct on any page; more than one is a bug. Tell us.

  4. The accessor exists.

    typeof window.GWP.selection // → "function"
    window.GWP.selection() // → { gifts: [] } before you pick anything
    Object.keys(window.GWP) // → ["selection"] and nothing else
  5. Watch a selection happen.

    document.addEventListener("gwp:selection", (e) => console.log("GWP", e.detail));

    Pick a gift in the widget. Expect one log with a gifts array of length 1, and a POST /v1/select returning 200 with a clid. A 403 on /v1/select means the hostname in your browser's address bar is not on your registered-domains list: the widget still renders, nothing is recorded. On a production hostname, send us the domain. On localhost or a dev machine, that 403 is expected and local development tells you how to work around it.

  6. It persists. document.cookie now contains gwp_ses and gwp_sel, and localStorage has the same keys. These are first-party on your own domain.

  7. Cart rules apply. Drop the basket below your configured minimum: the widget unmounts and the selection is dropped. Raise it again: it returns. If it does not unmount, your adapter is probably not reading. See cart adapters.

  8. The confirmation leg. Complete a test order. On the confirmation page expect the redemption card, a POST /v1/associate returning 200 with your real order id, and, on clicking Claim, a POST /v1/clickout followed by a redirect to the partner carrying the click id in the query string.

  9. The dashboard agrees. Your GWP dashboard → Install shows "Detected & healthy" once both a basket and a confirmation load have been seen. "Detected on basket only" means the confirmation leg has not reported yet.

Prove the no-op case too. Load a product page and a category page with the tag present and confirm the widget renders nothing, logs nothing to your error tracker, and adds no console noise.

Turn on window.GWP_DEBUG = true before the tag executes (add <script>window.GWP_DEBUG=true</script> immediately above the tag on a staging build) and read the [GWP debug] lines. They are written to say exactly which gate refused.

Symptom / debug lineCauseFix
No [GWP debug] lines at allThe bundle never executed.Check Network for w.js; check for a CSP violation (Content Security Policy); check the tag is actually in the rendered HTML.
missing site-key or API base → not bootingNo data-site on the tag, or the src origin is wrong.The attribute is data-site, on the same <script> element as src.
no config returned — unknown/paused/kill-switched site-key, or non-eligible page → render nothingWrong, unknown or paused site key (or a kill switch).Confirm the key from your dashboard. This line is not the URL-pattern case (see the next row for that).
page type "(other)" is not basket/confirmation (check page-type URL patterns) → nothingThe pathname does not match your basket/confirmation patterns, or an exclusion (!*/pages/*) caught it.Add an anchored pattern for your real path (page registration). Remember matching ignores query and hash.
cart read: FAILED (adapter couldn't read the cart)The adapter cannot see your cart.Cart adapters. Common causes: value sent as a string to the window adapter; the dom selector matching nothing; a dataLayer created after boot so the push wrap was never installed.
not eligible → nothing (no offers, cart below min, or frequency cap hit)Cart under minCartValue, no live offers, or perSessionCap/perDayCap already spent.Raise the basket; check offers are assigned; clear gwp_shows from both localStorage and cookies to reset caps while testing.
all offers below their minimum cart value → nothingEvery offer has its own minimum above the current cart.Raise the basket.
no explicit slot and no fallback anchor found → fail closed (will retry on DOM changes)The configured selector matched nothing and no fallback anchor was found.Add <div data-gwp-slot></div> to the template. That is the reliable fix.
confirmation page but no persisted selection to redeem → nothingCorrect behaviour: this shopper never picked a gift.If a selection was made, check the basket and confirmation pages share a registrable domain and that cookies are not blocked.
consent denied (CMP) → nothing (no storage written) / …has not answered the banner yet / strict consent mode: no explicit CMP grant → fail closedThe CMP gate.Accept the banner, or review consentMode with us.
config fetch transiently failed (429/5xx/network) — keeping current state, will retryTransient.No action; it retries. Persistent → tell us.
Widget renders, but nothing appears in reporting/v1/events and /v1/select are origin-checked and returning 403.Register the exact domain(s) you serve from: the hostname only, no scheme or port. If you are on localhost or a preview host, see local development.
Widget appears twiceTwo mount points matched, or a stale container from an old bundle.Make the selector match exactly one element. If it persists, tell us.
Widget appears inside a hidden/closed drawerThe openWhen selector is true while closed.Re-verify root.matches(openWhen) in both states (cart drawers).
Gifts shown on a basket below your minimumThe cart read is failing, and the minimum gate is skipped on an unreadable cart (fail-open).Check cart read: in the debug log and fix the adapter (cart adapters).

If none of these fit, capture the [GWP debug] output, the /v1/config response body, and the URL, and send them to us at support@gwpingenuity.com, with [INTEGRATION] in the subject. The widget also reports its own uncaught errors to /v1/error with the message, stack, and the page's origin + pathname (no cart contents, no DOM, no personal data), so we may already be looking at it.