GA4's migration from Universal Analytics caught many Canadian businesses off-guard, and rushed implementations often embed measurement errors that persist for months. Recognizing and fixing the most frequent setup mistakes—consent mode gaps, missing e-commerce schemas, server-side misconfigurations, and cross-domain tracking failures—ensures you're collecting clean data instead of garbage that misleads every optimization decision downstream.
When you create a GA4 property, Google turns on Enhanced Measurement by default and lists checkboxes for page views, scrolls, outbound clicks, site search, video engagement, and file downloads. Many assume this means those events flow in automatically. The reality: Enhanced Measurement works only if your site structure matches Google's expectations. If your search uses a query parameter other than 's' or 'q', GA4 won't detect it. If your videos live in a custom player rather than YouTube or Vimeo embeds, engagement won't register. File downloads trigger only for common extensions—pdf, xlsx, docx, zip—so proprietary formats or server-rendered PDFs behind authentication often go untracked. Instead of assuming, audit the Realtime report during a test session where you deliberately scroll, click an outbound link, search, and download a file. If events don't appear, you need custom GTM triggers. For complex interactions—accordion expands, calculator submissions, chat widget opens—Enhanced Measurement does nothing; you must define those events manually in Google Tag Manager with specific click classes or JavaScript listeners.
PIPEDA and Quebec's Law 25 both require meaningful consent before dropping analytics cookies, and the EU's GDPR enforcement has never been stricter. GA4's Consent Mode lets you load tags in a degraded state when a visitor hasn't consented, sending pings without cookies and modeling the data gap server-side. The mistake: deploying GA4 without any consent banner, or using a banner that blocks the tag entirely rather than switching it to consent mode. If you block GA4 completely for non-consented users, you lose 30 to 60 percent of your Canadian and European traffic data. If you ignore consent and fire tags unconditionally, you're liable under privacy law, and browser-side blockers like Brave or Firefox Total Cookie Protection kill the tags anyway. The fix is a consent management platform—Cookiebot, OneTrust, or the free open-source Klaro—integrated with GTM's built-in consent API. You set default consent to denied, update to granted when the user clicks Accept, and configure GA4's tag to respect those signals. This keeps you compliant, preserves modeled data for non-consented sessions, and ensures clean measurement for users who do consent.
GA4's e-commerce events—view_item, add_to_cart, begin_checkout, purchase—require an items array with specific keys: item_id, item_name, price, quantity, and ideally item_category. A common GA4 setup mistake is pushing a purchase event with transaction-level revenue but an empty or incorrectly structured items array. GA4 will accept the event, show it in Realtime, but your Monetization reports display zero revenue because the schema failed validation. Another pitfall: using a string for price instead of a number, or omitting currency at the event level when you sell in both CAD and USD. If your checkout flow spans subdomains—cart on shop.example.ca, payment on secure.example.ca—and you haven't configured cross-domain measurement, the purchase event fires but attributes to direct traffic with no session continuity. The fix: use GTM's e-commerce variable in Data Layer mode, validate the exact JSON structure in Preview before publishing, and test a end-to-end transaction in GA4's DebugView. For multi-currency stores, set the currency parameter explicitly in every e-commerce event, and if you're invoicing in CAD but reporting in USD, handle conversion server-side before the data layer push to avoid currency-mismatch errors that corrupt your reports.
If your main marketing site lives on example.com and your application or checkout lives on app.example.com or portal.example.com, sessions break at the domain boundary unless you configure cross-domain measurement in two places: GA4's data stream settings and your GTM container. The frequent mistake is adding the domains to GTM's GA4 configuration tag under 'domains to configure' but forgetting to list them in the GA4 property's Configure > Data Streams > Configure tag settings > Configure your domains section. Without both, the _ga cookie doesn't transfer, and every subdomain visit starts a new session attributed to referral or direct. You also need referral exclusions for each domain so internal navigation doesn't count as a referral source. For Canadian SaaS products that use a .ca domain for marketing and a .com domain for the app, or bilingual sites where French content lives on a subdomain, this mistake splits attribution and makes funnel analysis impossible. The fix: in GA4, navigate to Admin > Data Streams > Web > Configure tag settings > Configure your domains, and list every domain and subdomain. In GTM, open your GA4 tag, expand Configuration Settings, add a 'linker' parameter with an array of all domains, and ensure your GTM container publishes to every domain involved. Test by navigating from domain A to domain B and confirming in DebugView that the session_id persists.
Server-side Google Tag Manager runs your tags in a cloud container instead of the visitor's browser, which improves page speed, bypasses ad blockers, and gives you control over what data leaves your infrastructure. The setup pitfall: forwarding events to the server container without sending client IP, user-agent, and client_id correctly. GA4 uses IP for geographic reporting and bot filtering; if your server container receives every request from your cloud instance's IP, all traffic appears to originate from a single data center, ruining location reports. User-agent passthrough is needed for device and browser breakdowns. Client_id stitching ensures the server-side event links to the same user as browser-side events. The mistake often happens when developers implement a custom event relay—Node, Python, or PHP script—that posts to the server GTM endpoint but strips headers. The fix: use the official gtag or data layer push from the browser to send events to /gtag/js, or if you're building a custom client, explicitly forward x-forwarded-for for IP, user-agent header, and the _ga cookie value as client_id in the event payload. In the server GTM container, configure the GA4 client to read those fields. For App Engine or Cloud Run deployments in Canada, ensure your server container runs in a nearby region—northamerica-northeast1 for Montreal—to minimize latency and avoid the appearance of cross-continental traffic.
GA4 lets you define internal traffic filters by IP address so your own team's visits don't inflate metrics. The setup mistake is adding your office IP or VPN range to Admin > Data Streams > Configure tag settings > Define internal traffic, but forgetting to activate the filter in Admin > Data Settings > Data Filters. By default, the internal traffic filter is in Test mode, meaning GA4 tags the traffic but still includes it in reports. You must switch the filter to Active. A second mistake: defining only your office's static IP and ignoring remote employees on residential connections or mobile data. For a distributed Canadian team—employees in Ottawa, Vancouver, and remote—you either accept that some internal traffic leaks through, or you configure a VPN that funnels all company access through a known IP range and filter that. If your agency works in a co-working space with a shared IP, filtering becomes impractical; instead, rely on hostname filters or custom user properties. The validation step many skip: after activating the filter, visit your site from the office, open DebugView, and confirm that events carry the traffic_type parameter set to internal. Then check a standard report and verify those sessions are excluded. For e-commerce clients, internal test purchases should also be filtered or made in a separate GA4 test property to avoid corrupting revenue data.
GA4 conversions are just events you promote by toggling 'Mark as conversion' in the Events report or Admin > Conversions. The mistake: you configure a GTM tag to fire purchase, but in GA4 you mark Purchase as a conversion—capital P. GA4 event names are case-sensitive; purchase and Purchase are different events. Your conversions report stays empty because the event name doesn't match. Another common error: tracking form submissions with a custom event name like form_submit in GTM, then marking form_submission as a conversion in GA4. No match, no conversions. The fix is strict naming discipline. Decide on a convention—snake_case, all lowercase—and enforce it across GTM tags and GA4 configuration. Before marking an event as a conversion, go to Reports > Realtime or Reports > Events, trigger the event on your site, and confirm the exact name that appears. Copy that name character-for-character when you create the conversion. For lead-gen businesses tracking multiple forms—contact, quote request, demo booking—ensure each has a distinct event name and mark each as a separate conversion so you can attribute value and optimize bidding in Google Ads. If you're importing conversions to Ads, double-check that the event name in GA4 matches the conversion action name in the Ads interface, or the import will silently fail.
Use GA4's DebugView in real time. Navigate to Admin > DebugView, then on your site append ?debug_mode=true to the URL or enable Preview mode in Google Tag Manager. Complete the conversion action—submit a form, finish a checkout, click a CTA—and watch DebugView. You should see the event fire with all expected parameters. Then go to Admin > Conversions and confirm the event name matches exactly, case-sensitive. If the event appears in DebugView but not in the Conversions list, you either haven't marked it as a conversion or there's a name mismatch.
Enhanced Measurement is a set of automatic events GA4 fires based on common interactions—scrolls, outbound clicks, file downloads, site search, video plays—using built-in heuristics. It requires zero GTM configuration but only works if your site structure matches Google's assumptions. Custom events in GTM give you full control: you define the trigger (click class, form submission, JavaScript variable change) and the exact event name and parameters. Use Enhanced Measurement for standard interactions, but rely on GTM custom events for anything specific to your business—product configurator submissions, chat widget opens, pricing calculator interactions—where generic tracking won't suffice.
No. Sharing the same measurement ID is necessary but not sufficient. You must explicitly list all domains in GA4's data stream configuration under Configure your domains, and in GTM you need to add a linker parameter to your GA4 tag with an array of those domains. Without both steps, the _ga cookie doesn't transfer across domains, so each domain hop starts a new session and breaks attribution. Also configure referral exclusions in GA4 so internal navigation between your domains doesn't show up as referral traffic in reports.
The purchase event is registering, but the items array is likely missing, empty, or malformed. GA4 requires an items array with item_id, item_name, price as a number, and quantity. If price is a string, if the array is absent, or if keys are misspelled, the event fires but revenue validation fails and Monetization reports show zero. Open DebugView or the GA4 Realtime report, expand a purchase event, and inspect the items parameter. Verify it's an array of objects with the correct schema, and ensure currency is set at the event level.
Server-side GTM moves tag execution from the visitor's browser to a cloud server you control. This bypasses ad blockers and browser privacy features, so you capture more complete data, and it improves page speed because fewer scripts load client-side. However, if you don't forward client IP, user-agent, and client_id from the browser to the server container, GA4 loses geographic, device, and user identity accuracy. Done correctly, server-side GTM increases data reliability and privacy compliance; done poorly, it creates duplicate users and breaks session stitching.
Dual tracking is safe and often recommended during migration, but Universal Analytics stopped processing data in July 2023 for standard properties, so you can only view historical data now. Running both tags in GTM historically didn't cause conflicts—they use separate cookies and endpoints—but added page weight. If you still have UA tags firing, remove them; they no longer collect data and just slow your site. Focus entirely on validating and fixing your GA4 setup, because that's the only analytics platform Google supports going forward.