Pokud používáte automatické eventy v Google tag manageru vycházející z pojmenování universal analytics, tak se vám může stat, že při odesílání dat, odešlete data i z přechozí automatické událostí. Hodnoty proměnných dataLayeru přetákájí, pokud nepoužijete vždy všechny odesílané proměnné. Na tento jev často narazíte u starých projektů navržených digitálními agenturami, kdy se často odesilala kombinace kategorie a akce události. Jelikož často nebyvají kapacity opravy těchto detailů, přišel jsem s tímto článkem a návodem jak to řešit.
Ukázka chyby:
První odesílání dat do Google analytics je plné, všech šest proměnných.
window.dataLayer.push({ 'event' : 'send-data1', 'eventCategory' : 'data1-category', 'eventAction' : 'data1-Action', 'eventLabel' : 'data1-Label', 'eventValue' : 1500, 'eventNonInteraction' : true });}
Další odesílání dat zkrácené.
window.dataLayer.push({ 'event' : 'send-data2', 'eventCategory' : 'data2-category', 'eventAction' : 'data2-Action' });}
Výsledek pak je kombinace odelání dat 1 a 2 .
window.dataLayer.push({ 'event' : 'send-data2', 'eventCategory' : 'data2-category', 'eventAction' : 'data2-Action', 'eventLabel' : 'data1-Label', 'eventValue' : 1500, 'eventNonInteraction' : true });}
Otázka … už to vyřešil Simo Ahava 😀 ?
Ano, problém vyřešíš tak že pošleš další event a hodnotu smažeš přes hodnotu undefined. Snadno se to říká, protože praxe je trochu méně příjmená.
window.dataLayer.push({ 'event' : 'event_send_data', 'key1' : 'value1'}); window.dataLayer.push({ 'event' : 'event_delete_data', 'key1' : undefined});
Je potřeba si hlídat jestli si mám po sobě smazat hodnotu dané proměnné. To jde vyřešit tím, že mohu udělat callback, což je docela otravné a dlouhé, ale smaže to dané data.
Ukázka kódu:
window.dataLayer.push({ 'event' : 'fireTags', 'eventCategory' : 'value1', 'eventAction' : 'value2', 'eventLabel' : 'value3', 'eventValue' : 1500, 'eventNonInteraction' : false, // alternative js shorthand !1 'eventCallback': function() { window.dataLayer.push( {'event' : 'delete', 'eventCategory' : undefined, // alternative js shorthand void 0 'eventAction' : undefined, 'eventLabel' : undefined, 'eventValue' : undefined, 'eventNonInteraction' : true, // alternative js shorthand !0 });}, 'eventTimeout': 2000 })
Pro vysvětlení:
- Základní odeslání dat.
- Callback obsahující další odeslání dat.
- Použijeme event s názvem, protože nechceme gtm event bez názvu so se zobrazí jako „message“.
- Smažeme přes hodnotu undefined danou hodnotu.
- A raději tomu dáme timeout 2sec.
Super, že? A tohle budete udělat s každý odeslaným automatickým eventem přes normalizované proměnné.
Kdy je callback s mazáním dat super?
Pokud používáte tečkovou notaci pro data o uživateli a tím pádem vytváříte JS objekty, může to vypadat následovně.
window.dataLayer.push({ 'event' : 'user.login.popup', 'eventCategory' : 'user', 'eventAction' : 'login', 'eventLabel' : 'popup', 'eventValue' : 0, 'event.NonInteraction' : false, 'user.id' : 'x', 'user.status' : 'x', 'user.segment.a' : 'x', 'user.rfm' : 'x', 'user.forecast' : 0.5 })
Pak výsledný objekt uživatel vypadá, což je alternativní zápis toho samého.
{'user: {id' : 'x', 'status' : 'x', 'segment.a' : 'x', 'rfm' : 'x', 'forecast' : 0.5 }}
Pak odhlášení uživatele odešle aktuální informace z datové vrstvy o uživateli X a callback smaže hodnotu user celé proměnné user, aby se již v dalším GA hitu nikam neposlali.
window.dataLayer.push({ 'event' : 'user.log-out.x', 'eventCategory' : 'user', 'eventAction' : 'log-out', 'eventLabel' : 'x', 'eventValue' : 0, 'eventNonInteraction' : false, 'eventCallback': function() { window.dataLayer.push( {'event' : 'user.data.delete', 'user' : undefined});}, 'eventTimeout': 2000 })
Co s tím?
Mohu po každém eventu, takto udělaném eventu poslat call back s vynulování dané hodnoty, takže udělám další event navíc.
Pokud chcete opravit historické implementace velkých projektů, máte smůlu, tohle vám nikdo implementovat nebude. Navíc to obsahuje otravný callback.
Moje řešení 1 : Načíst data jen v daný okamžik.
Data zůstávájí, ale skript beru si je ty správné přímo z objektu pole dataLayeru.
Odeslání do dataLayeru
Klasický plný zápis odesilaných dat.
window.dataLayer.push({ 'event' : 'fireTags', 'eventCategory' : 'value1', 'eventAction' : 'value2', 'eventLabel' : 'value3', 'eventValue' : 1500, 'eventNonInteraction' : false });}
Funguje to je pro část dat, zbytek proměnných bude undefined. Což pak můžete nechat nebo přes defaultní hodnotu pro „undefined“ nahradit.
window.dataLayer.push({ 'event' : 'fireTags', 'eventCategory' : 'value1', 'eventAction' : 'value2' });}
Získání dat přes custom javascript funkci
// js.actual.eventCategory // variable - JS custom code. function() { return window['dataLayer'].filter(function( obj ) {return obj["gtm.uniqueEventId"] }).slice(-1)[0].eventCategory; }
Update:
Po diskuzi se Simo Ahava, jsem udělal update. Tím, že se používají consenty a další věci, co mají jiný zápis než klasické dataLayeru.push eventy, je potřeba filtrovat eventy jen na ty co jsou v GTM dostupné.
Jak to funguje?
Místo, abych bral hodnotu z přes základní dataLaeyer proměnnou, tak použiji custom javascript, z toho plyne omezení, že to nefunguje pro NoJS implementaci. Ale to zase nebudou fungovat ani eventy ;),
Funkce je jednoduchá, šáhnu si do javascript objektu dataLayer pole, na jeho poslední položku a zní přečtu danou hodnotu. Takto se nepřenáší starší hodnota a nevyplněná hodnota je rovnou undefined nebo jde nahradit před definovanou hodnotou.
Na co to já používám?
Pro odesílání universálních události:
js.actual.eventCategory js.actual.eventAction js.actual.eventLabel js.actual.eventValue - hodnota pro undefined je 0 js.actual.eventNonInteraction - hodnota pro undefined je {{js.true}}
Pro dataLayer variable customDataSend na univerzální odesílání dalších jednorázových informací.
Stejného řešení asi i jediné správné je pro přístup k nativném proměným co se samy neresetuji, třeba podpůrné proměnné kolem gtm.elementVisibility etc. Víz třeba
gtm.visibleRatio: 14 gtm.visibleTime: 500 gtm.scrollThreshold: 10 gtm.scrollDirection: 'vertical'
Velká výhoda, je že jdou tak opravit staré projekty od přetékání, kde se zároveň odesílají jen 2 hodnoty (povinné kategorie + akce) či až 5 hodnot zároveň.
(2021-02-26) Simo Ahava udělal template, co dělá to samé.
Další alternativní řešení?
Spojení odesílaných hodnot do jednoho řetězce.
Dlouhý event, který je sekán na menší části.
Příklad:
window.dataLayer.push({'event' : 'ux-click-logo-0-true'})
Tedy fungovat podle toho vzorece, což je sada hodnot spojovaných přes speciální znak, často používám pomlčku nebo tvrdou mezeru.
Vzor:
eventCategory-eventAction-eventLabel-eventValue-eventNonInteraction
Při tomto zápis je nutné povolit každou kategorii v GTM.
Pokud použijete prefix, tak si oddělite tento typ události od ostatních a rovnou to můžete mít i jako pravidlo pro GTM.
ges.eventCategory-eventAction-eventLabel-eventValue-eventNonInteraction
„ges“ , Google analytics, Event, Shorhand (zkrácený zápis), můžete nahradit za cokoliv jiného.
U této verze můžete mít jedno pravidlo přes regulární výraz
^ges-.*-.*
Získání dat eventCategory přes následující js custom javascript proměnou.
function() { return {{Event}}.split("-")[1] // eventCategory }
Ověření, že posíláte ve správné formátu je
function() { return {{Event}}.split("-").length }
je rovna 4 nebo 6, a to podle množství, jestli posíláte value a interaction.
Je to ultimátní řešení?
Je to použitelné jen na GA události s žádnými daty navíc.
Trochu nachytření, event kategorie může být dlouhá až 150 znaků a akce i popisek každý 500 znaků. Takže výsledný event při tomto zápisu by byl dlouhý 1150 znaků+, takže výsledek může být dlouhý.
Vypadá to dobře, tedy dokud nebude chtít odeslat delší popisky.
window.dataLayer.push({'event' : 'ges-dlouhý název kategorie-dlouhý action-dlouhý název obsah-12121210-1'})
Viz obrázek.
Pak přehlednost v debuggeru klesá k nule. Délka viditelného obsahu v debuggeru je 21 znaků.
DataSlayer s tím má také problém.
Takže dobré řešení, ale jen na obsahově krátké události Google analytics.
Také se nesmí používat tečky jako oddělovač, protože ty jsou v eventValue jako oddělovač desetiných míst a pozor i na stejný znak v odesílané hodnotě, takže je potřeba ho nahradit, stejně jako jednoduché a dvojité uvozovky na náhradní znak.
Vyhodou může být i to, že všechny informace jsou v jedné proměnné.
Další řešení? 😀
Moje řešení 2 : Vložení objektu s hodnotami pod proměnnou Event
Jelikož Google tag manager podporuje tečkovou notaci při práci s JS objekty (V2) a zároveň je zpětnou kompatibilitu pro verzi dataLayer proměnné 1, tak si jde zakouzlit s přechody mezi těmito verzemi.
Tak jde odeslat následující, všimněte si teček.
window.dataLayer.push({ 'event' : 'fireTags', 'event.Category' : 'value1', 'event.Action' : 'value2', 'event.Label' : 'value3', 'event.Value' : 1500, 'event.NonInteraction' : false });
V dataLayeru to vypadá následovně… přesně dle odeslání jako pro proměnnou verze 1
A jelikož hlavní je zápis v dataLayeru, tak i zůstane hodnota proměnné „event“
'event' : 'fireTags'
i když v debugeru to vypadá jako přepsaný objekt, protože ten ukazuje verzi 2 🙂
{'event' : { 'Category' : 'value1', 'Action' : 'value2', 'Label' : 'value3', 'Value' : 1500, 'NonInteraction' : false } }
Při vytvoření nového eventu, se hodnota proměnné event zachová jako proměnná GTM dataLayer verze 2 a přemaže celý objekt.
Ano, jde to. Vím, že to jde, ale nelibí se mi to 😀 a beru to jako funkční věc, ale prasárnu. Nedoporučuji to, ne všechny scripty to pak mohou pobrat a dopadne to špatně.
Data se pak získávájí přes datalayer proměnou, přeplou na verzi 1.
PS: Hodnoty se nesmažou, pokud uděláte odeslání data do datalayeru bez hodnoty event a výsledek je prázdný event „message“. Což je taky prasárna, asi i větší než takové odesílání eventů jako je tohle.
Jaký je výsledek? Co je nejlepší? Asi kombinace.
Ideální je být konzistentní a podobný problém u eventů neřešit.
To co jsme chtěl ukázat, že existuje více variant řešení. Někdy se mohou hodit ve speciálních případech.
U starých účtů jsem to opravoval přes moje řešení č1., tím jsem opravil přetákání, které se často s radosti ignoruje.
U uživatelských dat vytvářím větší zanořené objekty a pak je celé mažu přes undefined.
Ze spojení odesílaných hodnot do jednoho řetězce jsem si vzal to, že věci pojmenovávám sice krátce, ale snažím se používat delší event name. Místo „GAevent“ raději použiji „ga.ux.click“ což zvyšuje přehled pri debugu, snažit se použít krátké popisky. Plně použitelné řešení ve správnou chvíli.
Co si o tom myslíte Vy?
Sdílejte a napište mi na sociálních sítích jak se stavíte k dané problematice nechtěného přetékaní dat.