Struggling with “(not set)” landing pages in GA4? We got you covered

If you have GA4 I bet you have “(not set)” landing pages. You do, don't you? Go on, check, I'll wait… (And while you check make sure you’re not including today or yesterday in your date range because GA4 data can take between 24 and 48 hours to process which could increase the number of “(not set)” landing pages you’re seeing)
 
You back? Cool. So you're probably wondering why that "(not set)" value is appearing and how to fix it, well don't worry, I have your back.
Wooden sculpture of a hand supporting a falling tree

Background on "not set" in GA4

You might see a value of "(not set)" in your Landing Pages report for a multitude of reasons but the most common reason is similar to why it could happen in Universal Analytics (UA). When the first event of a session is not "page_view" then GA4 sets the landing page to "(not set)". This can be quite frustrating and tough to get to the bottom of, but fear not, I have spent an embarrassing amount of time investigating this and have emerged with a solution.


Screenshot from Google Analytics - Landing Page report

Investigating the problem of "not set"

The tricky thing about this problem is that you can scrutinize your GA4 implementation as much as you want but you probably still won't find out what the issue is. I was able to GUARANTEE that page_view was the first event tag to fire on each page and STILL I saw "(not set)". So why was this continuing to happen?

 

It was still happening because I was looking in the wrong place, it wasn't event tags I should have been looking into (although this is definitely something to check, if page_view isn't the first event to fire you will see this issue as well). What I should have been looking at was the CONFIG TAG.

 

For those that don't know, the config tag is what's used by all other GA4 event tags, it loads the GA4 JS library, it directs events to your property and sets values that all other events can share. It also sends some GA4 events of its own! Some of these events you can switch off through the Enhanced Measurement feature in the GA4 UI, but others, namely user_engagement, you cannot switch off.

 

A bit of testing later and I was convinced, user_engagement was firing before page_view for a lot of the page views in my session, so it was possible it was happening for the FIRST page view of a session too! I had found the problem, cut off the head of the hydra, but now two more heads had appeared:


  • How do I stop something that happens automatically and can't be edited or blocked?
  • If I find out how to do this, should I? What is the impact of removing user_engagement?


What does user_engagement actually do, and is it ok to remove?

When we look at Google's own documentation we can see that user_engagement fires "when the app is in the foreground or webpage is in focus for at least one second.". With this event, we get the engagement_time_msec parameter used to calculate the amount of time a user spends on a page.

 

This explains A. LOT.

 

If your page_view tag takes longer than a second to fire (which could happen on any site and inconsistently at that) then the user_engagement event will fire first, and you'll end up with “(not set)” landing pages.

 

You may be inclined to think that removing the user_engagement event will prevent you from seeing session duration metrics and so shouldn't be tampered with, but fortunately this is not the case, as plenty of other events send this information by default including:


  •  app_exception
  •  first_open
  •  page_view
  •  screen_view
  •  scroll


This isn't the only thing the user_engagement event is used for though, it also triggers when a user updates their consent settings to notify Google that a user has accepted/denied consent and applies that setting to previous events on the page to tie traffic source information to the session.

 

"That's great Dan but how do we remove something that happens automatically and can't be configured or edited while also making sure I don't break my consent mode setup?"

 

I hear you scream at your monitor, and you're right, lets finally talk about the solution.

Screenshot of the payload of a google analytics event

The Solution to removing user_engagement [UPDATED]

In a phrase "server-side tagging". That's it, that's all I have for you.

 

OK fine, I can provide a little more detail. Server-Side GTM is great, I love it, it gets my geeky brain all excited. One of the coolest things about GTM Server Side is the fact that it gives us ULTIMATE CONTROL over what we send and where. Talking through how it works in detail would be a blog post in and of itself (Which is why we wrote one - https://www.hookflash.co.uk/blog/the-benefits-of-server-side-tracking) but the long and short of it is:

  • We still use a client-side (traditional) GTM container except instead of sending data directly to Google’s servers, we send it to our own first party server
  • Our server-side container processes those requests and then distributes them to other platforms (GA4, Google Ads, Facebook etc)

 

This seems like an arbitrary step but trust me, it's amazing. One reason why it's amazing (and the reason it's a solution to our problem) is that we can tell the server to IGNORE user_engagement events when we don’t want them. Now it may be tempting to ignore all instances of user_engagement, and for websites autoblocking GTM until consent is given (basic consent mode), this is fine, but many websites are now using Advanced Consent Mode and the user_engagement event plays an important role in updating and backdating a user’s consent once they click “agree” on a cookie banner. So, we can’t just remove all instances of user_engagement we just need to remove the scenarios where it starts a session.
 
Fortunately, GA4 has a very neat feature that allows us to work this out. When an event fires and starts a session, GA4 flags it as the first event of the session with a query parameter “_ss=1”, when it reaches the interface, a session_start event is paired with it and information like landing page and traffic source information is determined, the problem is that this first event needs to be a page_view in order for a landing page to be set.

First we need a parameter that tells GTM whether the incoming request started the session.

So all we need to do is tell GTM Server Side to fire user_engagement events ONLY when they don’t start a session which is pretty easy to do!

Then we need to create a trigger for our user_engagement tag such that it only fires when a session has already started.

Make sure you test this in debug mode before you publish, make yourself a coffee and see the Landing Page values start to improve.

Conclusion

After implementing this change, I can confirm that this works! Before this change, just over 7% of our landing pages were “(not set)” and it was the second highest value after our home page. Since making this change 0% of our landing pages are “(not set)” and we can now see where people land on our site with clarity. It’s important to note that you may not see the same results if other events occur before a page_view event so make sure your ordering is correct!

 

While this solution does work, we did see a slight drop in sessions where users landed on the page (would have only set off the user_engagement event) and then left before a pageview could fire. Additionally, the user_engagement event is what is used for the “Engaged Sessions” and “Engagement Rate” metrics so if these are important to you, you will want to implement a different solution.

 

I do hope that more accessible tools become available to address this issue or that Google just fixes the ordering problem. In the mean-time though if you want to learn more about server-side tagging or GA4 in general feel free to reach out to one of our experts.

Want to have a chat? 

Chat through our services with our team today and find out how we can help.

Contact us
Share by: