在Google Tag Manager中将googletag转换为自定义模板问题咨询
问题详情
简介
我需要在多个页面投放广告,此前为每个页面创建仅在对应页面触发的tag,每个页面要么仅配置leaderboard广告位,要么同时配置leaderboard及其他小尺寸广告位,原有实现示例如下:
<script async src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"></script> <script> window.googletag = window.googletag || {cmd: []}; googletag.cmd.push(function() { googletag.defineSlot(OurAdUnitPath, [728, 90], 'leaderboard').addService(googletag.pubads()); googletag.pubads().enableSingleRequest(); googletag.enableServices(); }); </script>
遇到的问题
我尝试将上述逻辑转换为GTM自定义模板,但无论怎么调整都无法正常展示广告,麻烦帮忙排查代码存在的问题。
完整自定义模板代码
输入参数说明
| 参数 | 说明 | 示例 |
|---|---|---|
| data.ad_types | 待添加到页面的广告类型列表 | [{ ad_type: 'leaderboard' }] |
| data.ad_id | 广告位目标容器ID | leaderboard |
模板代码
const copyFromWindow = require('copyFromWindow'); const injectScript = require('injectScript'); const setInWindow = require('setInWindow'); const createArgumentsQueue = require('createArgumentsQueue'); // Get ad ID and types from data const adTypes = data.ad_types; const adId = data.ad_id; injectScript("https://securepubads.g.doubleclick.net/tag/js/gpt.js"); let googletag = copyFromWindow('googletag'); googletag = setInWindow('googletag', googletag || {cmd: []}, true); googletag = copyFromWindow('googletag'); googletag.cmd.push(function() { // Loop through all the ad types and define the slots for(let i = 0; i < adTypes.length; i++) { const adType = adTypes[i].ad_type; googletag.defineSlot(OurAdUnitPath + adId + '/' + adType, [728, 90], adType).addService(googletag.pubads()); } googletag.pubads().enableSingleRequest(); googletag.enableServices(); }); googletag.cmd.push(function () { googletag.display(adId); }); // Call data.gtmOnSuccess when the tag is finished data.gtmOnSuccess();
问题排查及修复方案
存在的问题
- 脚本加载逻辑异步不匹配:
injectScript是异步加载方法,现有代码直接在调用后同步执行GPT逻辑,大概率出现gpt.js未加载完成就执行后续代码的情况,导致API调用失败。 OurAdUnitPath变量未声明:GTM自定义模板运行在沙箱环境,无法直接读取页面全局变量,你没有显式获取该变量,导致广告位路径参数错误。display方法参数不匹配:googletag.display需要传入defineSlot时设置的第三个参数(广告位容器ID),现有代码defineSlot传的是adType,调用display时传的是adId,二者对不上导致找不到渲染容器。- 广告位尺寸写死:所有广告位都固定为728*90尺寸,和你需求里的小尺寸广告位不匹配,尺寸不符时广告平台不会返回对应物料。
- cmd队列初始化不规范:手动赋值
googletag.cmd队列容易和页面已有的GPT实例冲突,GTM官方推荐使用createArgumentsQueue方法初始化队列。
修正后代码
const copyFromWindow = require('copyFromWindow'); const injectScript = require('injectScript'); const createArgumentsQueue = require('createArgumentsQueue'); const log = require('logToConsole'); // 从模板输入参数获取配置 const adTypes = data.ad_types; // 新增模板参数:广告单元根路径,也可以用copyFromWindow('OurAdUnitPath')从全局取 const adUnitRootPath = data.ad_unit_root_path; // 初始化GPT队列,兼容已有实例 const googletag = createArgumentsQueue('googletag', 'cmd', copyFromWindow('googletag')); // 脚本加载成功后再执行GPT逻辑 injectScript("https://securepubads.g.doubleclick.net/tag/js/gpt.js", () => { googletag.cmd.push(function() { // 循环定义所有广告位 adTypes.forEach(adConfig => { const adType = adConfig.ad_type; const adSize = adConfig.size || [728, 90]; // 从参数取尺寸,默认728*90 googletag.defineSlot(`${adUnitRootPath}/${adType}`, adSize, adType) .addService(googletag.pubads()); }); googletag.pubads().enableSingleRequest(); googletag.enableServices(); // 所有广告位定义完成后统一渲染 adTypes.forEach(adConfig => { googletag.display(adConfig.ad_type); }); data.gtmOnSuccess(); }); }, () => { log('GPT脚本加载失败'); data.gtmOnFailure(); });
配套调整说明
- 新增模板输入参数
ad_unit_root_path,对应你原来的OurAdUnitPath变量值 - 调整
ad_types参数结构,新增size字段,示例:[{ ad_type: 'leaderboard', size: [728,90] }, { ad_type: 'sidebar', size: [300,250] }]
内容的提问来源于stack exchange,提问作者Cédric Bloem
相关产品推荐
相关产品推荐

