A native ad is made up of assets such as a title, description, and image URL that are plugged into a publisher-defined HTML template. The template includes placeholder macros for those assets, and may be styled to match the form of the surrounding page.
At a high level, Prebid.js’ support for native ads works like this:
To determine whether a bidder can supply native demand, check the bidder parameter page.
Create your ad server in-page implementation as usual. See Setting Up Prebid Native in GAM for instructions for how to do this with Google Ad Manager.
There are three options for defining the native template:
This table summarizes how the 3 approaches work:
Table 1: Native Implementation Approaches
Component | AdServer-Defined Creative Scenario | AdUnit-Defined Creative Scenario | Custom Renderer Scenario |
---|---|---|---|
Prebid.js | mediaTypes. native.sendTargetingKeys: false | sendTargetingKeys:false and mediaTypes.native.adTemplate contains ##macros## | sendTargetingKeys:false and mediaTypes.native.rendererUrl |
Ad Server Key Value Pairs | hb_adid | hb_adid | hb_adid |
Ad Server | Native template loads native-render.js and calls renderNativeAd(). Uses Prebid ##macro## format. | Native creative loads native-render.js and calls renderNativeAd() with requestAllAssets: true | Native creative loads native-render.js and calls renderNativeAd(), with requestAllAssets:true |
Prebid Universal Creative | renderNativeAd resolves macros in the creative body and CSS. | renderNativeAd resolves ##macros## in adTemplate and CSS, appending the adTemplate to the creative body | renderNativeAd loads javascript from renderUrl, calls the renderAd function, appending the results to the creative body. |
Javascript rendering function | n/a | n/a | Receives hash of attributes, responsible for resolving any macro format and returning an HTML block. |
The Prebid.js AdUnit needs to defines a native mediatype object to tell bidders which assets are required. This table defines all attributes that could be included in AdUnit.mediatypes.native. Specific examples of the three different scenarios follow.
Table 2: Prebid.js AdUnit Native MediaType Options
Attribute | Scope | Description | Example | Type |
---|---|---|---|---|
sendTargetingKeys | optional | Defines whether or not to send the hb_native_ASSET targeting keys to the ad server. Defaults to true for now, though we recommend setting this to false and utilizing one of the ways to define a native template. |
false |
boolean |
adTemplate | optional | Used in the ‘AdUnit-Defined Creative Scenario’, this value controls the Native template right in the page. | See example below. | escaped ES5 string |
rendererUrl | optional | Used in the ‘Custom Renderer Scenario’, this points to javascript code that will produce the Native template. | ‘https://host/path.js’ | string |
type | optional | A “type” is like a macro that defines a group of assets. The only value currently supported is ‘image’, which implies the following assets: image, title, sponsoredBy, clickUrl, body, icon, and cta. The first 4 are required attributes. | image |
string |
ASSETCODE. required | optional | Defines whether native bids must include this asset. Defaults to false . |
true |
boolean |
ASSETCODE. len | optional | For text assets, bidders should pass this value through to the endpoint. Prebid.js does not enforce the responses and there’s no default. | 40 | integer |
ASSETCODE. sizes | optional | For image assets, bidders may pass this value through to the endpoint. Prebid.js does not enforce the responses and there’s no default. Format is an array with two elements: [WIDTH, HEIGHT] | [50, 50] |
array of integers |
ASSETCODE. aspect_ratios | optional | For image assets, bidders may pass this value through to the endpoint. Prebid.js does not enforce the responses and there’s no default. Format is an object with the attributes in the rows below. | object | |
ASSETCODE. aspect_ratios.min_width | optional | Part of the aspect_ratios object, bidders may pass this value through to the endpoint. Prebid.js does not enforce the responses and there’s no default. | 50 | integer |
ASSETCODE. aspect_ratios.min_height | optional | Part of the aspect_ratios object, bidders may pass this value through to the endpoint. Prebid.js does not enforce the responses and there’s no default. | 75 | integer |
ASSETCODE. aspect_ratios.ratio_width | optional | Part of the aspect_ratios object, bidders may pass this value through to the endpoint. Prebid.js does not enforce the responses and there’s no default. | 2 | integer |
ASSETCODE. aspect_ratios.ratio_height | optional | Part of the aspect_ratios object, bidders may pass this value through to the endpoint. Prebid.js does not enforce the responses and there’s no default. | 3 | integer |
ext.CUSTOMASSET | optional | Non-standard or bidder-specific assets can be supplied on the ext here. Attributes on custom assets are documented by the vendor. |
Table 3: Native Assets Recognized by Prebid.js
Asset Code | Description | Macro |
---|---|---|
title |
The title of the ad, usually a call to action or a brand name. | ##hb_native_title## |
body |
Text of the ad copy. | ##hb_native_body## |
body2 |
Additional Text of the ad copy. | ##hb_native_body2## |
sponsoredBy |
The name of the brand associated with the ad. | ##hb_native_brand## |
icon |
The brand icon that will appear with the ad. | ##hb_native_icon## |
image |
A picture that is associated with the brand, or grabs the user’s attention. | ##hb_native_image## |
clickUrl |
Where the user will end up if they click the ad. | ##hb_native_linkurl## |
displayUrl |
Text that can be displayed instead of the raw click URL. e.g, “Example.com/Specials” | ##hb_native_displayUrl## |
privacyLink |
Link to the Privacy Policy of the Buyer, e.g. http://example.com/privacy | ##hb_native_privacy## |
privacyIcon |
Icon to display for the privacy link, e.g. http://example.com/privacy_icon.png | ##hb_native_privicon## |
cta |
Call to Action text, e.g., “Click here for more information”. | ##hb_native_cta## |
rating |
Rating information, e.g., “4” out of 5. | ##hb_native_rating## |
downloads |
The total downloads of the advertised application/product | ##hb_native_downloads## |
likes |
The total number of individuals who like the advertised application/product | ##hb_native_likes## |
price |
The non-sale price of the advertised application/product | ##hb_native_price## |
salePrice |
The sale price of the advertised application/product | ##hb_native_saleprice## |
address |
Address of the Buyer/Store. e.g, “123 Main Street, Anywhere USA” | ##hb_native_address## |
phone |
Phone Number of the Buyer/Store. e.g, “(123) 456-7890” | ##hb_native_phone## |
Specific bidders may not support all of the fields listed below or may return differing responses for the assets that are requested.
There are two methods for defining sizes for image-like assets (image
and icon
). Both are shown below, but the first example (using sizes
) is more widely supported by demand partners.
Using mediaTypes.native.image.sizes
(or mediaTypes.native.icon.sizes
for icons):
Using mediaTypes.native.image.aspect_ratios
(or mediaTypes.native.icon.aspect_ratios
for icons):
In order to fit special bidder requirements, Prebid.js supports defining assets beyond the standard set. Simply define custom attributes in mediaTypes.native.ext, and they can be retrieved at render time. Other than being under the ext
object, custom assets are declared in the same way as the standard ones.
Note: The native-render.js::renderNativeAd()
function must be called with requestAllAssets: true
.
Bid adapters will declare which custom assets they support in their documentation. It is recommended to prefix the asset name with the bidderCode to avoid collision issues.
mediaTypes {
native: {
body: {
required: true
},
ext: {
bidderA_specialtracking: { // custom asset
required: false
}
}
}
In the native template, simply access the custom value with the normal Prebid ##macro## format assuming hb_native_
as the prefix. For example:
<div id="mytemplate">
... render a lovely creative ...
... refer to ##hb_native_bidderA_specialtracking## when appropriate ...
</div>
In this scenario, the body of the native creative template is managed within the ad server and includes special Prebid.js macros.
When the native AdUnit is defined in the page, declare sendTargetingKeys: false
in the native Object. This will prevent Prebid.js from sending all the native-related ad server targeting variables.
Example Native AdUnit:
pbjs.addAdUnits({
code: slot.code,
mediaTypes: {
native: {
sendTargetingKeys: false,
image: {
required: true,
sizes: [150, 50]
},
title: {
required: true,
len: 80
},
sponsoredBy: {
required: true
},
clickUrl: {
required: true
},
privacyLink: {
required: false
},
body: {
required: true
},
icon: {
required: true,
sizes: [50, 50]
}
}
},
bids: [{
...
}]
});
Here’s an example native AdUnit using the ‘type’ feature, which implies a number of required and optional attributes.
const adUnits = [{
code: 'adUnit-code',
mediaTypes: {
sendTargetingKeys: false,
native: {
type: 'image'
}
}
bids: [{
...
}]
}];
There are three key aspects of the native template:
Example creative HTML:
<div class="sponsored-post">
<div class="thumbnail" style="background-image: url(##hb_native_image##);"></div>
<div class="content">
<h1><a href="%%CLICK_URL_UNESC%%##hb_native_linkurl##" target="_blank" class="pb-click">##hb_native_title##</a></h1>
<p>##hb_native_body##</p>
<div class="attribution">##hb_native_brand##</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/prebid-universal-creative@latest/dist/native-render.js"></script>
<script>
var pbNativeTagData = {};
pbNativeTagData.pubUrl = "%%PATTERN:url%%"; // GAM specific
pbNativeTagData.adId = "%%PATTERN:hb_adid%%"; // GAM specific
// if you're using 'Send All Bids' mode, you should use %%PATTERN:hb_adid_BIDDER%%
pbNativeTagData.requestAllAssets = true;
window.pbNativeTag.renderNativeAd(pbNativeTagData);
</script>
When using ‘Send All Bids’ mode you should update pbNativeTagData.adId = "%%PATTERN:hb_adid_BIDDERCODE%%";
for each bidder’s creative
Example CSS:
.sponsored-post {
background-color: #fffdeb;
font-family: sans-serif;
padding: 10px 20px 10px 20px;
}
.content {
overflow: hidden;
}
.thumbnail {
width: 120px;
height: 100px;
float: left;
margin: 0 20px 10px 0;
background-image: url(##native_image##);
background-size: cover;
}
h1 {
font-size: 18px;
margin: 0;
}
a {
color: #0086b3;
text-decoration: none;
}
p {
font-size: 16px;
color: #444;
margin: 10px 0 10px 0;
}
.attribution {
color: #fff;
font-size: 9px;
font-weight: bold;
display: inline-block;
letter-spacing: 2px;
background-color: #ffd724;
border-radius: 2px;
padding: 4px;
}
In this scenario, the body of the native creative template is managed within the Prebid.js AdUnit and includes special Prebid.js macros.
When the Native AdUnit is defined in the page:
sendTargetingKeys: false
in the native Object. This will prevent Prebid.js from sending all the native-related ad server targeting variables.Example AdUnit:
var adUnits = [{
code: 'native-div',
mediaTypes: {
native: {
sendTargetingKeys: false,
adTemplate: "<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\" style=\"background-image: url(##hb_native_image##);\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"%%CLICK_URL_UNESC%%##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">\r\n ##hb_native_title##\r\n <\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t##hb_native_brand##\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>",
title: {
required: true,
len: 800
},
image: {
required: true,
sizes: [989, 742],
},
sponsoredBy: {
required: true
}
}
}
}
}];
Even though the body of the native creative is defined in the AdUnit, an AdServer creative is still needed. There are two key aspects of the native creative in this scenario:
Example Creative HTML
<script src="https://cdn.jsdelivr.net/npm/prebid-universal-creative@latest/dist/native-render.js"></script>
<script>
var pbNativeTagData = {};
pbNativeTagData.pubUrl = "%%PATTERN:url%%"; // GAM specific
pbNativeTagData.adId = "%%PATTERN:hb_adid%%"; // GAM specific
// if you're using 'Send All Bids' mode, you should use %%PATTERN:hb_adid_BIDDER%%
pbNativeTagData.requestAllAssets = true;
window.pbNativeTag.renderNativeAd(pbNativeTagData);
</script>
When using ‘Send All Bids’ mode you should update pbNativeTagData.adId = "%%PATTERN:hb_adid_BIDDERCODE%%";
for each bidder’s creative
In this scenario, the body of the native creative is managed from an external JavaScript file.
When the Native AdUnit is defined in the page:
sendTargetingKeys: false
in the Native Object. This will prevent Prebid.js from sending all the native-related ad server targeting variables.rendererUrl
as a URL that defines a window.renderAd
function in the creative iframe. Any CSS definitions need to be defined in the body (e.g. <style>
tags) or in the AdServer creative.Example AdUnit setup:
var adUnits = [{
code: 'native-div',
mediaTypes: {
native: {
sendTargetingKeys: false,
rendererUrl: "https://files.prebid.org/creatives/nativeRenderFunction.js",
title: {
required: true,
len: 800
},
image: {
required: true,
sizes: [989, 742],
},
sponsoredBy: {
required: true
}
}
}
}
}];
Even though the body of the native creative is defined in the external JavaScript, an AdServer creative is still needed. There are two key aspects of the native creative in this scenario:
Example creative HTML:
<script src="https://cdn.jsdelivr.net/npm/prebid-universal-creative@latest/dist/native-render.js"></script>
<script>
var pbNativeTagData = {};
pbNativeTagData.pubUrl = "%%PATTERN:url%%"; // GAM specific
pbNativeTagData.adId = "%%PATTERN:hb_adid%%"; // GAM specific
// if you're using 'Send All Bids' mode, you should use %%PATTERN:hb_adid_BIDDER%%
pbNativeTagData.requestAllAssets = true;
window.pbNativeTag.renderNativeAd(pbNativeTagData);
</script>
When using Send All Bids
you should update pbNativeTagData.adId = "%%PATTERN:hb_adid_biddercode%%";
for each bidder’s creative
Requirements for a native rendering function:
Here’s an example script:
window.renderAd=function(data){
let template = "<div class=\"sponsored-post\"><div class=\"thumbnail\"><\/div><div class=\"content\"><h1> <a href=\"##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a><\/h1><p>##hb_native_body##<\/p> <div class=\"attribution\"> ##hb_native_brand## <\/div> <\/div> <\/div>";
const map = {
title: 'hb_native_title',
body: 'hb_native_body',
body2: 'hb_native_body2',
privacyLink: 'hb_native_privacy',
sponsoredBy: 'hb_native_brand',
image: 'hb_native_image',
icon: 'hb_native_icon',
clickUrl: 'hb_native_linkurl',
displayUrl: 'hb_native_displayurl',
cta: 'hb_native_cta',
rating: 'hb_native_rating',
address: 'hb_native_address',
downloads: 'hb_native_downloads',
likes: 'hb_native_likes',
phone: 'hb_native_phone',
price: 'hb_native_price',
salePrice: 'hb_native_saleprice'
}
for (var i = 0; i < data.length; i++){
if (map[data[i].key]) {
template = template.replace("##"+map[data[i].key]+"##",data[i].value);
}
}
return template;
}
Note that the format of any macros in external render JavaScript is totally up to you. The data object coming in will be keyed according to the Key column in the table in the appendix, e.g. privacyLink and not hb_native_privacy.
A few details that may help understand and debug your setup:
clickUrl
and not hb_native_linkurl
.clickUrl
.There are detailed instructions for setting up native in GAM, but none of the Prebid functionality is specific to GAM. The requirements to use any of these approaches in a different ad server are: