Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 112 additions & 86 deletions demos/vanilla/nocookies/targeting/prebid.html.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@
cookies: false,
node: "${DCN_NODE}",
legacyHostCache: "${DCN_LEGACY_HOST_CACHE}",
initTargeting: true,
});

optable.instance.tryIdentifyFromParams();

// Create a ref for RTD module to use SDK.
optable.prebid_instance = optable.instance;
});
</script>
<script async src="${SDK_URI}"></script>
Expand All @@ -43,13 +47,6 @@
optable.instance.installGPTEventListeners();
});

// Try to fetch and cache targeting data from DCN:
optable.cmd.push(function () {
optable.instance.targeting().catch((err) => {
console.log("[OptableSDK] targeting() exception: " + err.message);
});
});

// Set up GPT:
window.googletag = window.googletag || { cmd: [] };
googletag.cmd.push(function () {
Expand All @@ -75,94 +72,92 @@
"/22081946781/web-sdk-demo-gam360/footer-ad": [[728, 90]],
};

var adUnits = [
{
code: "/22081946781/web-sdk-demo-gam360/header-ad",
mediaTypes: {
banner: {
sizes: bannerSizes["/22081946781/web-sdk-demo-gam360/header-ad"],
},
var adUnits = [
{
code: "/22081946781/web-sdk-demo-gam360/header-ad",
mediaTypes: {
banner: {
sizes: bannerSizes["/22081946781/web-sdk-demo-gam360/header-ad"],
},
bids: [
{
bidder: "districtmDMX",
params: {
dmxid: "/22081946781/web-sdk-demo-gam360/header-ad",
memberid: "102034",
},
},
],
},
{
code: "/22081946781/web-sdk-demo-gam360/box-ad",
mediaTypes: {
banner: {
sizes: bannerSizes["/22081946781/web-sdk-demo-gam360/box-ad"],
},
bids: [
{
bidder: "pubmatic",
params: {
publisherId: "156209", // Example: PubMatic test publisher ID
}
}
],
},
{
code: "/22081946781/web-sdk-demo-gam360/box-ad",
mediaTypes: {
banner: {
sizes: bannerSizes["/22081946781/web-sdk-demo-gam360/box-ad"],
},
bids: [
{
bidder: "districtmDMX",
params: {
dmxid: "/22081946781/web-sdk-demo-gam360/box-ad",
memberid: "102034",
},
},
],
},
{
code: "/22081946781/web-sdk-demo-gam360/footer-ad",
mediaTypes: {
banner: {
sizes: bannerSizes["/22081946781/web-sdk-demo-gam360/footer-ad"],
},
bids: [
{
bidder: "pubmatic",
params: {
publisherId: "156209",
}
}
],
},
{
code: "/22081946781/web-sdk-demo-gam360/footer-ad",
mediaTypes: {
banner: {
sizes: bannerSizes["/22081946781/web-sdk-demo-gam360/footer-ad"],
},
bids: [
{
bidder: "districtmDMX",
params: {
dmxid: "/22081946781/web-sdk-demo-gam360/footer-ad",
memberid: "102034",
},
},
],
},
];
bids: [
{
bidder: "pubmatic",
params: {
publisherId: "156209",
}
}
],
}
];

function initAdserver() {
if (pbjs.initAdserverSet) return;
pbjs.initAdserverSet = true;

googletag.cmd.push(function () {
pbjs.setTargetingForGPTAsync && pbjs.setTargetingForGPTAsync();
const disableGamTargeting = localStorage.getItem("disableGamTargeting") === "true";
console.log("[OptableSDK] Reading 'disableGamTargeting' from localstorage: " + disableGamTargeting);

// Setup page-level GAM targeting from any cached targeting data, and load GAM ads:
optable.cmd.push(function () {
const tdata = optable.instance.targetingKeyValuesFromCache();

if (tdata) {
for (const [key, values] of Object.entries(tdata)) {
googletag.pubads().setTargeting(key, values);
console.log("[OptableSDK] googletag.pubads().setTargeting(" + key + ", [" + values + "])");
}
googletag.cmd.push(function () {
if (disableGamTargeting) {
console.log("[OptableSDK] Skipping pbjs.setTargetingForGPTAsync() because disableGamTargeting is set to true");
} else {
pbjs.setTargetingForGPTAsync && pbjs.setTargetingForGPTAsync();
console.log("[OptableSDK] pbjs.setTargetingForGPTAsync()");
}

googletag.pubads().refresh();
console.log("[OptableSDK] googletag.pubads().refresh()");
});
});
}

pbjs.que.push(function () {
optable.cmd.push(function () {
const ortb2 = optable.instance.prebidORTB2FromCache();

pbjs.mergeConfig({
ortb2,
debug: true,
priceGranularity: "low",
userSync: {
iframeEnabled: true,
enabledBidders: ["districtmDMX"],
enabledBidders: ["pubmatic"],
},
realTimeData: {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation of that page should be updated accordingly

auctionDelay: 400,
dataProviders: [
{
name: 'optable',
waitForIt: true, // should be true, otherwise the auctionDelay will be ignored
},
],
},
});
pbjs.addAdUnits(adUnits);
Expand Down Expand Up @@ -220,24 +215,55 @@

<div class="row">
<div class="twelve column">
<h4>Example: targeting API: Prebid.js</h4>
<h4>Prebid.js Integration with OptableRTD</h4>

<h5>Overview</h5>
<p>
Shows how to load active cohorts for a visitor and pass them to Prebid.js via
<a href="https://docs.prebid.org/dev-docs/publisher-api-reference/mergeConfig.html">mergeConfig</a>.
It's assumed in this example that your primary ad server is
<a href="https://admanager.google.com/home/">Google Ad Manager</a> (GAM) and that you are integrated with it
using the
<a href="https://developers.google.com/publisher-tag/guides/get-started">Google Publisher Tag</a> (GPT), so
we also pass matching active cohorts to GAM.
This demo demonstrates how to integrate Optable's targeting capabilities with Prebid.js using the
<a href="https://docs.prebid.org/dev-docs/modules/optableRtdProvider.html">OptableRTD module</a>.
The implementation assumes Google Ad Manager (GAM) as the primary ad server, integrated via
<a href="https://developers.google.com/publisher-tag/guides/get-started">Google Publisher Tag (GPT)</a>.
</p>

<h5>Key Features</h5>
<ul>
<li>Loads active visitor cohorts and passes them to Prebid.js via OptableRTD</li>
<li>Automatically forwards matching cohorts to GAM for targeting</li>
<li>Supports local cache updates for improved targeting accuracy</li>
<li>Configurable GAM targeting override via localStorage</li>
</ul>

<h5>Implementation</h5>
<p>
In this example, we use the <code>prebidORTB2FromCache()</code> API to retrieve any targeting data from browser
LocalStorage, in order to pass it to Prebid.js via <a href="https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy">seller defined audiences</a>. We also call the SDK <code>targeting</code> API
which will fetch the latest targeting data from our DCN and cache it locally for later use. Since these
two events happen asynchronously, it's possible that the targeting data passed to GAM is slightly outdated.
To ensure ad targeting accuracy, it is recommended to call <code>targeting</code> to update the local cache on
page load.
The Prebid.js configuration requires minimal setup. Here's the essential configuration:
</p>
<pre><code>pbjs.mergeConfig({
debug: true,
priceGranularity: "low",
userSync: {
iframeEnabled: true,
enabledBidders: ["pubmatic"]
},
realTimeData: {
auctionDelay: 400,
dataProviders: [{
name: 'optable',
waitForIt: true // Required to respect auctionDelay
}]
}
});</code></pre>

<h5>Important Notes</h5>
<ul>
<li>
<strong>Targeting Cache:</strong> For optimal targeting accuracy, call <code>targeting</code>
on page load to update the local cache, as the RTD module only uses cached values.
</li>
<li>
<strong>GAM Targeting Override:</strong> Set <code>localStorage.disableGamTargeting = "true"</code>
before page load to prevent the SDK from sending targeting data to GAM.
</li>
</ul>
</div>
</div>

Expand Down
41 changes: 24 additions & 17 deletions demos/vanilla/nocookies/targeting/prebid.js

Large diffs are not rendered by default.