Vi byggde en delad tracking-infrastruktur som alla våra produkter kopplas in i. En tracking-infrastruktur av den här typen kan kräva ett team, en analytiker, en taggningskonsult, kanske en datatekniker. Jag är ingen av dem. Jag visste ungefär vad jag ville ha som resultat och byggde det tillsammans med AI.
Vi byggde en delad GTM-container, ett BigQuery-projekt och ett server-side-lager som alla produkter delar, ett system byggt för att hantera två appar av olika karaktär och redo att ta emot fler.
Infrastrukturen bygger vidare på en tidigare tracking-setup. Den artikeln beskriver beslutsprocessen och grunden, den här handlar om hur samma infrastruktur gjordes delad och skalbar.
Vad vi ville uppnå
Grunden var att bygga för AI-styrda beslut baserat på analys. Det krävde data från många källor i ett standardiserat format, samlad på ett ställe.
Vi ville kunna svara på frågor som: Vilken annonsvariant driver faktiska installationer, inte bara klick till en landningssida? Hur ser resan ut från en betald annons till ett aktivt app-konto? På längre sikt handlar det om att kunna bygga attributionsmodeller och hitta rätt balans mellan räckvidd och konvertering.
Det förutsätter att beteendedata från GA4 och prestandadata från betald media hamnar i samma datalager, med samma schema och samma nycklar för att koppla ihop dem.
Det är ett arkitekturbeslut man fattar tidigt. Historisk data går inte att återskapa i efterhand. Vi valde att fatta det tidigt.
Innan AI kan agera på data måste data vara samlad, enhetlig och tillgänglig. Det bygger man inte i efterhand.
Hur vi tänkte
Det första arkitekturbeslutet gällde GTM och om vi skulle ha en container per produkt eller en delad. En container per produkt är enklare att förstå men kräver duplicerat arbete för varje setup och varje uppdatering. En delad container med hostname-baserad routing kräver lite mer initialt tänk men betalar av sig direkt vid andra produkten.
Hostname-routing innebär att varje tagg i GTM har ett trigger-villkor som kontrollerar vilket domännamn sidan laddas från. Flocken-taggar triggas bara på flocken.info, Nästahem-taggar bara på nastahem.com. Samma container, separerat beteende. Att lägga till ett tredje projekt tar minuter.
Det andra beslutet gällde BigQuery. Vi valde ett delat Google Cloud-projekt med dataset-namngivning per produkt. Varje produkt får tre dataset: _raw som innehåller data precis som den kommer in från GA4, orörd, _curated som är bearbetad och standardiserad, och _marts som är affärsfärdig data redo för dashboards och analys. Det ger full separation utan att splittra behörigheter, kostnadshantering och scheman över flera projekt.
Namngivningen var ett medvetet val för analysbarheten. När man ställer en query mot flocken_raw.events_* och en mot nastahem_raw.events_* i samma körning behöver man aldrig fundera på vilket system data kommer ifrån. Det öppnar för jämförelser tvärs produkter, vilka kanaler driver engagemang som håller, inte bara registreringar?
Det tredje beslutet var server-side taggning. Det konfigurerades en gång och gäller alla produkter. Fördelarna är flera. Datakvaliteten förbättras eftersom spårningen inte blockeras av webbläsaren, sessioner lever längre tack vare first-party cookies och GDPR-hanteringen blir enklare att sköta centralt för alla produkter på en gång.
Vad vi skapade
Webb-containern är den delade GTM-containern. Varje produkts GA4-konfiguration lever som en separat tagg med ett hostname-villkor. Triggers är produktspecifika, ett event som triggas på flocken.info skickar data till Flockens GA4-property och påverkar ingen annan produkt.
Server-containern kör på en egen subdomän och hanterar server-side GA4-insamling för alla produkter. Consent Mode v2 är konfigurerat i webb-containern och gäller globalt, ett beslut som ger alla produkter GDPR-kompatibel mätning utan att implementeras separat för varje produkt. Hur cookie-bannern är byggd och integrerad med Consent Mode v2 beskriver vi i Egen cookie-banner för full kontroll.
BigQuery-projektet tar emot GA4-export för samtliga produkter. Varje produkt har tre dataset i en standardiserad struktur. _raw innehåller rå GA4-export direkt från Googles exportpipeline. _curated innehåller bearbetade events med standardiserade fält. _marts innehåller affärsfärdiga aggregat för dashboards och analys.
Betald medias prestandadata flödar in i samma BigQuery-projekt via egna dataset. Meta Ads-prestanda per annonsvariant hamnar i samma schema som GA4-eventerna, med UTM-nycklarna som binder ihop dem. Det är den kopplingen som gör cross-channel attribution möjlig. En session i GA4 med en specifik UTM-sträng kan matchas mot exakt den annonsvariant i Meta som genererade klicket och mot appinstallationen som följde.
Varje GA4-property är konfigurerad med en property per produkt och separata data streams per plattform, webb, Android och iOS. Det innebär att samma property håller hela användarresan när appen är i produktion, i stället för att data fragmenteras i separata properties per kanal.
Resultat och lärdomar
När Flocken lades till som andra produkt var GTM, server-containern och BigQuery redan i drift. Arbetet bestod i att lägga till hostname-villkor och skapa produktens dataset, en bråkdel av vad det hade kostat att starta från noll. Det är strukturens verkliga värde. Varje ny produkt börjar inte längre vid noll.
Namnkonventionen i BigQuery visade sig vara viktigare än vi förutsett. Friktionsfri analys kräver att man aldrig behöver stanna upp och fundera på var data kommer ifrån. Det är en liten sak som hänger ihop med allt annat, naming är infrastruktur.
En lärdom var att Google Clouds regionsinställningar måste vara konsekventa från start. Vi valde EU-regionen av GDPR-skäl, men GA4-exporten måste konfigureras mot samma region som BigQuery-dataseten. En felmatch genererar fel som inte är intuitiva och tog tid att felsöka.
Att köra server-side GTM kostar något per månad. Men kostnaden delas av alla produkter och är linjär snarare än multiplicerande, ett projekt till ändrar inte priset nämnvärt.
Fortsatt utveckling
Infrastrukturen är på plats men cross-platform-analysen väntar på att apparna är i produktion. När Firebase kopplas in för iOS och Android kommer _curated-lagret att hålla hela användarresan, från första webbesök via betald annons till aktivt app-användande. Då kan attributionsfrågorna besvaras med data i stället för antaganden.
Hur vi går vidare
Nästa steg är att bygga ut analysdelen. Dashboards kopplas mot _marts-lagret och automatiserade analyser körs enligt schema för att ge löpande insikter utan manuella körningar. Grunden för att lägga till nästa produkt är redan på plats.
Parallellt planeras integration av Google Ads med samma princip. Kampanjprestanda flödar in i _marts-lagret med samma namnkonvention som Meta-datan. Det gör att analyser kan jämföra kanaler direkt, utan manuell ihopslagning av data från olika plattformars egna rapporter.
På längre sikt är målet att _marts-lagret håller tillräckligt med data för att AI ska kunna identifiera mönster och föreslå ändringar tillbaka via de plattformsspecifika API:erna. Infrastrukturen är byggd för det, det är tillståndet i datan och mängden observationer som avgör när vi kan aktivera det.
Verktyg i den här processen
- Google Tag Manager – Delad webb-container med hostname-routing. Alla produkters taggar och triggers lever här.
- GTM Server Container – Server-side taggning på egen subdomän. Hanterar GA4-insamling och Consent Mode v2.
- BigQuery – Delat datalager med produktprefixade dataset i standardiserad raw/curated/marts-struktur. Tar emot GA4-export och data från betald media.
- GA4 – En property per produkt med separata data streams för webb och app.
- ChatGPT – Utforskade arkitekturalternativ, validerade dataset-namngivning och identifierade regionskonflikten i Google Cloud.
- Cursor – Implementerade routing-logik, konfigurerade container-triggers och felsökte BigQuery-export.