Integration of metaTag.min.js
Please implement the provided JavaScript file (ending in metaTag.min.js) in the <HEAD> tag of your website. The file either can be served by the domain of your website or be loaded directly from our CDN.
The library is created for each website individually and will only work correctly on this specific site.
Request from our CDN (Content Delivery Network)
You will receive the path to the file from a Partner Manager responsible for your account (and, as a rule, with the same E-Mail as this documentation).
For integrations via javascript it could look like this:
Code Block | ||
---|---|---|
| ||
(function() { var channel = !!document.location.href.match(/sdgmt=preview/i) ? 'preview' : 'live'; var script = document.createElement('script'); script.type = 'text/javascript'; script.async = true; script.setAttribute('fetchpriority', 'high'); script.src = 'https://cdn.stroeerdigitalgroup.de/metatag/' + channel + '/beispielseite/metaTag.min.js'; document.head.appendChild(script); })(); |
Tip |
---|
You can view the human-readable version of our code by enabling “source maps” in your prefered browsers “Development tools”. Please see your browsers documentation on how to enable this. |
Hosting on your domain
For performance and data-privacy reasons, it might be beneficial to host all MetaTag2 files on your own domain.
Examples on how to update MetaTag2 files regularly and host on your CDN, can be found in our documentation: Metatag2 hosting on a publisher webserver
Integration of Ads.txt file
In order to participate safely in an automatic (programmatic) auctioning network environment, it is possible to lodge an additional file in the domain of the website. This file contains a list of all approved and certified parties, that are eligible for the sale of advertisements on your website. During the auction process, advertisers can scan the file and check if they are negotiating with an authorized party. This assures that the relation between seller, buyer, and the website is established. In addition, unauthorized parties will be strictly excluded.
We already offer a prepared file ready to use via the following URL https://cdn.stroeerdigitalmedia.de/Ads/adstxt/ads.txt
Please download this file and place it in the root domain of your website, for example //mydomain.com/ads.txt
Note |
---|
Please make sure this file stays updated. We recommend a synchronization every 24 hours (e.g. via Cronjob). This guarantees that changes will be applied as soon as possible for your website. |
Feel free to add further entries to this file, e.g. if you like to include any of your own marketing partners. Please make sure that on automatic retrivial of our version of adx.txt, your changes are applied regularly to your version of the file.
You can check your version of the file for errors or problems, with several freely available, online validators. For example: https://adstxt.guru/validator/
Further Information about Ads.txt can be found on the website of the Interactive Advertising Bureau, initiator of the Ads.txt initiative.
Configuration of your website
In order to be able to allocate the correct AdTags to your website, our library requires further information.
This information varies depending on which HTML page the advertisements are being called from. For instance, the library needs different information for the start page of your website than for an article in the category “Fashion”.
There are several JavaScript methods available, which you can call and fill with information, to allow our TagManager to render the correct AdTags to your website. See “Publisher Api” further below for a list of available methods.
In order to fill the functions with content, we will provide a file detailing the marketing structure of your website in table form. You should have received this with the same e-mail as your documentation, or you may request this table from your Ströer Partner Manager.
PublisherApi
Anchor | ||||
---|---|---|---|---|
|
Calling these methods should always be wrapped inside a JavaScript “command queue”, please use the namespace “window.SDG.cmd”.
This will allow you to send commands, even if “metaTag.min.js” file is not fully loaded yet.
Code Block |
---|
<script> window.SDG = window.SDG || {}; window.SDG.cmd = window.SDG.cmd || []; window.SDG.cmd.push(function() { SDG.Publisher.setZone('homepage') SDG.Publisher.setPageType('rubrik') }) </script> |
SDG.Publisher.setZone( zone ) | Sets the zone for all ad slots of the HTML page to the same indicated value. |
---|---|
SDG.Publisher.addKeywords( keyWords ) | Transfers multiple words to the ad server for which specific advertising media can be booked. |
SDG.Publisher.addKeyword( keyWord ) | Transfers a word in the form of a string, for which specific advertising media can be booked, to the ad server. |
SDG.Publisher.removeKeywords( keyWords ) | Removes multiple previously added “keywords”. |
SDG.Publisher.removeKeyword( keyWord ) | Removes a single previously added “keyword”. |
SDG.Publisher.addKeyValue( key, value ) | Transfers a key and a single value assigned to it to the ad server. |
SDG.Publisher.addKeyValues( keyValuesObject ) | Transfers a key and multiple values assigned to it. |
SDG.Publisher.removeKeyValue( key ) | Removes a key and all of the assigned value. |
SDG.Publisher.removeKeyValues( keyChain ) | Removes multiple keys and all their assigned values. |
SDG.Publisher.registerSlot( slotName, container ) | Creates a new ad slot on the HTML page. |
SDG.Publisher.finalizeSlots() | Should be executed as soon as all relevant ad slots of a page have been registered. |
SDG.Publisher.unregisterSlot( slotName, deleteAdContent ) | Removes a specific ad slot from the page. |
SDG.Publisher.unregisterAllSlots( deleteLoadedAds ) | Removes all ad slots from the page. |
SDG.Publisher.loadSlot( slotName ) | Requests new advertising media from the ad server for a particular ad slot and displays them on the page. |
SDG.Publisher.loadMultipleSlots( slotNames ) | Request new ad media from the ad server for a given amount of ad slots and displays them on the page. |
SDG.Publisher.loadAllSlots( redoLoadedSlots ) | Requests new ad media for all existing ad slots on the page from the ad server and displays them on the page. |
SDG.Publisher.generateVastUrls( vastPositions ) | Requests VAST-Adtags from the video ad server. |
SDG.Publisher.generateVastUrlsPromise( vastPositions ) | Request VAST-AdTags and return them as a |
SDG.Publisher.setAdServerConsent ( perzonalizedAdsAllowed ) | Will notify the tag manager if you, as the Publisher of your website, object to using personalized advertisments on your site. |
SDG.Publisher.transitionAdvertisements() | Allows “Interstitial” ads to be loaded when the user is navigating the website. |
Example for a complete configuration
Anchor | ||||
---|---|---|---|---|
|
In this example, three ad slots "banner", "sky" and "mrec" will be registered directly in the <head> of the page, after all relevant site parameters have been configured.
We know these ad slots should always be loaded, no matter how the user interacts with the site. Therefor, we execute the finalizeSlot() method as soon as all "save" ad slots are registered. During registration, we mark all ad slots for loading, via .load(). Slots will only be loaded as soon as their respective containers are rendered by the browser. The ads will not interfere with the loading of the site, since all slots are loaded "asynchronous", meaning parallel, to the site.
The user has furthermore the possibility to load further content, if he clicks on the site. This content should also include ads, but it might happen that the content is never loaded by the user. It makes no sense to send the content (as well as the ads) to the user, as long as he/she does not wish so. Suitably, we only register the 4th slot "posterad", after the user has clicked the content.
Additionally, the ads should be reloaded after 60 seconds. This would never be done in a live environment, but illustrates the use of the Publisher.loadAllSlots() method for this example.
Example for a complete configuration
Code Block | ||
---|---|---|
| ||
<!DOCTYPE html> <html> <head> <!-- library at the end of <head> --> <script> window.SDG = window.SDG || {}; window.SDG.cmd = window.SDG.cmd || []; window.SDG.cmd.push(function() { SDG.Publisher.setZone('beauty'); SDG.Publisher.addKeywords(['auto','auto_news','naesse','reifen']); SDG.Publisher.addKeyValue('gender', 'woman'); SDG.Publisher.addKeyValues({ 'interest' : ['finance', 'automotive', 'fashion'] }); SDG.Publisher.registerSlot('banner', 'headerBeforeNavigation').load(); SDG.Publisher.registerSlot('rectangle', 'adInContent').load(); SDG.Publisher.registerSlot('sky', 'adInSidebar').load(); SDG.Publisher.transitionAdvertisements(); SDG.Publisher.finalizeSlots(); }); </script> <script src="http://cdn.stroeerdigitalgroup.de/metatag/live/beispielseite/metaTag.min.js" type="text/javascript"></script> </head> <body> <div id="contentWrapper"> <div id="headerBeforeNavigation"> <!-- "banner" slot will be displayed here --> </div> <nav>Navigation</nav> <main id="mainContent" class="contentWidth floatsLeft"> Content<br> Content<br> <div id="adInContent"> <!-- "rectangle" slot will be displayed here --> </div> Content<br> Content<br> Content which will be loaded on user interactive (scrolling, click, etc) <br> <div id="adInAsynchronContent" onclick="showContentAndAds"> <!-- "posterad" slot will be displayed here --> </div> </main> <aside class="sidebar floatsRight"> <div id="adInSidebar"> <!-- "sky" slot will be displayed here --> </div> </aside> </div> <script type="text/javascript"> //This function registers and loads the adlot "posterad", as soon as the user has loaded additional content successfully. function showContentAndAds() { loadAsychronContent().set('isContentLoaded', true); if(isContentLoaded){ window.SDG.cmd.push(function() { SDG.Publisher.registerSlot('posterad', document.getElementById('adInAsynchronContent')).load() }); } } //after 60 seconds all ad slots will be loaded anew. Since all slots were already loaded once, we pass true as argument. window.setTimeout(function() { window.SDG.cmd.push(function() { SDG.Publisher.loadAllSlots(true) }); },60000); </script> </body> </html> |
PublisherSlotApi
Anchor | ||||
---|---|---|---|---|
|
These methods are available to you for all registered ad slots.
Slot.load() | Will start the call to the ad server for this specific ad slot. |
---|---|
Slot.setTargeting( object ) | Passes a given key and its value/s just to this ad slot. |
Slot.blockFormats( formatList ) | Excludes an amount of formats from this ad slot. |
Slot.configure( configObject ) | Change settings for this ad slot. |
Slot.nativeBackfill( fallbackAd ) | Will render an advertisement when no ad is returned from the adserver |
You can combine or “chain” methods with each other:
Code Block |
---|
SDG.Publisher.registerSlot('sky', 'mySkyContainer') .setTargeting({'interesse': ['sport','finanzen']}) .load() |
All methods will return the “Slot” object itself, which in turn can be saved as a variable, so you can easily access the ad slot later on.
Code Block |
---|
var mySlotvar = SDG.Publisher.registerSlot('sky', 'mySkyContainer'); mySlotVar.setTargeting({'interesse': ['sport','finanzen']}).load(); |
Guidelines for integrating ad slots
In the following guidelines, we will give you a short collection of tips and best practices for handling ad slots.
These guidelines are not compulsory, but they do help to prepare your page or site for the different forms of advertising formats as efficiently as possible.
General guidelines for integrating ad slots
An ad slot must always be bracketed by an HTML tag, preferably a <div>, which has been assigned a unique ID value.
The ID can be chosen freely and can be used in the registerSlot() method.
Note |
---|
The tag should not have any further content apart from the script containing the method registerSlot(). Any further content it will be removed when ads are loaded. |
Example using the ad slots “banner” and “banner2”
Code Block | ||
---|---|---|
| ||
<div id="Site_superbanner_pos1"> <script type="text/javascript"> SDG.Publisher.registerSlot('banner','Site_superbanner_pos1'); </script> </div> . . . <div id="Site_superbanner_pos2"> <script type="text/javascript"> SDG.Publisher.registerSlot('banner2','Site_superbanner_pos2'); </script> </div> |
The HTML tags surrounding the ad slot should in no way hinder the visibility of the advertising material.
Please avoid CSS attributes such as “overflow:hidden” or “clip:rect()”.When having to position the advertising spaces, please avoid the CSS attribute “text-align” in the directly surrounding HTML tags. The interpretation of this attribute is browser specific and can be different from one browser to the next. Particularly in special advertising forms such as Wallpaper or Fireplace, imprecise positioning can lead to errors. As contrasted with that, the CSS attributes “position:relative”, “left” and “top” are implemented in exactly the same way in all browsers.
If you want to mark your advertising spaces with the label “Anzeige”, we can do this for you. The label can, in general, be freely designed and be seamlessly integrated into the rest of your typographical and color design.
Please send us a sample design for the label, together with the desired CSS rules. If you do not want to use a self-designed label, we can employ a standard label for all ad slots inserted automatically.In order to ensure a clean delivery of special advertising forms which are delivered via multiple advertising spaces at the same time, the three slots “banner”, “sky” and “out_of_page” should be delivered in a fixed sequence. Before, between or after these three types of ad slots it is possible to integrate additional ad slots without further difficulties as long as the sequence of these three locations is not changed.
Code Block language js //first "banner" is registered, afterwards "sky", finally "out_of_page". Other slots can be inserted at will. SDG.Publisher.registerSlot('banner','myBannerContainer'); SDG.Publisher.registerSlot('banner2','myBanner2Container'); SDG.Publisher.registerSlot('banner3','myBanner3Container'); SDG.Publisher.registerSlot('sky','mySkyContainer'); SDG.Publisher.registerSlot('rectangle','myRectangleContainer'); SDG.Publisher.registerSlot('out_of_page','myOOPContainer');
Guidelines for integrating specific ad slots
“banner” Ad Slot
Info |
---|
The “banner” or Leaderboard is the most frequently used ad slot for realizing large special formats and is often used in connection with other slots in order to serve and position large formats correctly on the page. |
In case of centered pages or so-called “responsive design” pages, in which the width of the page or the distance between the left margin of the content and the left margin of the browser window changes depending on the screen resolution set by the user, you should make sure that the distance between the left margin of the Superbanner and the right margin of the content always remains the same.
The following example shows a solution for this problem using the Hockeystick/Wallpaper format for visualization. This format wraps around the outer upper and right margins of the content of the page and as such can easily collide with the content of the page in responsible web pages.
In order to avoid this, we have the browser calculate the most favorable position for the slot automatically, while at the same time setting fixed distances in order to make the positioning, albeit dynamic, always clearly predictable at the same time.
For this purpose, we will always leave a 300 pixel margin on the right-hand side of the content, while at the same time still allowing the Skyscraper slot to deliver all formats.
To emphasize this, the most important CSS rules have been written inline, directly to the elements, while the less important rules have been relegated to <style> tags.
Example: Hockeystick, left-justified
Code Block | ||
---|---|---|
| ||
<!DOCTYPE html> <body> <style> #contentWrapper{background-color:yellow;height:800px;margin:auto;} #leaderboard {background-color:red;width:728px;height:90px;} #Hockeystick_1 {width:728px;height:90px;left:0px;background-color:orange;position:absolute;} #Hockeystick_2 {width:120px;height:600px;background-color:orange;left:728px;position:absolute;} #Content {height:500px;background-color:lightgreen;} </style> <div id="contentWrapper" style="min-width:1038px;"><!--min-Width is calculated from the minimal content width (here 728) plus right gap (310)--> <div id="leaderboard" style="position:relative;margin:0px 300px 0px auto;"> <div id="Hockeystick_1">Hockeystick</div> <div id="Hockeystick_2" style="">Hockeystick</div> </div> <div id="Content" style="margin:10px 310px 0px 0px; ">Content</div> </div> </body> </html> |
“sky” Ad Slot
Info |
---|
The “Skyscraper” advertising space is often used to deliver special formats with very high widths. |
Some formats, such as the “Dynamic Sidebar”, for instance, reserve the complete space between the left beginning of the skyscraper and the right browser margin. When integrating the Skyscraper it is therefore advisable to avoid the use of the attribute “float” in the surrounding HTML tags. This attribute positions elements in keeping with their height and width depending on the rest of the page and can result in the Skyscraper not being displayed on the right-hand side of the content anymore from a certain value onwards. This problem, however, is strongly related to the structure of the website and does not have to occur every time the attribute “float” is used.
“rectangle” Ad Slot
The ad slot “rectangle” is usually filled with advertising media from 300 x 250 up to 300 x 600 pixels.
To realize this, please ensure that the ad slot embedded within the content, is able to change its height dynamically without covering up the surrounding content or otherwise rendering it illegible.
“stickyfooter” Ad Slot
The “stickyfooter” ad slot is a mobile slot, in which small mobile formats (often 320x50 or 320x100 pixel) are rendered at the bottom corner of the users browser. Ads will scroll along with the user, and are permanently visible. The user can close the format via a small button.
When integrating this slot, please pass the “pinToBottom” option in the Slot.configure()
method. The sticky effect as well as the close button will be delivered automatically, no further set up is required.
Code Block |
---|
SDG.Publisher.registerSlot('stickyfooter','myStickyFooterContainer') .configure({pinToBottom: true}) .load(); |
Event System
Anchor | ||||
---|---|---|---|---|
|
MetaTag has its own set of JavaScript-Events which can be listened to over the JavScript method “addEventListener”. The system differentiates between two types of events:
system events
slot events
System Events
All system events use the "window" object, in where the metatag library is implemented under, as the "eventTarget".
Each event passes information about itself within the first argument given within the listener method.
Example for a system event:
Code Block | ||
---|---|---|
| ||
window.addEventListener('metaTagSystemBeforeLoadAll', function (eventObject) { console.log('system Event "metaTagSystemBeforeLoadAll", event information can be found here %o',eventObject) }); |
Available events on the window object:
Event | Description |
---|---|
metaTagSystemBeforeLoadAll | Gets triggered before the first call from an ad slot is send to the ad server. |
metaTagSystemContentLoaded | Gets triggered once the event DOMContentLoaded has fired |
metaTagSystemAdServerModuleLoaded | Gets triggered once MetaTag has decided which ad server to use on the website. |
metaTagSystemContentElementLoaded | Gets triggered when an Element has been found on the page which measurements coincide with the width and height of the content. Some formats do not start loading until this event has been fired. |
metaTagSystemPrebidResponded | Gets triggered once all real time auctions have finished from the open source solution "Prebid". Prebid is not active on all websites |
metaTagSystemZoneSet | Gets triggered once our interface method setZone() has been completed |
metaTagSystemPageTypeSet | Gets triggered once our interface method setPageType() has been completed |
metaTagSystemSlotRegistered | Gets triggered as soon as an ad slot is registered. This event contains general information for the ad slots. For more specific information about an ad slot please use the slot events |
metaTagSystemSlotDeleted | Gets triggered as soon as an ad slot is deleted or unregistered. This event contains general information for the ad slots. |
metaTagSystemSlotPrepared | Gets triggered once an ad slot has received all information needed to start a call to the ad server. |
metaTagSystemSlotCalling | Gets triggered once an ad slot starts a call to the ad server. This event contains general information for the ad slots. |
metaTagSystemSlotResponded | Gets triggered once an ad slot receives an answer from the ad server. This event contains general information for the ad slots. |
metaTagSystemSlotDone | Gets triggered once an ad slot has received an answer from the ad server and the slot has finished rendering an advertisement. This event contains general information for the ad slots. For more specific information about an ad slot please use the slot events. |
metaTagSystemSlotEmpty | Gets triggered once an ad slot receives an answer from the ad server that no advertisement is available. |
metaTagSystemCmpConsentAvailable | Gets triggered once the user has set his/her consent for all vendors (IAB/Non IAB). At this point in the systems process you are able to get the consent information pro vendor from our publisher interface methods: SDG.Publisher.getIABVendorConsent() or SDG.Publisher.getCustomVendorConsent(). |
metaTagSystemCmpChoiceUiShown | This event signals that the user is being shown a message layer from the consent manager. This layer covers most of the elements from the webpage. It is encouraged that |
metaTagSystemCmpChoiceSelected | Gets triggered once the user has finished interacting with the communication layer of the consent manager platform. |
Slot Events
These events use the DOM node in which the ad slot was registered as the "eventTarget".
Aside from the information available about the event itself, additionally you can access information about the ad slot. For this use the first argument given through the listener method.
The data from the ad slot is available in "eventObject.detail". Since the ad slot starts firing multiple events after its registration it is advised to set your listeners before the ad slot gets registered.
Example for a slot event:
Code Block | ||
---|---|---|
| ||
<div id="mySkySlot"></div> <script> document.getElementById('mySkySlot').addEventListener('metaTagSlotCalling', function (eventObject) { console.log('system Event "metaTagSlotCalling", event information can be found here %o',eventObject); console.log('additionally the name of the ad slot is saved here %o',eventObject.detail.slot); }); SDG.Publisher.register('sky', document.getElementById('mySkySlot')).load(); </script> |
Available slot events:
Event | Description |
---|---|
metaTagSlotRegistered | The slot beeing listend on has been registerd and is available |
metaTagSlotDeleted | The slot beeing listend on has been unregistered/deleted and will not fire any more events. |
metaTagSlotCalling | The slot being listened on got the command to load an advertisement and will call the ad server |
metaTagSlotResponded | The slot being listened on has received and answer from the ad server, slot has not been rendered yet. |
metaTagSlotDone | The slot being listend on has completed its process. It has received an answer from the ad server and the slot has finished rendering an advertisement |
metaTagSlotEmpty | The slot being listened on did not receive an advertisement from the ad server. The slot removes itself from the webpage and does not reserve any more space on the page. This event will not necessarily fire consistently. |
Additional Features
MetaTag brings a few additional features helping with the day to day handling of ad formats.
If you have any questions concerning which options are available, please consult your Account Manager at Ströer.
Labeling ad slots with "Anzeige" (advertisements)
MetaTag can label your ad slots with the word "Anzeige" (advertisements). This label can be localized to your needs or changed for example into "promotion" if this is preferred.
Ad labels should always be attached and are required under certain circumstances by law.
Per default MetaTag will always deliver ad labels, this can be turned off if you would like to take care of the labeling yourself.
If you wish to change/remove/add these labels, please see the Slot.configure() method
Define local ad slots
For your website you can define your own ad slots (for example: to book your own local advertisements). Please contact us before implementing a local ad slot.
In order to create and register a local ad slot you will need to use a different method than usual.
Code Block | ||
---|---|---|
| ||
SDG.Publisher.registerModularSlot(position, container, width, height, adServerSizes, isMobile, useSubzone) |
Method arguments for registerModularSlot()
Code Block |
---|
@param {String} position - the self selected name of the new position. This name will be extended with the prefix "local_" by the tag manager, to avoid collision with other ad slots. If your self selected name is "rectangle", the slot will be registered as "local_rectangle" @param {String||Object} container - the container of the ad slot, either as ID string or as DOM Node Object if the container already exists @param {Number} width - the width of the ad slot, how it is rendered on the page @param {Number} height - the height of the ad slot, how it is rendered on the page @param {Array.<Array>} adServerSizes - nested array of the adserver sizes used for the new position @param {Boolean} isMobile - true/false if the slot is a mobile slot @param {String} useSubzone - the name which an ad slot will use as subZone. Can be used to create an artifical "sub section" for this ad slot (optional) |
When accessing the local ad slot at a later time, please make sure to always include the automatically added prefix.
Code Block |
---|
SDG.Publisher.registerModularSlot('my-rectangle', 'myContainer', 300, 250, [[300,250]], false) SDG.Publisher.loadSlot('local_my-rectangle'); |
MetaTag Video-Ads
MetaTag-Video provides the Publisher with the possibility to easily setup a connection to any video ad server per VAST or VPAID. Formats like "Pre-Roll", "Mid-roll" or "Post-Roll" can be implemented into your video player.
Your video player must support the IAB standard VAST (Video Ad Serving Template). In order to receive VAST URLs from MetaTag, please see the PublisherApi method Publisher.generateVastUrls()
We can gladly discuss an individual integration in your current video system. Questions regarding IAB-Standards, Video formats or popular video-SDK's for desktop or mobile. Feel free to contact your Publisher Account Manager at Ströer.
Lazy Load
Anchor | ||||
---|---|---|---|---|
|
When an ad slot is “lazy loaded”, the slot will contact the Ad Server as soon as you indicate that you like the Ad Slot to load. For example, by using the /wiki/spaces/SDGPUBLIC/pages/51578793 interface. Rendering of the content of the ad slot however, will only start shortly before the user scrolls the ad into view.
Tip |
---|
This will help use as little resources as possible on the users devices and might improve the loading performance of your website tremendously. |
Note |
---|
An Ad Slot is only eligible for counting towards “guaranteed traffic” if the Ad Slot starts to render. Subsequently, only a rendered ad will be paid for by the advertiser. This feature might have impacts on the revenue of your website. We strongly recommend testing the effect of “Lazy Load” and weight the results against the gains of website load performance and layout shift reduction. |
If you are interested in using this feature, please contact your Account Manager at Ströer. We will check the possible impact on your website's revenue and help you discover the best implementation strategies.
You can test and activate lazy loading for an ad slot at any time, using our Slot.configure() method.
Expand | ||
---|---|---|
| ||
Avoiding Cumulative Layout Shift
Anchor | ||||
---|---|---|---|---|
|
So-called “Layout shifts” are, in short, height changes to a website, after the user is interacting with the site.
This might lead to content changing positions while the user reads it, or interactive elements vanishing shortly before the user wanted to interact with them.
Layout shifts will also have a negative impact on Googles “Web Vitals Score” of your website, potentially causing your website being penalized in Googles Search ranking.
Height changes to the content are often introduced by loading large-dimensioned parts of the website asynchronously, for example advertisements.
While loading ads asynchronously helps tremendously with the performance of the website, it introduces many forms of “layout shifts”
Ad Slots inside the pages can support multiple, different formats, each with a unique height.
When loading those Ad Slots, information about the delivered formats and their height are only available after ads are already rendered to the page (causing the shift).Ad Slots can be reloaded during longer sessions. Removing old ads and inserting new ads might lead to different heights being reserved by the Ad Slot.
Ad Slots might not deliver an ad on each Page Impressions, because campaigns and advertisements might not be available.
Nevertheless, the Ad Slot has to perform a call to the Ad Server to check for ads, causing a possible reservation of space on the site.
Solutions
To lessen the impact of ads to the content of the website, without sacrificing revenue potentials, MetaTag supports multiple distinct solutions.
Solutions can be combined with one another, potentially removing layout shifts completely.
Registering AdSlots on start of the website
MetaTag is able to receive all relevant information for “Ad Slots” inside the <head> HTMLElement of the website. Using the interface methods/wiki/spaces/SDGPUBLIC/pages/51578793 and /wiki/spaces/SDGPUBLIC/pages/51578793 early, the TagManager is able to reserve needed space for the ad slots as soon as the browser starts to render your website. Use our command queue to register ad slots as soon as possible.
Load processes of your site will not be impacted by registering Ad Slots inside the <head> HTMLElement. However, loading the Ad Slot (and automatically rendering the ad contents) will impact the performance of your site negatively.
Consider using “LazyLoad AdSlots” to remedy this.
Strict AdSlots
An ad slot consists of different “Formats”, which may be displayed by the slot. Each possible format has a pixel “width” and “height”.
When employing “strict ad slots”, MetaTag will reserve the largest possible height, of all available formats, on the ad slot. Reservation will take place before the user scrolls the Ad Slot into view or an ad is delivered.
This will avoid layout shift completely but will lead to large “empty spaces” on your site, until ads are finally delivered.
Ads inside the slot will be centered and scrolled alongside with the user, should the delivered ad be smaller than the reserved space.
You can watch a demonstration of this behavior
Alternatively you can set a fixed height by employing the Slot.configure() method. This is helpful if you like to reserve some space for an adslot, but like to have control about the exact height used.
Please note: If the Ad Slot can not be filled with an ad, with strict mode enabled the slot will remain empty and will not be hidden.
To remedy this you can can fill the Ad Slot with your own content, for example an image/text teaser, for more details see the “Native Backfills” section.
This feature can be activated by contacting your Ströer representative or sending us a ticket via our Publisher Support Center (separate account required).
Detailed information about how MetaTag is calculating/handling how much space to reserve, can be found in our documentation: TagManager guidelines for avoiding "Layout Shift"
Loading Animations
When employing “Strict Ad Slots”, it may happen that the user already will see a slot, that is not filled with an ad yet. Since strict ad slots will reserve a fixed height and width for the slot, this empty space might be jarring to look at or signal to the user that the website is not functioning correctly.
To solve this, we can activate icon animations inside the Ad Slot, that will imply that the content is still loading. As soon as an ad is delivered, the animations will be removed.
Loading animations can be activated for the whole site, with 3 different options available. Please contact your Ströer representative or send us a ticket via our Publisher Support Center (separate account required) to start the process.
Expand | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||
Option 1 - Bounce
Option 2 - Circle
Option 3 - Wave
|
Consent Management Platform
Expand | ||
---|---|---|
| ||
A Consent Management Platform (CMP) allows to collect users decisions, how their personalized data can be processed by the website and connected service providers. For more information about how to integrate such a CMP, please see our documentation: Consent Management for Websites
The consent of the user for processing personalized data is informed by an categorisation of different, possible usages of this data. Each service provider integrated into a website might use some or all data in diverse ways (deliver personalized content, display only relevant ads, etc). To allow the user to give a well-informed decision, these usages are clustered into a manageable amount of categories, which in turn the user can consent or decline.
By consenting or declining a category, all service providers inside such a category will be allowed or blocked,
Classification and categorisation of service providers is done by the industry association “Interactive Advertising Bureau (IAB)” based upon the advertising industry-standard “Transparency & Consent Framework (TCF)” . Service providers, which already have been classified, are named “IAB vendors” in the upcoming guide. Non-classified service providers are used as “non-IAB vendors”.
After the user chooses whether to give consent or not, we (Ströer) block/allow all IAB-vendors, which are related and responsible for advertisement. You will not need to do anything for managing these vendors.
Should you use any vendors yourself (IAB or Non-IAB), you will need to ask your users for permission to send personalized data to these vendors.
In case the user does not wish to consent to specific service providers or whole categories, you will have to block these vendors and make sure they will not be activated or delivered to the user.
This might have different impacts for each vendor. Some can still function without any form of personalized data, some will not function at all.
Please contact your vendors / service providers to understand the full technical implementation.
TagManager behaviour with user consent
As soon as a Consent Management Platform is detected on your website, MetaTag will not deliver any advertisements, until the user has decided how their personalized data should be handled.
Some scripts and or vendors, which do not collect any personalized data, might be loaded before the user gives their consent. These scripts are rigorously tested and monitored, to always ensure full compliance.
Other vendors or scripts, which might collect personalized data, are delayed until the user’s decision.
To subsequently deliver any ads (even non-personalized), the user needs at minimum allow the following IAB Transparency & Consent Framework data usages for all involved vendors:
Select basic ads (Purpose 2)
Measure ad performance (Purpose 7)
Apply market research to generate audience insights (Purpose 9)
Develop and improve products (Purpose 10)
These purposes need to be either consented to by the user (user opts-in to the purposes), or the website needs to claim “legitimate interest” for these purpose (meaning the user does not explicitly refuse / opt-out)
Note |
---|
Should the user refuse these purpose (opt-out), no ads will be delivered on the website and no ad impression will be generated or counted. |
For delivering personalized ads and to allow for full monetization of a website, users need to consent fully to the above purposes and additionally to:
Store and/or access information on a device (Purpose 1)
Create a personalized ads profile (Purposes 3)
Select personalized ads (Purposes 4)
CMP interfaces for user consent
When trying to build complex logic based on the consent or refusal of the user (especially when you try to determine which data usage categories specifically where declined), interfacing directly with the CMP is the fastest and safest way.
Each IAB TCF compatible CMP provides a JavaScript interface method called “__tcfapi()” present on the main window object, to which the CMP was delivered.
Extensive documentation for this interface is available on the GitHub page of the IAB: InteractiveAdvertisingBureau / GDPR-Transparency-and-Consent-Framework / Consent Management Platform API
Simplified Example
Code Block | ||
---|---|---|
| ||
/** * We like to check multiple data purposes at once, and based on the result, load vendors if consent was available for data purpose 1,2,4,7. * For in-depth explanation what the purposes are and do, see: https://iabeurope.eu/iab-europe-transparency-consent-framework-policies/#Appendix_A_Purposes_and_Features_Definitions * * First we make sure to only get a consent status, when the user has decided and closed the CMP layer. * We register an eventListener with the tcfapi() and will react only when the returned eventStatus is "tcloaded" or "useractioncomplete" * * Secondly we will parse the returned consent status from the tcfapi() and check if the purpose 1,2,4,7 have consent from the user. * If consent for 1,2,4,7 is granted, continue with our logic loadPublisherVendors() and remove the eventListener from the tcfapi() * */ __tcfapi('addEventListener', 2, function (consentData, callbackSuccessfull) { let status = consentData.eventStatus, purposeConsents = consentData.purpose.consents; if (callbackSuccessfull && (status === 'tcloaded' || status === 'useractioncomplete')) { if(purposeConsents['1'] === true && purposeConsents['2'] === true && purposeConsents['4'] === true && purposeConsents['7'] === true) { publisherScript.loadPublisherVendors() window.__tcfapi('removeEventListener', 2, function () {}, consentData.listenerId); } } }); |
Another use case might be to pass the complete consent information to another system / vendor, so these systems can decide for themselves which usages of personalized data are allowed and react on their own.
For this the __tcfapi() provides a “base-64” encoded string, which includes information about all vendors, purposes and the users decision in a compact, easily transmittable format. To signal a vendor that the user is originating from an GDPR relevant country, most vendors require an indicator, often a boolean switch called “gdprApplies”. These “tcString” and “gdprApllies” parameters are recognized and useable by most vendors in the web eco-system. Please consult the documentation of you vendor to see how you can specifically pass along this information.
Subsequenly the following example shows calling the tcfapi(), requesting “tcString” and “gdprApplies” and forwarding them to a video player.
Code Block | ||
---|---|---|
| ||
/** * The setupPlayer method will take 2 optional arguments. Should we be able to recover consent data, make the data available inside the setupPlayer method. * Other functions inside the video player will be able to use the consent data, for example when constructing a video advertisement request. * If no consent data is available, setup the player normally. */ let setupPlayer = function(gdprApplies, tcString) { let GDPR = gdprApplies ? 1 : 0; let GDPR_CONSENT = tcString ? tcString : ''; // setup your player here, use GDPR and GDPR_CONSENT variables when constructing the VAST-URL }; if( typeof window.__tcfapi !== 'undefined' ) { window.__tcfapi('addEventListener', 2, function (tcData, success) { if (success && tcData && (tcData.eventStatus === 'tcloaded' || tcData.eventStatus === 'useractioncomplete') && tcData.tcString && tcData.tcString.length > 0) { setupPlayer(tcData.gdprApplies, tcData.tcString); window.__tcfapi('removeEventListener', 2, function () {}, tcData.listenerId); } }); } else { setupPlayer(); } |
Embedding social media plugins
In some cases users might decline consent for some data usages or vendors, but later would like to see content from these vendors (for example: User refused Twitter to use personalized data, but the content of your website includes a Twitter plugin. The user likes to change their decision.)
Most CMPs allow the change of consent for a single vendor on the fly.
Depending on your used CMP, the necessary steps might be different. Please see the documentation of your CMP.
Example for SourcePoint CMP (allowing CustomVendor “Twitter Inc”, internal Id: “5ec85c9cb8e05c4a2002f42e”) after the user clicked some kind of “I accept Twitter Inc.” button:
Code Block |
---|
/** * Method takes 4 arguments: * callback {function} * vendorIds {Array<string>} * consent data purposes {Array<string>} * legitimate interest data purposes {Array<string>} * documentation for this method can be found at Sourcepoints documentation hub: https://documentation.sourcepoint.com/web-implementation/web-implementation/sourcepoint-gdpr-and-tcf-v2-support/the-__tcfapi-gettcdata-api-overview/__tcfapi-postcustomconsent-api */ __tcfapi('postCustomConsent', 2, function(data) {console.log(data)}, ["5ec85c9cb8e05c4a2002f42e"],[],[]) |
Documentation for other CMPs: