Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite scroll – refresh same ad units but in new div #1811

Closed
pribeh opened this issue Nov 8, 2017 · 9 comments
Closed

Infinite scroll – refresh same ad units but in new div #1811

pribeh opened this issue Nov 8, 2017 · 9 comments
Labels

Comments

@pribeh
Copy link

pribeh commented Nov 8, 2017

Type of issue

We're attempting to migrate an ad setup which involves loading the same 3-4 ad units/slots across multiple pages of the same article to an ajax solution where each new page's content is loaded underneath via a button press (kind of like infinite scroll).

Description

We were wondering if there might be a way to refresh the same set of ads (or rerun prebid) but only in the new container. We're aware of the refresh ad unit documentation but not sure how to target the same ad units in a new div and how to do that repeatedly (ad infinitum).

Any help or pointers would be much appreciated. Here's an html breakdown of what we're aiming to achieve.

<body>

<div id="content">
<ad-slot-1/>
<ad-slot-2/>
<ad-slot-3/>
</div>

<button class="ajax-link" rel="#content-2-load" onclick="refreshBid()">Read More</button>

<div id="content-2">
<ad-slot-1/>
<ad-slot-2/>
<ad-slot-3/>
</div>

<button class="ajax-link" rel="#content-3-load" onclick="refreshBid()">Read More</button>

<div id="content-3">
<ad-slot-1/>
<ad-slot-2/>
<ad-slot-3/>
</div>

</body>
@GLStephen
Copy link
Collaborator

@pribeh I'm riffing a bit here since I've not tested this exact approach, but you should be able to add the adunits to the adunits array then call addAdUnits() again and then run the auction with the infinite scroll logic.

Similarly, if you know the way the divs are built you can preload their names, and so long as you are not doing a global refresh style load and this ajax style load, the adunits will just be stored and not bid against until you call them specifically.

@pribeh
Copy link
Author

pribeh commented Nov 9, 2017

@GLStephen Thanks for chiming in. I'll see if I can give that a go and report back.

@YOzaz
Copy link

YOzaz commented Nov 16, 2017

@pribeh confirming this is possible, as long as <ad-slot-N/> identificator (adUnitCode, whichever you'll use) is unique. If you're serving ads through DFP, this is a mandatory thing - you won't be able to deliver ads otherwise. If you're serving directly, my suggestion would still be declaring them uniquely by adding a suffix of content-id - re-adding configuration - and running / refreshing Prebid auction on specific adUnitCodes only.
We have this already working on lazy-loaded ads, so feel free to ask questions, if any.

@pribeh
Copy link
Author

pribeh commented Nov 16, 2017

@YOzaz Thanks for letting me know! I haven't been able to get anywhere with this yet. And yes I'm using DFP.

I think my confusion lies with not knowing the the exact "thing" that needs to be distinct. Do I need to set up distinct units in DFP and prebid for each new unit I call an auction for or can I just generate unique codes on demand? Meaning, do I need 50 some ad units defined in prebid and DFP? Or, can I generate random codes for the units when I load a the same four ad units (as defined in DFP/prebid) on the page and rerun the auction each time?

@YOzaz
Copy link

YOzaz commented Nov 17, 2017

@pribeh from our experience, having separate DFP ad units even for infinite scrolls has some advantages - e.g. easier reporting, etc. But you can't generate enormous amount of them, have to limit yourself up to 10 for example (from the other hand, haven't seen any visitor who'd scroll more than 10 pages). That's why, usually, same DFP ad unit is re-used.
I don't know which template engine you're using for parsing custom tags, but see example below. Yes, DFP ad slot IDs must be unique for every instance on a page - and that's how Prebid.js "maps" them on an auction. Assuming your ad-slot-N are custom HTML5 components, extending div - but GPT may not like it.
P.S. I suppose you have disableInitialLoad() set on GPT.
P.S.S. Note, code below is UNTESTED, and may have syntax errors.

<script>

(function(window, document)
{
	'use strict';
	
	var pbjs = pbjs || {};
	pbjs.que = pbjs.que || [];

	var googletag = googletag || {};
	googletag.cmd = googletag.cmd || [];

	var iterator = 0;

	window.refreshBid = function(element)
	{
		var config = [{
			// first ad unit config
			component: 'ad-slot-1',
			dfp_code: '/network_id/dfp_ad_unit_code_1',
			sizes: [/** ... **/],
			bids: [/** ... **/]
		}, {
			// second ad unit config
			component: 'ad-slot-2',
			dfp_code: '/network_id/dfp_ad_unit_code_2',
			sizes: [/** ... **/],
			bids: [/** ... **/]
		}, {
			// third ad unit config
			component: 'ad-slot-3',
			dfp_code: '/network_id/dfp_ad_unit_code_3',
			sizes: [/** ... **/],
			bids: [/** ... **/]
		}];

		var container = document.getElementById( element.getAttribute('rel') );
		
		googletag.cmd.push( function()
		{
			var slots = [];
			
			config.forEach( function( config_item, index )
			{
				var component_name = config_item.component;
				// get that custom element
				var component = container.getElementsByName(component_name)[0];
				
				// generate new DFP ID
				var new_ad_slot_id = 'div-gpt-ad-' + component_name + '-' + iterator;
				component.setAttribute('id', new_ad_slot_id);
				
				// store DFP ID on pbjs config
				config[index].code = new_ad_slot_id;
				
				// define GPT slot
				var new_dfp_slot = googletag.defineSlot( config_item.dfp_code, config_item.sizes, new_ad_slot_id ).addService(googletag.pubads());
				// assuming you have initial load disabled - display() is required for initialization - otherwise this needs to be moved below in bidsBackHandler and refresh() removed
				googletag.display( new_ad_slot_id );
				
				// store it for later reference on auction callback
				slots.push( new_dfp_slot );
			});
			
			pbjs.que.push( function()
			{
				pbjs.addAdUnits( config );

				// get newly generated IDs - or you can store them in array above of course
				var slotCodes = slots
					.map( function( slot ) { return slot.getSlotElementId() || ''; } )
					.filter( function( id ) { return id; } );

				// run auction only for newly generated DFP IDs
				pbjs.requestBids({
					adUnitCodes: slotCodes,
					bidsBackHandler: function( bidResponses )
					{
						pbjs.setTargetingForGPTAsync( slotCodes );
						googletag.pubads().refresh( slots );
					}
				) );
			});
				
			} );
		});
		
		iterator++;
	};
	
	// wait for DOM to load - and launch first non-ajax auction
	
	document.addEventListener("DOMContentLoaded", function(event)
	{
		refreshBid( document.getElementById('content') );
	} );
  
});

})(window, document);

</script>

<div id="content">

	<ad-slot-1/>
	<ad-slot-2/>
	<ad-slot-3/>
	
</div>

<button class="ajax-link" rel="content-2" onclick="refreshBid(this)">Read More</button>

<div id="content-2">

	<ad-slot-1/>
	<ad-slot-2/>
	<ad-slot-3/>
	
</div>

<button class="ajax-link" rel="content-3" onclick="refreshBid(this)">Read More</button>

<div id="content-3">

	<ad-slot-1/>
	<ad-slot-2/>
	<ad-slot-3/>
	
</div>

What we're doing here is just on every Ajax load (or button click in this case) generating new ad unit IDs, defining GPT slots, passing new IDs to pbjs.addAdUnits() and pbjs.requestBids() calls, and running callback on them on successful auction.

There are alternatives for this - which is using custom components callbacks (if you're using AngularJS - you can run auction on directive load, throttled), call queues, etc.

Cheers.

@YOzaz
Copy link

YOzaz commented Nov 17, 2017

Ah, to answer your question - DFP allows having unlimited amount of same ad slots defined on same page, as long as DIV IDs are unique - see here: https://support.google.com/dfp_premium/answer/4578089#infiniteContents.
The way you're telling Prebid.js which auction is mapped to what is up to you (using code field) - but usually it's DIV ID. So yes, generate unique IDs with same DFP slots, and run auction with them only.

See here: https://github.com/prebid/Prebid.js/blob/master/src/targeting.js#L54 - you can use either DFP ad unit path / code (which is unsuitable in our case), or GPT DIV IDs.

@pribeh
Copy link
Author

pribeh commented Nov 20, 2017

Thanks so much for the info @YOzaz. I'm going to give this a go over the next couple days and report back with my successes (hopefully).

@ptomasroos
Copy link
Contributor

I've actually sent a PR since this was bothering us as well @pribeh #1876

@stale
Copy link

stale bot commented Mar 6, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Mar 6, 2018
@stale stale bot closed this as completed Mar 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants