ReTarget.gg
Operate

Debugging checklist

What to check when the widget doesn't render, impressions don't count, or clicks don't attribute. Five minutes, most problems fixed.

5 min readReviewed Apr 27, 2026

The widget is intentionally quiet on the happy path. Here's how to get it talking when something's off.

Start from the dashboard

Dashboard → Websites → click the site → look at the Visitors panel. A green Live pill means the widget is pinging us; No pings in 24h means the install isn't reaching the API: that's almost always install-side, which we'll cover first.

Symptom: widget never renders

1. Confirm the script tag loads

In your browser's DevTools → Network tab, filter for widget. You should see a single request to https://cdn.retarget.gg/widget.js (or widget-section.js / widget-decline.js) returning 200.

  • 404 → wrong URL. Check the src is exactly https://cdn.retarget.gg/widget.js.
  • Request doesn't appear → script tag never rendered. Check your CMS / framework is outputting it. In Next.js make sure you're using <Script strategy="afterInteractive" /> inside app/layout.tsx and not a Server Component that's been dropped.
  • Blocked by CSP → your Content Security Policy rejected it. Check DevTools → Console for Refused to load the script. Add https://retarget.gg to script-src and https://api.retarget.gg to connect-src.

2. Confirm the decision call

Filter Network for decision. You should see GET /v1/decision?pub=…&website=… returning 200 with a JSON body like { allowed, requestId, country, region, ... }.

  • No decision request at all → the script loaded but didn't find its data-pub / data-website attributes. Check they're on the <script> tag itself, not a parent element.
  • 403 Forbidden → the request Origin doesn't match the domain registered on that website. Either fix the domain in the dashboard or use the correct website's keys for this host.
  • 400 Bad Request → missing or malformed key. Re-copy from the dashboard; keys always start with pk_ / web_.

3. Confirm you're actually blocked

If decision returns { allowed: true }, you're on the allowed side of your geo rule: the widget is correctly staying silent. To see the blocked experience:

Dev-country override (localhost only)
<!--
On localhost (or any host when data-allow-localhost is set), data-dev-country
tells the widget to pretend the visitor is in that country. The flag is
IGNORED on production hosts: use a real VPN there.
-->
<script
src="https://cdn.retarget.gg/widget.js"
data-pub="YOUR_PUBLIC_KEY"
data-website="YOUR_WEBSITE_KEY"
data-dev-country="DE"
data-dev-region="BY"
async
></script>
Curl your decision
curl -sS "https://api.retarget.gg/v1/decision?pub=YOUR_PUBLIC_KEY&website=YOUR_WEBSITE_KEY" \
-H "Origin: https://example.com" | jq

Or use a real VPN (Mullvad, Proton, or any regional VPN). VPNs matter for the full signal: the API resolves the country server-side from the request IP, not from browser locale.

Symptom: blocked, but no offers show

Decision returned allowed: false but the overlay renders a "No offers available in your region right now" card, or the offer grid is empty.

  • No active offers for that country: common during quiet hours or for less-trafficked markets. Switch your VPN to a major market (US / UK / DE / AU / CA) to confirm.
  • Vertical mismatch: the advertiser pool is scoped by vertical. Check the website's vertical matches your intended advertiser category.
  • Rate limited: under heavy load /v1/offers can return 429. In practice you'll only see this under automated testing.

Symptom: widget renders but clicks don't count

Offers appear, you click, but analytics stays at 0.

  • Consent manager blocking the event: your CMP may be blocking non-essential POSTs. Allowlist https://api.retarget.gg.
  • Invalid-click filter hit: if you're testing from your own IP repeatedly, the filter counts only the first click per visitor per offer within a window. Use a VPN or second device.
  • Wrong redirect path: don't rewrite the card's href. The widget fires a click event before navigating, and short-circuiting the flow breaks attribution.

Symptom: Visitors panel says "No pings in 24h"

The widget posts to /v1/events/snippet-ping on every load (both allowed and blocked paths). If the dashboard's Visitors panel shows No pings in 24h:

  1. Open the page with the script.
  2. DevTools → Network → filter snippet-ping. You should see a POST returning 204.
  3. No request → the widget script didn't finish loading. Check the widget script's request in Network for a 5xx or timeout.
  4. Request present and 204, but dashboard still empty → you're likely viewing the wrong website. The data-website on the script must match the web_ key of the website you're viewing.

Symptom: Trigger Widget session never becomes ready

You loaded widget-decline.js, sent the sessionId to your server, and called trigger, but the embed never shows the overlay.

  • Trigger didn't succeedPOST /v1/widget-decline/trigger should return 200 with { ok: true }. If it's an error status, check the response body. Common: session expired, wrong sessionId, or a revoked integration secret.
  • Wrong session id → your client sent a newer sessionId but your server is triggering an older one. Make sure the id you send matches window.__RETARGET_DECLINE_SESSION_ID or the payload of the retarget:decline-session event.
  • Integration secret leaked and rotated → your old env var is stale. Pull the current secret from the website's Trigger Widget section and redeploy.
  • Polling blocked by CSP / CORS → the embed polls the Trigger Widget session endpoint. Make sure connect-src includes https://api.retarget.gg.

Symptom: analytics numbers look wrong

  • Timezones: all timestamps are UTC. If you compare against your own analytics in local time, expect offset.
  • Ad-blockers: desktop ad-blockers intercept /v1/events/*. Our numbers will be slightly below what your own first-party beacons report if you run both; that's expected.
  • Device attribution: we bucket device from viewport width (mobile < 640, tablet < 1024, else desktop). On shared devices this is best-effort.
  • Country mismatch: the API resolves country from the request IP. VPNs and new IP ranges occasionally land as an adjacent country.

Where to get a log

For self-service debugging, add data-comments="true" to the script tag temporarily: the widget prints decision, offer, impression, and click activity to the browser console with timestamps.

When you contact support, include the full request URL (with query string), the approximate timestamp in UTC, and the response body from any failing request. That's enough for us to pinpoint the event.

`data-dev-country` only works in development

The widget accepts data-dev-country / data-dev-region only when the page host is localhost / 127.0.0.1: or when you explicitly set data-allow-localhost="true" (use sparingly, only in gated dev environments). On production hosts it's silently ignored. Use a real VPN there.

Still stuck?

Need help with setup?

Send us your website stack, target regions, and whether you are installing Geo Popup or Decline Popup.

Debugging checklist | Docs | ReTarget.gg