Section widget
Render sponsored offers inline inside your layout with widget-section.js: same keys as the geo-blocking widget, different surface.
The section widget embeds sponsored offers inside your layout: sidebar, below an article, a dedicated "Deals" strip: instead of a full-screen takeover. Same keys as the Geo-blocking widget; the API returns section-optimized offer counts.
When to use this
Content sites (news, reviews, recipes, how-to) that want a revenue strip alongside organic content. If your vertical is regulated and you want the "block until they click" UX, use the Geo-blocking widget instead.
Install
Two pieces: a container where offers render, and the script tag.
<!-- Container: place it where you want the offers to appear -->
<div id="retarget-ads"></div>
<!-- Script: paste the guarded loader 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-section.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');
s.setAttribute('data-container', 'retarget-ads');
(document.head || document.documentElement).appendChild(s);
})();
</script>// app/page.tsx (App Router)
import Script from "next/script";
export default function Page() {
return (
<>
<article>{/* ... your content ... */}</article>
<div id="retarget-ads" className="mt-10" />
<Script
src="https://cdn.retarget.gg/widget-section.js"
data-pub="YOUR_PUBLIC_KEY"
data-website="YOUR_WEBSITE_KEY"
data-container="retarget-ads"
strategy="afterInteractive"
/>
</>
);
}<!-- Use any id you like: pass it via data-container -->
<div id="my-offers-slot"></div>
<script
src="https://cdn.retarget.gg/widget-section.js"
data-pub="YOUR_PUBLIC_KEY"
data-website="YOUR_WEBSITE_KEY"
data-container="my-offers-slot"
async
></script>How it works
Script loads, decision runs
widget-section.jscallsGET /v1/decision?mode=sectionso analytics reflect inline placement instead of a takeover.Allowed → nothing renders
The container stays empty. This is expected: allowed visitors use your normal site.
Blocked → offers appear inside the container
The widget fills the container with an offer card grid (up to
data-max-ads, default 6). The container's width decides the layout.Clicks attribute via redirect
Clicks route through
/v1/r?t=…for attribution before opening the advertiser's landing page.
Attributes
| Attribute | Required | Purpose |
|---|---|---|
data-pub | ✅ | The website's public key. |
data-website | ✅ | The website key. |
data-container | : | Default retarget-ads. Change to target a different element by id. Accepts a single id only. |
data-max-ads | : | Cap the number of offer cards. Default 6, hard cap 24. |
data-api | : | Override API base URL (defaults to https://api.retarget.gg). |
data-comments="false" | : | Mute console.log diagnostics. Purely a logging toggle. |
data-dev-country, data-dev-region | : | Simulate a location. Only honored on localhost or with data-allow-localhost. |
data-allow-localhost | : | Treat the current host as "localhost" for dev-override purposes. |
data-debug | : | Force verbose debug mode. |
Layout tips
- Width: the widget respects its container: give it
100%width and it will fill the slot. - Height: cards grow with content. Expect ~320 to 480 px per row of three offers.
- Sidebar: 300 to 400 px wide columns work well; offers stack into one column per row.
- Below article: a full-width strip of 2 to 3 offers works well on news/blog layouts.
- Gap to content: add
margin-topon the container (e.g.mt-10) so offers don't feel stapled to your prose.
Origin must match
The widget refuses to render if the page's Origin doesn't match the domain registered on the website. For staging or preview hosts, use a separate website entry (its own keys) or point data-api at a dedicated staging API.
Multiple placements on one page
Each script tag mounts into one container. If you want offers in two places on the same page, use two separate script tags, each pointing at its own container id:
<div id="offers-above"></div>
<article>...</article>
<div id="offers-below"></div>
<!-- Widget #1 -->
<script
src="https://cdn.retarget.gg/widget-section.js"
data-pub="YOUR_PUBLIC_KEY"
data-website="YOUR_WEBSITE_KEY"
data-container="offers-above"
async
></script>
<!-- Widget #2: note different data-website guards won't dedupe these,
since they're two separate script elements with the same website key.
Use with caution: you'll trigger two decision calls per pageload. -->
<script
src="https://cdn.retarget.gg/widget-section.js"
data-pub="YOUR_PUBLIC_KEY"
data-website="YOUR_WEBSITE_KEY"
data-container="offers-below"
async
></script>Prefer one placement per page
Each script tag makes its own decision + offers calls. For most content layouts, a single well-placed block converts better than two and avoids the extra requests.
Performance
Same architecture as the Geo-blocking widget: single async script, no critical-path work. The container is reserved in your layout but empty until a blocked decision lands.
For a shift-free experience, give the container a min-height (e.g. 320px) so the layout doesn't jump when offers appear.
Related
Geo-blocking widget
Full-page overlay on the same keys: good for regulated verticals.
Widget integration reference
Full attribute list and cross-cutting behavior across all three widgets.
Debugging
The script loaded but the container is empty? Start here.
Geo rules
Decide which visitors see the section block.
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.