Skip to main content

WordPress Google Analytics 4: Correct Setup Guide

WordPress · 27.01.2025 · 4 min read
Illustration for “WordPress Google Analytics 4: Correct Setup Guide”

Three Ways to Add GA4 to WordPress

MethodProsCons
Site Kit by GoogleOfficial, easy to useHeavy plugin
Manually (functions.php)LightweightRequires PHP knowledge
Google Tag ManagerFlexible, all tags in one placeHarder to set up

Method 2: Manually via functions.php

function add_ga4_tracking() {
    $measurement_id = 'G-XXXXXXXXXX';
    echo "
    <script async src='https://www.googletagmanager.com/gtag/js?id={$measurement_id}'></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', '{$measurement_id}');
    </script>";
}
add_action('wp_head', 'add_ga4_tracking');
💡 Add if (!current_user_can('manage_options')) before the echo so your own visits are not counted in analytics.

Setting Up GA4 Goals

In GA4, goals are called Events. The key events for a hosting site are:

  • purchase — order placed
  • sign_up — registration
  • generate_lead — form submission
  • page_view — page view
⚠️ GA4 does not store IP addresses by default — this is GDPR compliant. Do not change this setting unless you have to.

Diagnosing GA4 tracking errors

The tracking code is in place, but no data shows up in the reports. The difference between GA4 and the old Universal Analytics is that GA4 groups everything into events, so many "errors" are not really bugs but just a different data model. Here is what the typical symptoms mean.

SymptomCauseWhat to do
The Real-Time report is empty even though the code is presentThe Measurement ID has a typo, or the script is blocked by a cache plugin as "unused JS"Check the ID in GA4 → Admin → Data Streams, exclude the file from minification
Console error: gtag is not definedgtag.js did not finish loading before gtag() was called, usually because the include order was changedDo not change the order from the example: dataLayer first, then the gtag.js script itself
Session count is twice what is expectedGA4 is wired up both through Site Kit and manually via functions.phpKeep only one way of adding the tracking code
A request to google-analytics.com is marked Blocked by clientAn ad blocker is stopping the request for part of the visitorsThis is expected for a share of traffic; for reliability use server-side tagging with a GTM Server Container

When a manual GA4 setup is not enough

  • Sites with strict GDPR requirements — you need Consent Mode v2 and a consent banner before any data is sent to GA4
  • Online stores with sales reporting — passing purchase data manually via functions.php is hard; the built-in WooCommerce integration or GTM is easier
  • Companies with a legal requirement to keep data inside the EU — this needs a separate data processing region setting in GA4 Admin, not just inserting the code
  • One-page sites with dozens of micro-conversions — manually tagging every event in code does not scale; you need Google Tag Manager
  • Sites with several domains under one brand — cross-domain reporting needs cross-domain measurement configured, not just the same code pasted on every domain

There is a separate problem of trusting the numbers. Even when the tracking code works technically, comparing conversions before and after a site redesign is only valid with the same traffic source: paid traffic and organic traffic convert differently, and mixing them in one report distorts the conclusions.

Setting it up with Google Tag Manager

GTM is convenient because every tag is managed from one interface without touching code for every change.

<!-- In head, right after the opening body tag -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

<!-- The main container is inserted into head via functions.php,
     the same way as in the gtag example above -->

If the GTM container fails to load because of a content security policy, check the CSP setup on the site.

How to check that data reaches GA4 correctly

  • In GA4 → Admin → DebugView, events appear in real time while debugging is active
  • In DevTools → Network, the request to google-analytics.com/g/collect returns status 204
  • The Tag Assistant browser extension shows the tags firing with no configuration errors
  • The number of page_view events roughly matches the number of unique page loads for the same period
// Quick check in the browser console
console.log(window.dataLayer);
// The array should contain gtag('config', ...) and gtag('event', ...) entries

After checking the tracking, it is also worth reviewing the basic SEO setup — see the article on Yoast SEO.

Was this article helpful?
← Back to Knowledge Base Ask Support