prebid / Prebid.js

Setup and manage header bidding advertising partners without writing code or confusing line items. Prebid.js is open source and free.
https://docs.prebid.org
Apache License 2.0
1.33k stars 2.08k forks source link

Need help with responsive ads and bid requests #1274

Closed sparklette closed 7 years ago

sparklette commented 7 years ago

Type of issue

I would appreciate if someone here can catch what I'm doing wrong with my prebid code.

I am new to header bidding, and recently implemented prebid.js on my site. It worked correctly the first two days, except that there were mobile ad sizes showing on desktop and desktop ad sizes on mobile. So what I did on the third day was to make the ad units responsive, but I must have done something wrong because right after implementing the codes for responsiveness, my filled impressions with each of the bidding partners dropped sharply, from about 10% fill rate to 1% after.

Description

There are 3 bidding partners for now. Here are my 2 ad units and their responsive sizes I want to show.

Header unit:

Sidebar unit:

I use window.innerWidth to detect the window's content area, and make bid requests for the correct ad sizes accordingly. For example, the header unit only requests bids for 728x90 and 970x250 on desktop, and 320x50, 320x100 and 300x250 on mobile. The sidebar unit only requests bids on desktop, and not make any bid request at all on mobile.

The DFP ad tags also have sizeMapping so that the correct ad unit sizes are rendered.

Changes I made that may have caused filled impressions to fall

Here's the complete code that I have on my pages. I am using Prebid.js v0.24.1. Can anyone let me know if there's anything wrong with it?

    <script type="text/javascript" src="xxx/prebid.js"></script>
    <script> 
    var PREBID_TIMEOUT = 2000;

    if (window.innerWidth >= 1024) { // Request bids for desktop ad units
        var adUnits = [{
             code: 'div-gpt-ad-header-0', // Header ad unit
             sizes: [[728, 90], [970, 250]],
             bids: [
            {
                bidder: 'sovrn',
                params: {
                   tagid: 'xxx' // 728x90
                }
            }, {
                bidder: 'sovrn',
                params: {
                   tagid: 'xxx' // 970x250
                }
            }, {
                bidder: 'gumgum',
                params: {
                    inSlot: 'xxx' // 728x90
                }
            }, {
                bidder: 'sekindoapn',
                params: {
                    placementId: 'xxx' // 728x90
                }
            }, {
                bidder: 'sekindoapn',
                params: {
                    placementId: 'xxx' // 970x250
                }
            }
            ]},
        {
            code: 'div-gpt-ad-sidebar-0', // Sidebar ad unit
            sizes: [[300, 250]],
            bids: [{
                bidder: 'sovrn',
                params: {
                   tagid: 'xxx' // 300x250
                }
            }, {
                bidder: 'gumgum',
                params: {
                    inSlot: 'xxx' // 300x250
                }
            }, {
                bidder: 'sekindoapn',
                params: {
                    placementId: 'xxx' // 300x250
                }
            }]
        }];
    } else if (window.innerWidth > 720) { // Request bids for tablet ad units
        var adUnits = [{
             code: 'div-gpt-ad-header-0', // Header ad unit
             sizes: [[728, 90]],
             bids: [
            {
                bidder: 'sovrn',
                params: {
                   tagid: 'xxx' // 728x90
                }
            }, {
                bidder: 'gumgum',
                params: {
                    inSlot: 'xxx' // 728x90
                }
            }, {
                bidder: 'sekindoapn',
                params: {
                    placementId: 'xxx' // 728x90
                }
            }]
        }];
    } else { // Request bids for mobile ad units
        var adUnits = [{
             code: 'div-gpt-ad-header-0', // Header ad unit
             sizes: [[320, 50], [320, 100], [300, 250]],
             bids: [{
                bidder: 'sovrn',
                params: {
                   tagid: 'xxx' // 320x50
                }
            }, {
                bidder: 'sovrn',
                params: {
                   tagid: 'xxx' // 320x100
                }
            }, {
                bidder: 'sovrn',
                params: {
                   tagid: 'xxx' // 300x250
                }
            }, {
                bidder: 'gumgum',
                params: {
                    inSlot: 'xxx' // 320x50
                }
            }, {
                bidder: 'gumgum',
                params: {
                    inSlot: 'xxx' // 300x250
                }
            }, {
                bidder: 'sekindoapn',
                params: {
                    placementId: 'xxx' // 320x50
                }
            }, {
                bidder: 'sekindoapn',
                params: {
                    placementId: 'xxx' // 320x100
                }
            }, {
                bidder: 'sekindoapn',
                params: {
                    placementId: 'xxx' // 300x250
                }
            }]
        }];
    }

    var pbjs = pbjs || {};
    pbjs.que = pbjs.que || [];

    const customConfigObject = {
      "buckets" : [{
          "precision": 2,
          "min" : 0,
          "max" : 20,
          "increment" : 0.05
        }]
    };

    //set custom config object
    pbjs.setPriceGranularity(customConfigObject);

    pbjs.bidderSettings = {
    standard: {
      adserverTargeting: [{
        key: "hb_bidder",
        val: function(bidResponse) {
          return bidResponse.bidderCode;
        }
      }, {
        key: "hb_adid",
        val: function(bidResponse) {
          return bidResponse.adId;
        }
      }, {
        key: "hb_pb",
        val: function(bidResponse) {
          if(bidResponse.cpm >= 20) return '20.00';
          return bidResponse.pbHg;
        }
      }]
    },
      sekindoapn: {
        bidCpmAdjustment : function(bidCpm){
          return bidCpm * 0.75;
        }
      }
    };

    </script>
    <!-- Prebid Config Section END -->

    <!-- Prebid Boilerplate Section START. No Need to Edit. -->
    <script>
    var googletag = googletag || {};
    googletag.cmd = googletag.cmd || [];
    googletag.cmd.push(function() {
        googletag.pubads().disableInitialLoad();
    });

    pbjs.que.push(function() {
        pbjs.addAdUnits(adUnits);
        pbjs.aliasBidder('appnexus', 'sekindoapn');
        pbjs.requestBids({
            bidsBackHandler: sendAdserverRequest
        });
    });

    function sendAdserverRequest() {
        if (pbjs.adserverRequestSent) return;
        pbjs.adserverRequestSent = true;
        googletag.cmd.push(function() {
            pbjs.que.push(function() {
                pbjs.setTargetingForGPTAsync();
                googletag.pubads().refresh();
            });
        });
    }

    setTimeout(function() {
        sendAdserverRequest();
    }, PREBID_TIMEOUT);

    </script>

    <script type='text/javascript'>
      var googletag = googletag || {};
      googletag.cmd = googletag.cmd || [];        
      (function() {
        var gads = document.createElement('script');
        gads.async = true;
        gads.type = 'text/javascript';
        var useSSL = 'https:' == document.location.protocol;
        gads.src = (useSSL ? 'https:' : 'http:') +
          '//www.googletagservices.com/tag/js/gpt.js';
        var node = document.getElementsByTagName('script')[0];
        node.parentNode.insertBefore(gads, node);
      })();
    </script>

    <script type='text/javascript'>
      googletag.cmd.push(function() {
        var gptAdSlots = [];

        var headerMap = googletag.sizeMapping().
            // Desktop
            addSize([1024, 200], [[728, 90], [970, 250]]).
            // Tablet
            addSize([720, 200], [728, 90]).
            // Mobile
            addSize([0,0], [[320, 50], [320, 100], [300, 250]]).
            build();

        var sidebarMap = googletag.sizeMapping().
            // Desktop, Landscape Tablet
            addSize([1024, 200], [300, 250]).
            // Mobile, Portrait Tablet
            addSize([0,0], []).
            build();

        gptAdSlots[0] = googletag.defineSlot('/xxx/Site_Header', [320,50], 'div-gpt-ad-header-0').
          defineSizeMapping(headerMap).
          setCollapseEmptyDiv(true).
          addService(googletag.pubads());

        gptAdSlots[1] = googletag.defineSlot('/xxx/Site_Sidebar', [300, 250], 'div-gpt-ad-sidebar-0').
          defineSizeMapping(sidebarMap).
          setCollapseEmptyDiv(true).
          addService(googletag.pubads());

        googletag.enableServices();
      });
    </script>
kizzard commented 7 years ago

The adserverTargeting property of the pbjs.bidderSettings is likely overriding your custom granularity settings (see red text in the docs here). As it is using bidResponse.pbHg, it's returning unrounded bids, which won't match your 5c ad server lines - meaning 4/5ths of bids could be lost.

I recommend removing the entire "standard" section of your pbjs.bidderSettings, as it's not required and is covered by the Prebid defaults and your custom granularity.

sparklette commented 7 years ago

Thank you for that! It's great that you were able to spot the problem right away. I will implement the change.