Tracking empty search results in GTM/GA4

Tracking empty site search results using GTM and GA4

It might be useful to see if people are searching for something that is not available in your E-commerce store, help portal, or even on your blog to get ideas on what information or product needs to be added to fulfill customer needs.

In this post, we will take a look at how to track searches that returned no results using Google Tag Manager and Google Analytics 4. We will capture not only the fact of an empty search results but also the keyword that was used.

You can find how to set up regular site search tracking in GA4 if you don’t have that in place yet.

Review search results page

We will use Google Tag Manager and a visibility trigger to send not found events to Google Analytics so before we dive into the setup you need to make sure that:

  • GTM is installed on the search results page
  • You can access the search results page when nothing was found (search for random characters and numbers, it usually shows no results)

Here is an example of how it looks on my blog:

On your site, you need to find an element that indicates that no results were found. It can be an ID or class name or text in a worst-case scenario.

Right-click and Inspect the element to open the dev console.

Try to find a class or id that could be unique to the not found page. In my case I’m lucky and here I have 2 class names – “not-found” and “no-results”. This will be different for each website and this is the value that we will use for our visibility trigger in GTM.

What if I don’t have a unique CSS selector for an empty search results page?

In case you don’t have any element that indicates that no results were found (based on class name or id) find an element with text that indicates that nothing was found. Then we can extract that text and trigger an event if the given text (E.g. “Nothing Found”) is on the page.

In my case, that would be the “Nothing Found” title.

As you can see, targeting this element would be very easy, just by using the CSS selector – “

How to track empty results page if I have no text or elements that distinguish it

In such scenarios, you might need either to figure out a more elaborate solution using a custom javascript variable or adding a dataLayer event and using it to send data to GA4.

The most simple example of such a dataLayer event could be:

  'event': 'emptySearchResults',
  'searchTerm': 'some keyword' // this is dynamic search phrase that returned no results

You can find a more detailed guide on how to fetch those values from dataLayer and pass them to GA4 in site search tracking article.

Create a “not found” event in GTM

Once we know the element that can be used to trigger an event, we can do a setup in Google Tag Manager and send this information to GA4. I will use “search_not_found” as my event name (you can pick any other if you like).

If you have a data layer event instead, please see the article linked at the end of the previous section for detailed information, otherwise, pick one of the methods below to continue with the setup:

Based on element visibility trigger

In my scenario, I had an element with class names “not-found” and “no-results” so I will use them both in my visibility trigger.

  • Open Google Tag Manager > Triggers > Create New
  • From trigger type select “Element Visibility”
  • Selection method – “CSS selector” if you have class names, or “ID” if you have a unique ID for such page.
  • Element selector – in my case – “” (In your case it will be different, I’m using standard CSS selector notation by dividing each class name with a dot)
  • When to fire – Once per page (adjust this only if you have a Single-Page-App and search results can be seen without page refresh)
  • Minimum Percent visible – I will set this to 5. You can set any value as long as you can be sure that the selected element will be seen in all scenarios (including mobile devices)
  • Observe DOM changes – You might need to set it if results are loaded within same page (asynchronously). In my case, I can leave it empty.

If the search not found page can be seen on other pages you might need to specify additional URL conditions for this trigger by selecting “Some Visibility Elements”.
I could skip it, but for the sake of an example, I will add an additional Page URL condition for pages with ?s= parameter.

Now you can save the trigger and proceed with the GA4 event tag setup.

Based on text content

Without a visibility element, we can do a small workaround using the DOM element variable and checking element text content. You can check this article dedicated to the DOM Element variable if you haven’t worked with that before.

  • Go to Google Tag Manager > Variables > Create a new User-Defined variable
  • Select “DOM Element” from variable type
  • Selection method – CSS selector in my case (unless you have a unique ID for such text element)
  • Element selector – “” same as described above
  • Attribute name – leave this one empty, since we are interested only in element text content, which will be returned by default
  • Save the variable
  • Go to Triggers section > Create New
  • Select the “DOM Ready” trigger type, since our element will be available only when DOM has been loaded.
  • Select “Some DOM Ready Events”
  • Add “Page URL” filter “contains” and your search page URL. (e.g. it can be “search”, “?q=”, etc.). In my case, all search results pages have a common “?s=” parameter (e.g. ), so I will add it here.
  • Select DOM variable that we have just created and specify the text that it has when no results were found. In my case, it’s always “Nothing Found”. (If you have a multilanguage site you might need to either create multiple triggers for each language variation or use Regex to match those).

Now we should be ready to set up event tag and give it a try.

NB! This trigger won’t work for Single-Page apps. While you can still try to use DOM element values, your trigger type most likely will be a history change or a custom dataLayer event. Also most probably instead of a Page URL, you will have to use either a virtual URL from dataLayer or history event-based page fragments.

Setup GA4 event tag

  • Go to Tags section > Create new
  • Select tag type – GA4 Event
  • Configuration Tag – Select your GA4 configuration tag, you should have it if you have GA4 tracking in place
  • Event name“search_not_found” . You can use another name as long as it fits 40 character limit (as mentioned in Google documentation)
  • Leave Event parameters empty for now, we will add searched keywords in the next section.
  • Select the trigger that you have created in the section above. It will be visibility, DOM, or custom dataLayer event trigger.
  • Save your tag

Test implementation on empty search result pages

  • Enable preview mode and initiate a search without search results
  • Open the Tag Assistant tab, and if everything worked well you should see your tag was fired.

For the event visibility trigger, you should see the “Element Visibility” event that fires on that page same as on the screenshot below.

Common problems that you could have at this point:

Can’t see the Element Visibility event

This means that the element is either not visible on the screen or CSS selector is wrong.

  • Try adjusting the CSS selector and make sure it’s correct
  • Make sure the “Minimum percent visible” setting is small enough to trigger an event
  • Check if page load actually works on search or you’ll need to enable “Observe DOM changes” setting

DOM trigger with text content doesn’t fire my tag

  • Check if the text that you have in your condition is actually present in the element.
    You can click on your tag from tag assistant in preview mode and should see the actual value returned by the DOM variable.
  • If the value returned is not expected – please check the CSS selector, it might be wrong.
  • If your website has multiple languages – check if all of those are covered by the trigger.

Capture keywords with no search results

Once we have the basic event for empty search result pages in place we can work on passing dynamic searched keyword text as it will be the most valuable piece of data here.
The implementation, of course, will be based depending on keyword availability so please find the most appropriate one from the sections below.

Searched keywords can be found in the URL parameter

This is the easiest approach when a keyword is inside the URL in a separate search parameter, for example:

We are interested in the dynamic value that comes after “search=” and will contain the search phrase.
To extract such values we can use the URL variable in GTM.

  • Go to Variables > Create new (User defined variable)
  • From Type select “URL”
  • Component type – Query. This allows us to select such parameters as “search=” above.
  • Query Key – Provide a parameter name that is used on your website.
    On this blog, at the moment I have this URL –
    so I will enter “s” in this field.

Save the variable and see the “Add keyword variable to your tag” section below.

Keywords can be found in other parts of the URL

Often search keywords are in the URL, but don’t have a separate query parameter.

In such cases, you need to find a common text in the Page Path that is used in any search page and based on that extract keyword value. We will have to use a little bit of JavaScript to get it done, and most likely you will have to adjust the example provided below to work with your URL structure.

  • Create a new Variable in GTM
  • Select type “Custom JavaScript”
  • Copy the code provided below into the variable content field.
function() {
  // Return second element from the URL path
  var path = {{Page Path}};
  return path.split("/")[2];

What we do here is splitting Page Path by forward slash “/” so that “/search/keyword/page/1” becomes a list of separate elements – “”, “search”, “keyword”, “page”, “1”.
From this list, we are then fetching the 3rd element “keywod” (in JS we count array elements starting from 0).

This means that if you have dynamic keyword value somewhere else in your URL you will need to adjust 2 to another number.

E.g. for this URL, you would need to use 4 instead of 2

I hope this makes sense.

Now, save the variable and proceed with the “Add keyword variable” section below.

Get searched keywords from the page content

Sometimes searched keyword doesn’t appear in the URL, but there still is an option to get it from page content before asking a developer to add it into the dataLayer.

Use DOM element variable

The easiest way to extract searched keyword is when it’s available in a separate element or element attribute – using the DOM element variable.

For example, on my page, I have a searched keyword inside the search input field.

Same as we did in the examples above, I could fetch “” value to get keyword text.

  • Create a new variable with the type “DOM Element”
  • Selection Method – CSS selector (unless you have unique ID)
  • Element selector – add CSS selector to target this element. In my example –
  • Attribute name – In my case I want “value” from the input. In your case, it could be empty to fetch text content or another attribute name.

Use custom JavaScript

In some cases, you might not have a “clean” keyword text available somewhere in the DOM and you would need to extract the correct keyword value using the Custom JavaScript variable.

For example, you could use the DOM element to fetch a block that contained searched keyword, but it’s inside other text.

You searched for "werwe"

Those are very specific cases that can be handled only individually, so I will not have a “one size fits all” type of solution. You could use either a JavaScript variable that uses DOM element output to regex extract keyword text or just use a modification or javascript variable template that I provided above (By changing split text to double quotes or another symbol and fetching the correct element number.

No keywords in the URL or on the website

If none of the methods are applicable to your case then most likely you will have to ask a developer to add dataLayer event together with dynamic keyword value and implement the whole use case using that approach.
See the first section above for a dataLayer event example.

Add keyword variable to your tag

Finally, we have extracted keyword text, now we just need to pass it to GA4.

  • Open the empty search result event tag that you created previously
  • Go to “Event parameters” and Add new
  • Add “search_term” parameter name
  • Select a custom variable that extracts keyword text in the value field
    You can do that by clicking on the “Plus” icon on the right side or by typing.
  • Save the tag and let’s test it in Preview mode.

Navigate to the “Not found” page again and let’s check our Tag Assistant tab.

  • Find your tag and click on it to see more details

If everything worked well you should see your searched term in the event parameter list, like in the screenshot below.

  • In Google Analytics you can go to Reports > Realtime
  • And find your event name in the Event count card
  • Click on the event and find “search_term” parameter
  • If you click on it, you should be able to see your keyword that didn’t return any search results.

Now, you should be good to go and publish your GTM container on LIVE to start receiving empty search result events.

Next steps

Once you have all the tracking in place and also have generic search tracking working (that can be done even inside the GA4 interface), you can explore collected data either in GA4 – Reports > Engagement > Events or using Data Studio.
In Data Studio you can even prepare a separate dashboard monitoring how big is the share of people who see no search results and what are the most popular keywords that they search for.

Hope you found it useful and good luck with exploring the data!

One thought on “Tracking empty site search results using GTM and GA4

  1. Great guide!
    Very interesting to be able to track empty search results to understand customer expectations.
    Thanks for sharing

Leave a Reply

Your email address will not be published. Required fields are marked *