Your Google Analytics is probably under-reporting. Here's how we fixed one in a day
After a site relaunch, GA4 showed organic search down about 65% while Search Console showed only 20%. The cause was measurement, not marketing: a cookie banner blocking analytics by default, leftover tags and unfiltered internal traffic. Seven steps fixed it in one working day.
The "traffic drop" was a measurement problem
A services business relaunched its website. A few months later, Google Analytics 4 (GA4) showed organic search traffic down about 65% year on year. That looked like an SEO disaster.
Search Console told a different story: Google clicks were down only about 20%. Two Google tools, two very different answers. The gap was the first sign that the problem was the measurement, not the marketing.
Five things we found
- Hundreds of visits with no source. After the relaunch, GA4 started recording a large block of Unassigned sessions. They weren't bots: they landed on real pages and behaved like real visitors. GA4 simply didn't know where they came from, so the traffic ended up in Unassigned or Direct instead of Organic Search.
- The cookie banner was blocking analytics by default. Most visits were sent with both analytics and ads denied. The banner blocked analytics until the visitor clicked Accept, and most visitors never clicked anything. Google can model the missing data, but only above roughly a thousand events a day. A typical small business site never reaches that, so the data was just lost.
- Years of leftover tags. The tag container still held Universal Analytics, an old CRM tracker, old form and video tags, and several Google Ads IDs from past campaigns. Some still fired on every page.
- Internal and editor traffic mixed in. Staff visits weren't excluded, and visits from the website builder's own editor showed up as referral traffic.
- No lead tracking. Nothing measured phone clicks, email clicks, form enquiries or which buttons people used. The business couldn't say which pages produced enquiries.
How to read the consent state: open browser DevTools → Network, filter for collect, and look at the gcs parameter in the requests sent to Google Analytics.
| gcs value | Meaning |
|---|---|
| G111 | Analytics and ads storage both granted |
| G101 | Analytics granted, ads denied |
| G100 | Both denied |
Steps 1–2: clean up GTM and clean the data at the source
Step 1: clean up Google Tag Manager
- List every tag with its trigger and when it last fired or was edited.
- Delete tags for tools you no longer use.
- Pause tags you're unsure about. You can turn them back on, and GTM's version history keeps everything.
- Publish with a clear version name, such as "Remove legacy tags".
Step 2: clean the data at the source
- Internal traffic: in GA4, go to Admin → Data streams → Configure tag settings → Define internal traffic, and add your office and staff IPs. Then, under Admin → Data filters, change the Internal Traffic filter from Testing to Active.
- Unwanted referrals: in the same tag settings, list your website builder's editor domains and payment or booking domains, so they don't appear as referral traffic.
Once the internal filter is active, your own test visits disappear from reports, including Realtime. That's correct, but it surprises people when they test.
Steps 3–6: track leads and visitor behaviour
Step 3: track phone and email clicks
In GTM, create a Just Links trigger where Click URL starts with tel:, and another where it starts with mailto:. Add a GA4 Event tag for each, named click_phone and click_email. In GA4, mark both as key events with Once per session counting. One person tapping the phone number three times is one lead, not three.
Step 4: track scroll depth properly
Turn off GA4's built-in scroll tracking (Enhanced measurement → Scrolls); it only records 90%. In GTM, add a vertical Scroll Depth trigger at 25, 50, 75 and 90%, and a GA4 Event tag scroll_depth with the parameter percent_scrolled set to {{Scroll Depth Threshold}}. Then register percent_scrolled as a custom dimension in GA4 (Admin → Custom definitions).
Step 5: track call-to-action buttons by text, position, page and device
Make one GA4 event, cta_click, that carries the details you need. The trigger is a Just Links trigger where Click URL matches a regular expression of your conversion pages, such as contact, team and case study pages. Set cta_text to {{Click Text}}, cta_destination to {{Click URL}}, and cta_location to a Custom JavaScript variable: it first checks whether the button sits in the mobile menu, header, footer or a service-page call-to-action block, and otherwise sorts it into top, middle or bottom by its height on the page.
Replace the selectors with your site's own. Website builders often give sections generated IDs, so match on part of the ID. Check the mobile layout separately: the same button often has a different ID on mobile. You don't need extra parameters for page or device, because GA4 already records Page path and Device category with every event. The resulting report: page × device × button position × button text × clicks.
Step 6: track form enquiries without a thank-you page
The usual advice is to redirect the form to a thank-you page and count page views. Many website builders already push an event when a form is submitted, so you may not need the page:
- In GTM, click Preview and submit a test form. Warn colleagues first, because it arrives as a real enquiry.
- In Tag Assistant, read the event list that appears after the submission. Click each one and open Data Layer.
- Watch for this: in our case the builder pushed two events, lead and generate_lead. Only generate_lead was a standard dataLayer.push. The other was sent in Google's gtag format, which a GTM Custom Event trigger ignores. We built the trigger on lead first and it never fired.
- Create a Custom Event trigger with the right event name, plus a GA4 Event tag generate_lead.
- Verify on the live site: open DevTools → Network, filter collect, and look for en=generate_lead.
- In GA4, create the key event (Admin → Events → Create event → Create with code) using Once per session and no default value. Otherwise GA4 adds a default monetary value to every lead.
Step 7: fix the cookie banner
This is the step that recovers the most data, and it's a business and legal decision, not just a technical one.
- Find out what controls consent. It may be a third-party banner app, not the platform's own setting.
- Check the defaults. Many banner apps ship with "block analytics until consent" turned on, which is the strictest EU-style setting.
- If the law in your market doesn't require opt-in consent for analytics, consider allowing analytics by default while keeping advertising cookies behind consent. Take advice for your own jurisdiction.
- Always keep the visitor's choice working. Test both cases:
| Visitor action | Expected gcs | Tracked? |
|---|---|---|
| Ignores the banner | G101 | Yes |
| Clicks Accept all | G111 | Yes |
| Clicks Decline all | G100 | No |
If Decline doesn't stop tracking, don't ship it. Use a banner that supports Google Consent Mode properly.
The result, and a checklist
In one working day, the site went from unreliable traffic numbers and no lead data to:
- a clean tag container with legacy tags removed
- staff and editor visits excluded
- four key events: form enquiries, phone clicks, email clicks and downloads
- button clicks reported by text, position, page and device
- scroll depth at four thresholds
- a clear explanation for the "traffic drop": search trends come from Search Console, on-site behaviour from GA4
Is your own GA4 telling the truth?
- Does GA4 organic traffic roughly follow Search Console clicks? If not, investigate before you react.
- Is Unassigned more than a few percent of sessions?
- What gcs value does your site send before anyone touches the cookie banner?
- Is your Internal Traffic filter set to Active, not Testing?
- Are there still Universal Analytics or other retired tags in GTM?
- Do you track form enquiries, phone clicks and email clicks as key events?
- Can you say which page and button produced last month's enquiries?
If you ticked fewer than half, your analytics is probably under-reporting what your website really does. If you want help getting search and tracking right together, see our SEO and SEM search marketing service.
Key Data & Sources
| Data | Value | Source |
|---|---|---|
| Year-on-year organic search drop shown in GA4 after the relaunch | about 65% | Client site GA4 and Search Console data, project review |
| Year-on-year drop in Google clicks in Search Console, same period | about 20% | Client site GA4 and Search Console data, project review |
| Data threshold for consent mode behavioural modelling | about 1,000 events a day | Google Analytics Help |
| Key events set up after the fix | 4 | Client site GA4 and Search Console data, project review |
| Time taken to fix | 1 working day | Client site GA4 and Search Console data, project review |
FAQ
GA4 and Search Console disagree. Which one should I trust?
They measure different things. Search Console counts clicks in Google search results and isn't affected by cookie banners or tag setup; GA4 counts the sessions your site actually collects. Their trends should roughly match. If GA4 falls much further than Search Console, check the measurement before you change your SEO.
Why count key events once per session?
A visitor who taps the phone number three times in one visit is one lead, not three. Counting once per session keeps GA4's lead numbers close to your real enquiries.
Does GA4 track visitors in mainland China?
Google services are unreliable in mainland China, so GA4 usually under-reports mainland visitors. For sites aimed at China, run a local tool such as Baidu Tongji alongside GA4 and cross-check with server logs.