Geo-blocking widget
Full-page overlay that shows sponsored offers only to visitors outside your service area. Install in two minutes, CMS-agnostic.
The geo-blocking widget renders a full-screen overlay of sponsored offers only to visitors whose country or region falls outside the rule you set on your website. It's the right fit when your core product is regulated or region-locked (iGaming, finance, streaming catalogues) and you want to turn otherwise-declined traffic into revenue.
Before you start
You'll need a public key (pk_…) and a website key (web_…) from the dashboard: Websites → [Your site]. Both are per-website and safe to expose in client-side HTML: the widget validates the page's origin against the domain you registered.
How it works
Script loads, decision runs
The
<script>tag is async: it never blocks rendering. On load it callsGET /v1/decisionwith your public key, website key, and the visitor's country (resolved server-side from the client IP).Allowed → pass through
If the visitor falls on the allowed side of your geo rule, nothing renders. The script fires one
POST /v1/events/snippet-pingand exits. No visible DOM.Blocked → overlay appears
If the visitor is on the blocked side, the widget creates
#retarget-root, fetches eligible offers for their country, and renders a full-screen card layout.Clicks attribute via redirect
Every click routes through
api.retarget.gg/v1/r?…so attribution, fraud signals, and publisher revenue land in your dashboard.
Install
The simplest, universal form is a single guarded <script> block that works on any host: static sites, SPAs, GTM, Cloudflare Zaraz, anywhere.
<script>
(function () {
if (document.querySelector('script[data-website="YOUR_WEBSITE_KEY"]')) return;
var s = document.createElement('script');
s.src = 'https://cdn.retarget.gg/widget.js';
s.async = true;
s.setAttribute('data-pub', 'YOUR_PUBLIC_KEY');
s.setAttribute('data-website', 'YOUR_WEBSITE_KEY');
s.setAttribute('data-api', 'https://api.retarget.gg');
(document.head || document.documentElement).appendChild(s);
})();
</script>// app/layout.tsx
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://cdn.retarget.gg/widget.js"
data-pub="YOUR_PUBLIC_KEY"
data-website="YOUR_WEBSITE_KEY"
strategy="afterInteractive"
/>
</body>
</html>
);
}<!-- Custom HTML tag, trigger: All Pages -->
<script>
(function () {
if (document.querySelector('script[data-website="YOUR_WEBSITE_KEY"]')) return;
var s = document.createElement('script');
s.src = 'https://cdn.retarget.gg/widget.js';
s.async = true;
s.setAttribute('data-pub', 'YOUR_PUBLIC_KEY');
s.setAttribute('data-website', 'YOUR_WEBSITE_KEY');
s.setAttribute('data-api', 'https://api.retarget.gg');
(document.head || document.documentElement).appendChild(s);
})();
</script>Origin must match your registered domain
The widget refuses to render if the page's Origin doesn't match the domain you registered on the website. If you serve the same site on staging or a preview host, either add the staging hostname as a second website (with its own keys) or use data-api to point at a staging API.
Attributes
| Attribute | Required | Purpose |
|---|---|---|
data-pub | ✅ | The website's public key. Starts with pk_. |
data-website | ✅ | The website key. Starts with web_. |
data-api | : | Override the API base URL. Defaults to https://api.retarget.gg. Use for staging. |
data-dev-country | : | Force a country (e.g. DE) regardless of IP. Only honored on localhost or when data-allow-localhost is set; ignored on arbitrary production hosts. |
data-dev-region | : | Force a region (e.g. BY for Bavaria). Same localhost-only constraint. |
data-allow-localhost | : | Treat the current host as "localhost" for dev-override purposes (useful when testing on a tunnelled hostname like *.ngrok.io). |
data-comments="false" | : | Mute the script's console.log diagnostics. Purely a logging toggle. |
data-debug | : | Force the widget into verbose debug mode (same effect as localhost). |
Iframe / geo-gate setups
If you already use a third-party geo gate (Cloudflare Access, custom middleware, iframe sandboxing) that embeds your page inside an iframe for blocked traffic, point the blocked URL to a page on your domain that loads this widget: typically your homepage or a dedicated /blocked route. The script behaves identically inside the iframe.
Same keys, any surface
widget.js and widget-section.js share the same public key and website key. Embed them on the same page or swap between them without changes in the dashboard.
Verify the install
Reload your page from an allowed location
Nothing should appear. Open DevTools → Network and confirm the
GET /v1/decisioncall returns{ "allowed": true }. APOST /v1/events/snippet-pingwill follow it with a204 No Content.Simulate a blocked visit (local dev)
While developing on
localhost, adddata-dev-country="DE"(or any country on your blocked side) to the script tag and reload. The overlay should appear.Check analytics
The website's Analytics tab shows the decision, impression, and click events after they flush. If nothing appears, jump to the Debugging guide.
Performance
- Single async script. Never blocks first paint.
- The decision request is tiny (
GET /v1/decision) and doesn't need any payload beyond the query string. - Allowed visitors: one request out, nothing rendered. Blocked visitors: one decision call, one offers call, then render.
- The server responds with
Cache-Control: no-store: decisions are per-request. Don't put a CDN cache in front ofapi.retarget.gg.
Related
Section widget
Inline sponsored offers instead of a full-page takeover: same keys, different surface.
Trigger Widget
Server-triggered overlay for failed KYC / deposit decline flows.
API reference
The REST endpoints the widget calls under the hood: /v1/decision, /v1/offers, /v1/events/*.
Debugging
What to check when the overlay doesn't render or clicks don't attribute.
Publisher
Geo Popup & Decline Popup overview
The product framing for the install you just read.
Advertiser
CPC, CPA, eCPM in one auction
The demand side of the network — useful context even for publishers.
Essays
Long-form strategy
How others think about geo-blocking, KYC declines, and bid models.
Need help with setup?
Send us your website stack, target regions, and whether you are installing Geo Popup or Decline Popup.