-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
204 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,114 +1,151 @@ | ||
--- | ||
layout: page_v2 | ||
title: Prebid Ad Slot | ||
description: The Prebid Ad Slot | ||
title: Prebid Ad Slot and GPID | ||
description: Prebid Ad Slot and GPID | ||
sidebarType: 1 | ||
--- | ||
|
||
# Prebid Ad Slot | ||
# The Prebid Ad Slot and the GPID | ||
{:.no_toc} | ||
|
||
The Prebid AdUnit 'code' is a mixed attribute that's generally either the GPT slot name or the HTML div ID. The undecided nature of the 'code' makes it harder to utilize for reporting and auction targeting. | ||
* TOC | ||
{:toc} | ||
|
||
The `Prebid Ad Slot` is an optional inventory management convention allowing publishers to supply a descriptive and stable label for each ad on the page. This makes it possible to have more granular reporting and better deal targeting. | ||
Prebid Ad Slot and the Global Placement ID (GPID) are overlapping conventions that allow publishers to identify ad inventory on their pages so bidders and reporting systems can better deal with their sites. | ||
|
||
## Background | ||
|
||
It all starts with how publishers decide to label their ad slots: the places on their pages | ||
where ads can be served. In some ad servers like GAM, these things are called "ad units". | ||
Most publishers use unique ad slot names, but some publishers utilize the same name for every ad slot on their page. e.g. "/homepage" might be the name for 5 different slots. | ||
|
||
It's the case of 'same ad slot names' that Prebid Ad Slot and GPID are | ||
meant to address. | ||
|
||
### The Prebid.js AdUnit | ||
|
||
When Prebid.js was developed in 2015, they needed a data structure that would link each ad slot to the bidders and parameters involved in the auction for that slot. Thus was born the Prebid.js [AdUnit](/dev-docs/adunit-reference.html). The AdUnit 'code' is what links this object to the adserver's ad slot. Because some pubs use the same ad slot name everywhere, AdUnit.code is a mixed attribute that can be either the ad slot name **or** the HTML div ID. The undecided nature of AdUnit.code makes it hard to utilize for reporting and auction targeting. | ||
|
||
### The Prebid Ad Slot | ||
|
||
The 'Prebid Ad Slot' was developed in Prebid.js v3 as an optional inventory management convention allowing publishers to supply a descriptive and stable label for each ad on the page. This makes it possible to have more granular reporting and better deal targeting. | ||
However, the PB ad slot is not an industry standard convention, so didn't gain | ||
much traction. | ||
|
||
### The GPID | ||
|
||
The Global Placement ID (GPID) was an initiative in the Fall of 2021 led | ||
by the TradeDesk to solve the problem of inventory identification in an industry-wide way. i.e. Buyers want to be able to identify ad slots in a unique way even | ||
when the publisher uses the same ad slot name multiple times. | ||
|
||
The original suggestion for GPID was to simply append the HTML div element id (aka the 'div-id') to the ad slot name. But some publishers generate div-ids randomly, so the definition of GPID has become: | ||
|
||
``` | ||
imp[].ext.gpid: ADSLOTNAME#UNIQUIFIER | ||
``` | ||
Where ADSLOTNAME is the ad server's slot name (e.g. /1111/homepage) and UNIQUIFIER is something that makes the ADSLOTNAME different from others. Normally it's a | ||
div-id, but if div-ids are random, it can be something else. The "#UNIQUIFIER" is only required if the ADSLOTNAME isn't unique enough on its own. | ||
|
||
{: .alert.alert-info :} | ||
The Prebid Ad Slot was introduced with Prebid.js 3.x. | ||
The Prebid Ad Slot didn't ever get broad adoption, so it's likely that | ||
someday we'll deprecate it in favor of the more standard GPID. | ||
|
||
## A Scenario | ||
## Defining Prebid Ad Slot and GPID | ||
|
||
1. The publisher utilizes the same 'slotname' in the page for multiple holes-in-the-page, differentiating in the ad server by size. e.g. | ||
- defineSlot('/1111/homepage', [[300,250]], 'div-293rj893p9wje9we9fj'); | ||
- defineSlot('/1111/homepage', [[728,90]], 'div-j98s9u9usj987665da'); | ||
- defineSlot('/1111/homepage', [[160,600]], 'div-B2q3s4gseshekhsei9sh'); | ||
2. In order to be able to display the right ad in the right hole, the Prebid AdUnit therefore sets the 'code' to the div ID instead of the slotname. | ||
3. The div ID in this case is a random number, not very useful for reporting. | ||
4. Therefore, to get a stable ID that's useful from a business perspective to identify a hole-in-the-page, the publisher | ||
decides to add another identifier... the Prebid Ad Slot. | ||
5. The publisher adds a function to the page that annotates each Prebid AdUnit in the auction with the `pbadslot`. | ||
6. Participating bid adapters read the `pbadslot` and can target deals to them. | ||
7. Participating analytics adapters read the `pbadslot` for more granular reporting. | ||
|
||
Example page function: | ||
{% highlight js %} | ||
|
||
// Use adunit.ortb2Imp.ext.data.pbadslot if it exists. Otherwise, if the | ||
// the adunit.code is a div ID, then look for a data-adslotid attribute, then look a matching slot in GPT | ||
// Otherwise, just use the AdUnit.code | ||
var setPbAdSlot = function setPbAdSlot(adUnits) { | ||
// set pbadslot for all ad units | ||
adUnits.forEach(function (adUnit) { | ||
if (!adUnit.ortb2Imp) { | ||
adUnit.ortb2Imp = {} | ||
} | ||
if (!adUnit.ortb2Imp.ext) { | ||
adUnit.ortb2Imp.ext = {}; | ||
} | ||
if (!adUnit.ortb2Imp.ext.data) { | ||
adUnit.ortb2Imp.ext.data = {}; | ||
} | ||
|
||
// use existing pbadslot if it is already set | ||
if (adUnit.ortb2Imp.ext.data.pbadslot) { | ||
return; | ||
} | ||
|
||
// check if AdUnit.code has a div with a matching id value | ||
const adUnitCodeDiv = document.getElementById(adUnit.code); | ||
if (adUnitCodeDiv) { | ||
// try to retrieve a data element from the div called data-adslotid. | ||
if (adUnitCodeDiv.dataset.adslotid) { | ||
adUnit.ortb2Imp.ext.data.pbadslot = adUnitCodeDiv.dataset.adslotid; | ||
return; | ||
} | ||
// Else if AdUnit.code matched a div and it's a banner mediaType and googletag is present | ||
if (adUnit.mediaTypes && typeof adUnit.mediaTypes === 'object' && adUnit.mediaTypes.banner && adUnit.mediaTypes.banner.sizes && window.googletag && googletag.apiReady) { | ||
var gptSlots = googletag.pubads().getSlots(); | ||
// look up the GPT slot name from the div. | ||
var linkedSlot = gptSlots.find(function (gptSlot) { | ||
return (gptSlot.getSlotElementId() === adUnitCodeDiv.id); | ||
}); | ||
if (linkedSlot) { | ||
adUnit.ortbImp.ext.data.pbadaslot = linkedSlot.getAdUnitPath(); | ||
return; | ||
} | ||
} | ||
} | ||
// Else, just use the AdUnit.code, assuming that it's an ad unit slot | ||
adUnit.ortb2Imp.ext.data.pbadslot = adUnit.code; | ||
}); | ||
}; | ||
There are two ways a publisher can inject these values into the header bidding auctions: | ||
|
||
pbjs.onEvent('beforeRequestBids', setPbAdSlot); | ||
1. Supply them manually on the PBJS AdUnits | ||
2. Install the [GPT Pre-Auction module](/dev-docs/modules/gpt-pre-auction.html) | ||
|
||
{% endhighlight %} | ||
### Defining them on the PBJS Ad Unit | ||
|
||
## How It Works | ||
#### Example 1 - unique ad slot names | ||
|
||
The Prebid Ad Slot is just a convention -- it's a form of adunit-specific first party data | ||
stored under `adunit.ortb2Imp.ext.data.pbadslot`. | ||
It can be utilized by any code ready to look for it. | ||
In this example, there's no need for the "UNIQUIFIER" string because every ad slot | ||
on the publisher page is already unique. | ||
|
||
It's intended to be specified via Prebid.js in one of two ways: | ||
``` | ||
pbjs.addAdUnits({ | ||
code: '/1111/homepage-leftnav', | ||
ortb2Imp: { | ||
ext: { | ||
gpid: "/1111/homepage-leftnav", | ||
data: { | ||
pbadslot: "/1111/homepage-leftnav" | ||
} | ||
} | ||
}, | ||
mediaTypes: ... | ||
bids: ... | ||
}); | ||
``` | ||
|
||
#### Example 2 - duplicate ad slots | ||
|
||
In this example, the publisher's ad slots all have the same name, but at least | ||
the div-ids are unique. | ||
|
||
``` | ||
pbjs.addAdUnits({ | ||
code: 'div-leftnav', | ||
ortb2Imp: { | ||
ext: { | ||
gpid: "/1111/homepage#div-leftnav", | ||
data: { | ||
pbadslot: "/1111/homepage#div-leftnav" | ||
} | ||
} | ||
}, | ||
mediaTypes: ... | ||
bids: ... | ||
}); | ||
``` | ||
|
||
1. Either directly on the AdUnit itself | ||
2. Or defined during the run of a function before the auction | ||
#### Example 3 - duplicate ad slots, random div IDs | ||
|
||
The function could determine the pbadslot in any way that produces a stable value useful for targeting and reporting. | ||
Some scenarios that could be supported: | ||
In this example, the publisher utilizes the same 'slotname' in the page for multiple holes-in-the-page, differentiating in the ad server by size. They also use random div-ids. e.g. | ||
- defineSlot('/1111/homepage', [[300,250]], 'div-293rj893p9wje9we9fj'); | ||
- defineSlot('/1111/homepage', [[728,90]], 'div-j98s9u9usj987665da'); | ||
|
||
- parse a substring of the ad server's slot name | ||
- use a custom div data element ID, else the AdUnit.code | ||
- use the AdUnit.ortb2Imp.ext.data.pbadslot as a default rather than primary | ||
- support a different ad server | ||
``` | ||
pbjs.addAdUnits({ | ||
code: 'div-293rj893p9wje9we9fj', | ||
ortb2Imp: { | ||
ext: { | ||
gpid: "/1111/homepage#300x250", | ||
data: { | ||
pbadslot: "/1111/homepage#300x250" | ||
} | ||
} | ||
}, | ||
mediaTypes: ... | ||
bids: ... | ||
},{ | ||
code: 'div-j98s9u9usj987665da', | ||
ortb2Imp: { | ||
ext: { | ||
gpid: "/1111/homepage#728x90", | ||
data: { | ||
pbadslot: "/1111/homepage#728x90" | ||
} | ||
} | ||
}, | ||
mediaTypes: ... | ||
bids: ... | ||
}); | ||
``` | ||
|
||
## Prebid Server | ||
|
||
The OpenRTB location for the Prebid Ad Slot is `imp[].ext.data.pbadslot`: | ||
The Prebid Server Bid Adapter just sends the values to the conventional OpenRTB locations: | ||
- Prebid Ad Slot is `imp[].ext.data.pbadslot` | ||
- GPID is `imp[].ext.gpid` | ||
|
||
Mobile and AMP Stored Requests should place the values there as desired. | ||
|
||
- The Prebid SDK will place the value there. | ||
- AMP Stored Requests should place the value there if desired. | ||
- Server-side bid and anlytics adapters may be modified to read the value. | ||
Server-side bid and anlytics adapters may be modified to read the value. | ||
|
||
## Further Reading | ||
|
||
- The [onEvent()](/dev-docs/publisher-api-reference/onEvent.html) function | ||
- [GPT Pre-Auction Module](/dev-docs/modules/gpt-pre-auction.html) | ||
- [Ad Unit Reference](/dev-docs/adunit-reference.html) |