我为我的Angular2应用程序添加了Google跟踪代码管理器支持,我不知道如何为开发与生产注入所需的不同容器ID所需的GTM脚本,因为我有两个GTM中的容器。
有没有办法注入head标签并根据环境文件中的变量更改容器ID?
我在构建过程中使用Angular CLI。
答案 0 :(得分:0)
您可以为Tag Manager构建一个服务,我自己为我的公司项目构建了一个服务,该项目为AdWords
,Google Trusted Stores
和Analytics
等提供商处理多个容器ID和事件。
这是注入标记管理器脚本的模型的示例版本。 (注意:由于直接使用document
和window
,因此无法通用。)
export class TagManager {
private static instance: TagManager = null;
private ids: string[];
private dataLayerName: string;
private precision: number = 2;
public dataLayer: any[] = [];
public language: string;
public currency: string;
constructor(ids: string[], dataLayerName: string, language: string, currency: string) {
if(TagManager.instance) {
throw new Error("Error - use GoogleTagManager.getInstance()");
}
this.ids = ids;
this.dataLayerName = dataLayerName;
this.currency = currency;
this.language = language;
this.init();
}
private init() {
this.ids.forEach(id => this.initContainer(id));
}
private initContainer(id: string) {
let internal = this;
(function(w,d,s,l,i) {
w[l]=w[l]||[];
w[l].push({
'gtm.start': new Date().getTime(),
event:'gtm.js'
});
let f: any = d.getElementsByTagName(s)[0];
let j: any = d.createElement(s);
let dl: any = l!='dataLayer'?'&l='+l:'';
j.async=true;
j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
internal.dataLayer = w[l];
})(window,document,'script',this.dataLayerName,id);
}
public static getInstance(ids: string | string[] = [], dataLayerName = 'dataLayer', language = 'en', currency = 'EUR') {
ids = ids || [];
ids = Array.isArray(ids)? ids: [ids];
if(!TagManager.instance) {
if(ids.length === 0) {
return;
}
ids.forEach(id => {
if(!id || (typeof id !== 'string') || id.indexOf('GTM-') !== 0) {
console.error("Please provide a valid container ID (i.e. GTM-XXXXXX)");
}
})
if(!dataLayerName || (typeof dataLayerName !== 'string')) {
console.error("Please provide a valid name for the data layer");
}
}
TagManager.instance = TagManager.instance || new TagManager(ids, dataLayerName, language, currency);
return TagManager.instance;
}
}
服务示例:
@Injectable()
export class Service {
private static instance: TagManager = null;
private eventTracker$: ReplaySubject<any> = new ReplaySubject();
private dataStream$: ReplaySubject<any> = new ReplaySubject();
private currency: string;
private precision: number = 3;
private language: string;
private readyTracker$: ReplaySubject<boolean> = new ReplaySubject<boolean>();
public get settings() {
return {
language: this.language,
currency: this.currency,
precision: this.precision
}
}
public get eventTrack$() {
return this.eventTracker$.asObservable();
}
public get dataLayer$() {
return this.dataStream$.asObservable();
}
public get isReady$() {
return this.readyTracker$.asObservable();
}
public get isInitialized() {
return !!Service.instance;
}
constructor() {
this.readyTracker$.next(false);
}
public init(containerIds?: string[], dataLayerName?: string, language?: string, currency?: string) {
if(Service.instance instanceof TagManager) {
console.error('Google tag manager already loaded.');
return;
}
Service.instance = TagManager.getInstance(containerIds || [], dataLayerName || 'dataLayer', language || 'en', currency || 'EUR');
this.currency = currency;
this.language = language;
if(!Service.instance) {
console.info('no gtm container installed');
return;
}
this.dataLayer$.subscribe(e => {
Service.instance.dataLayer.push(e);
});
this.readyTracker$.next(true);
}
public push(data: any) {
this.dataStream$.next(data);
}
public pushCustomEvent(eventName: string, attributes: any) {
this.push({
event: eventName,
attributes: attributes
});
}
public pushEcommerceEvent(eventName: string, eventData: any) {
this.push(Object.assign({}, {
event: eventName
}, eventData))
}
}
AdWords提供商示例:
@Injectable()
export class AdwordsProvider {
constructor(private gtmService: Service) { }
public sendConversion(id: string, value: number) {
// build conversion
let conversion = {
[Fields.Conversion.attributes.id]: id,
[Fields.Conversion.attributes.value]: Number.parseFloat(value.toFixed(this.gtmService.settings.precision)).toString(),
[Fields.Conversion.attributes.currency]: this.gtmService.settings.currency
};
// push event to dataLayer
this.gtmService.pushCustomEvent('conversionEventName', {
// event data
});
}
}
或者你可以看一下angulartics2,也许它符合你的需要。