• GTM Courses
  • Blog
  • Services
  • Resources
    • Youtube channel
    • E-books and Guides
    • GTM Recipes
    • View All Resources
    • GTM Community
  • About
    • About
    • Contact
  • GTM Courses
  • Blog
  • Services
  • Resources
    • Youtube channel
    • E-books and Guides
    • GTM Recipes
    • View All Resources
    • GTM Community
  • About
    • About
    • Contact

track site search with Universal Analytics

Site Search Tracking with Universal Analytics and Google Tag Manager

Note: All examples in this blog post are using Universal Analytics (a.k.a. GA3). If you want to track site search with Google Analytics 4, read this guide instead.

Site search tracking has always been a hidden gem for me when it comes to analyzing visitors’ behavior on a site. Why? Because you can quickly identify what your visitors are looking for on your site and whether you have to offer something relevant.

Google Analytics offers built-in Site search reports that you can make use of. Sometimes they are easy-to-configure, and sometimes — not so much. In this blog post, I’ll cover various options of how to track site search with Universal Analytics and Google Tag Manager.

You should choose the option based on how the site search is implemented on your site.

Google Tag Manager Ebook Bundle

Table of Contents

  • Why are Site Search Reports valuable?
  • #1. Site site search with query parameters (without GTM)
  • #2. Site site search without query parameters
    • #2.1. Custom JavaScript Variable
    • #2.2. Update the GA Pageview Tag
    • #2.3. Test
    • #2.4. Enable the Site Search Tracking in GA view
  • #3. Track auto-complete search
  • #4. Track site search with the developer’s help
    • #4.1. A trigger and a variable
    • #4.2. GA pageview tag
    • #4.3. Enable Site Search reports in GA view
  • #5. Track site search with DOM scraping
    • #5.1. Variable that returns the search page’s H1
    • #5.2. A variable that extracts the Search Query and returns it as a query parameter
    • #5.3. Update your GA pageview tag
    • #5.4. Enable Site Search reports in GA view
  • Additional things to do
    • Lowercase search terms
    • Zero-result searches
  • Final Words

 

Why are Site Search Reports valuable?

First, let’s take a look at why this is important in the first place. If you have already implemented the site search tracking, you will see that data in GA > Behavior > Site Search.

There you will find your most popular search terms, how often they are used, etc.

Now, let’s move on to the reasons why and how I use these reports.

#1. I check whether the search is showing relevant results to my visitors. I just pick the most popular queries, enter them myself on my site and check what does the search return.

  • Are the top results relevant?
  • Are there any non-sense results? Maybe the search is also returning some hidden pages that shouldn’t appear there? etc.

Checking searches in such a way is very time-consuming and tedious, however, it’s a good way to evaluate whether the search is actually properly working on your site.

If you indeed have content related to the keyword X but it was not displayed in the results, you could talk to developers about how to improve this. If you are using a popular content management system (like WordPress), you could try to find a better-performing search plugin.

 

#2. I find new ideas for content. While you can do keyword research with tools like Google Search Console, Ahrefs, etc., your own site search is a gold mine too. If a significant number of visitors have landed on your site and are looking for X (and you don’t have that type of content), maybe it’s time to create one?

While it’s fairly difficult to aggregate the data (because people can look for the same thing while using different keywords), you can still get a sense of what are your visitors interested in.

What do I mean by saying “use different keywords to find the same thing”? For example, 5 people might be looking for an enhanced ecommerce guide but their search terms might look like this:

  • enhanced ecommerce
  • ecommerce
  • e-commerce enhanced
  • gtm ga eec
  • enhanced google analytics

And that’s the end of the quick introduction to the feature. So, how can we implement it? The answer is classic “it depends”.

It depends on how the site search is coded on your site and how does it work.

 

Option #1. Track site search with query parameters (without GTM)

This option is the easiest one (and does not require Google Tag Manager at all). Try to use your website’s search feature. Enter any keyword in the search field and hit the Search button.

Did the URL change?

If yes, is the search term displayed after the question mark? Does it look similar to this yoursite.com/?search=my+keyword? Or maybe like this yoursite.com/?s=my+keyword?

If the answer is yes, you’re lucky. If the search query is displayed in the URL after the question mark (but not after the #), this means that your search is working with query parameters. In my first example (yoursite.com/?search=my+keyword), the query parameter for the search term is search. In the second example, it is s.

Now, go to Universal Analytics > Admin (click the gear icon in the lower-left corner) > Choose the GA view where you want to implement the feature and go to View Settings.

In that section, enable Site Search Tracking and enter the Search Query parameter that your site uses. In the case of the first example, you should enter search. In the case of the second example, you should enter s. If your website is using another query parameter, enter its value.

Also, I recommend ticking the checkbox Strip query parameters out of the URL

Save the changes. If you want to implement this feature on multiple GA views, you will need to do that one by one.

That’s it! After a while, you will start seeing the data populated in Behavior > Site Search reports.

 

Option #2. Track site search without query parameters

Another situation how a search query can be displayed in the URL is like this yoursite.com/search/search+query.

In this case, the search term is not a query parameter, therefore, the built-in GA functionality will not be able to capture it. That’s where Google Tag Manager becomes handy.

There are many ways how to skin a cat in this type of situation but I’ll show you one of the possible ways. Here’s the plan:

  • We will extract the search term from the URL
  • We will add it as a query parameter to the Page Path
  • We will send this new value as the Page Path to Universal Analytics
Subscribe and Get the Ebook - Real Book Img - GTM for Beginners

#2.1. Custom JavaScript Variable

The first two steps will be done with a little Custom JavaScript variable named cjs – page path with search query. Here’s the code:

function() {
  var pagePath = window.location.pathname;
  var searchParam = '/pages/search/'; //replace this with your page path before the search term
  if (pagePath.indexOf(searchParam) > -1) {
    return searchParam + '?s=' + pagePath.split(searchParam)[1].split('/')[0]
  }
}

On line 3, you need to enter how does the Page Path of your URL looks like before the search term. Let me illustrate.

  • If your search URL is yoursite.com/search/your-search-term, you need to enter /search/ in the Custom JS variable (together with the opening and closing slash
  • If your search URL is yoursite.com/search/results/your-search-term/, you need to enter /search/results/

If the Page Path does not contain the searchParam that you have defined, then this Custom JS variable will return undefined. If Page Path contains your searchParam, then it will return the data in the following structure searchParam?s=your-search-term, for example, /search/results?s=your-search-term.

 

#2.2. Update the GA Pageview Tag

Let’s send the value of our Custom JavaScript variable to Universal Analytics as a page parameter. Go to Google Tag Manager > Tags > open your existing GA Pageview tag.

Below the Google Analytics Settings field, click Enable Overriding Settings in this tag checkbox. Then click More Settings > Fields to Set > Add Field and enter:

  • Field name: page
  • Value: {{cjs – page path with search query}} (or whatever you called your variable).

Save the tag, enable the preview mode and then refresh the page where you are implementing the site search.

 

#2.3. Test

First, let’s test the GTM preview mode. After you refresh the page of your search results, click the Pageview event in the preview mode (or another event when your GA pageview tag fires). Then click the GA pageview tag and see whether the page field was sent with a proper value:

Then let’s test whether the request to Universal Analytics was sent properly.

Enable the GA debugger extension (by clicking the icon in the top right corner of your Chrome browser). Then open your browser’s JavaScript console and refresh the page (while you are in the search results).

In the JS console, you will see a lot of new stuff appear. It might take some time to find the pageview request but it might look something like this:

Then try to locate the page (&dp) parameter and check its value. Does it contain your search term as a query parameter “s”?

 

#2.4. Enable the Site Search Tracking in Universal Analytics view

Now do the same thing that I have explained in chapter #1 of this blog post. Go to Admin > View > View Settings and enable the site search tracking. In this case, you need to enter “s”.

 

Option #3. Track auto-complete search

Some websites use auto-complete search functionality (when you start typing a search term and the results are starting to show up after a couple (or so) seconds.

In a nutshell, here’s the process of how things will work:

  • A visitor starts typing a search query in the search field
  • If he/she pauses or stops for a couple of seconds, a virtual pageview is sent to Universal Analytics together with a modified page field (just like we did in chapter #2).

I will not dive deeper into how to set this up but you can learn more about it here. I just wanted to mention that this possibility exists.

 

Option #4. Track site search with the developer’s help

If none of the abovementioned site search tracking options work for you, this means that:

  • The URL of the search page does not contain the search term at all
  • Your search is not based on auto-complete

In that case, your plan B is to ask for a developer’s help. You could ask him/her to push the search term to the Data Layer every time a visitor completes a search.

Here’s a sample dataLayer.push code that a developer should incorporate somewhere in his code:

<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event' : 'search',
  'searchTerm' : 'your search term' //this should be dynamically replaced with an actual search query
});
</script>

 

#4.1. A trigger and a variable

After a developer implements this code, we need to create a Custom Event Trigger for search and a Data Layer Variable for searchTerm.

In GTM, go to Triggers > New > Trigger Configuration > Custom and enter the following settings:

Save the trigger. Then go to Variables > User-defined Variables > New > Data Layer Variable and enter the following settings:

 

#4.2. New GA pageview tag

Go to Tags > New > Universal Analytics > Pageview.

Then choose the GA settings Variable you are using in other tags and also click the Enable Overriding Settings in this tag checkbox. Then go to More Settings > Fields to Set > Add Field and enter the following settings:

Assign the Custom Event Trigger (search) to this pageview tag.

To sum up, whenever a visitor lands on your search page, two pageviews will be sent. One regular and one with the search term. If you are very worried about the bounce rate of search pages, you could play around with separate tags and triggers to make sure that only one pageview is sent instead of two. But this is not a tragedy for me.

 

#4.3. Enable Site Search reports in GA view

Once again, you should enable the site search reporting functionality in GA (jump to chapter #1 to learn more).

 

Option #5. Track site search with DOM scraping

The final option of this guide is the riskiest one. You should try it ONLY if all of the other options mentioned in this article did not work.

Important: This is just an example. Your case might look different, therefore, you might need to adapt my solution.

In this chapter, I will show you a hypothetical situation where:

  • Page URL does not contain the search term
  • The search is not auto-complete
  • A developer is not available
  • BUT the search term is displayed on a page (e.g., as Heading 1). Like in the example below:

After I enter the search keyword, it is displayed at the top of the screen (surround by quotation marks). If I do the right-click on that search term, I’ll find out that the entire Search: “sample page” is a single element h1.

Therefore, I will need to extract it and then strip all of the unnecessary parts.

 

#5.1. A variable that returns the search page’s H1

First, let’s create a GTM variable that will pick the entire h1’s value. My hypothesis is that the element h1 with class archive-title is the only element on a page and using the CSS Selector h1.archive-title should be enough to pick that element (because if not, we will need to come up with a more specific way to pick that element).

To check that, open your browser’s JavaScript console and enter the command document.querySelectorAll(‘h1.archive-title’) and hit ENTER.

P.S. you will most like see different CSS classes on your website, therefore, you will need to come up with a different selector. If you have no idea what is going on, consider joining my Intermediate/Advanced Google Tag Manager course.

Back to the JS console. How many results do you see there? If one, that’s good. If many, then you need to be more precise and update your selector.

In my case, I was lucky and the h1.archive-title CSS Selector returned only one element on a page.

In GTM, go to Variables > New > DOM Element and enter the following settings:

Save the variable and enable the preview mode. Refresh the page with the search results and click on the DOM Ready event. Check the value of your DOM Ready variable. If it’s null, check whether you configured the settings of the variable exactly as I did.

 

#5.2. A variable that extracts the Search Query and returns it as a query parameter

In my example, the DOM Element Variable returns the Search: “sample page”. I need to get rid of Search: “ in the beginning and ” at the end.

Let’s create a Custom JS variable for that. I’ll show you everything step by step:

First, let’s create an anonymous function:

function() {

}

Then, let’s define the variable that will return the h1 (of our search page). This is not necessary but since I will be referring to it multiple times, that’s more convenient:

function() {
  var searchTitle = {{DOM - h1.archive-title}};
}

See that thing surrounded by {{ }}? That’s our DOM variable from the previous chapter. If you named it in a different way, then make sure you enter the correct name in the Custom JS variable’s code too.

Now, let’s make sure that this Custom JS variable returns the search query only if the DOM element actually contains “Search:”. We can do that with an IF statement.

function() {
  var searchTitle = {{DOM - h1.archive-title}};
  if (searchTitle && searchTitle.indexOf('Search:') > -1) {
     // something will happen
  }
}

If the Page Title (h1) does not contain “Search:”, then the variable will return undefined.

Then, let’s extract the actual search term from the Search: “sample page”. We are interested only in sample page. There are many ways to achieve this and I’m pretty sure the mine is not optimal but it still does the job.

First, let’s get rid of the Search: “ . I use replace() method for that where I locate Search: “ and replace it with nothing.

function() {
  var searchTitle = {{DOM - h1.archive-title}};
  if (searchTitle && searchTitle.indexOf('Search:') > -1) {
     var searchQuery = searchTitle.replace('Search: “','');
  }
}

After this is implemented, our CJS variable will return sample page” instead of Search: “sample page” but there’s still the quotation mark at the end. Let’s add one more replace().

function() {
  var searchTitle = {{DOM - h1.archive-title}};
  if (searchTitle && searchTitle.indexOf('Search:') > -1) {
     var searchQuery = searchTitle.replace('Search: “','').replace('”','');
  }
}

And finally, our Custom JS variable should return the new (fake) page path together with a search query parameter. If the search term consists of multiple words, the spaces between them will be encoded (thanks to encodeURI method).

function() {
  var searchTitle = {{DOM - h1.archive-title}};
  if (searchTitle && searchTitle.indexOf('Search:') > -1) {
    var searchQuery = searchTitle.replace('Search: “','').replace('”','');
    return '/search?s=' + encodeURI(searchQuery);
  }
}

To sum up. If the H1 of the search page is Search: “google tag manager”, this Custom JavaScript variable will return /search?s=google%20tag%20manager. Don’t worry, Universal Analytics recognizes encoded spaces (%20) and will display them as actual empty spaces in your site search reports.

 

#5.3. Update your GA pageview tag

In your GA Pageview tag, click the Enable Overriding Settings in this tag checkbox > More Settings > Fields to Set > Add field and enter:

  • Field name: page
  • Value: {{cjs – search query}} <– insert your Custom JS variable here. If you named it differently than I did, then enter your variable’s name.

If the h1.archive-title element does not exist on a page, the variable will return undefined and GA Tag will ignore this field. If, on the other hand, the element exists, you will send the /search?s=[your-search-query] to GA as the new URL.

IMPORTANT: Also, if you have been using the All Pages trigger for your GA pageview tag, now you need to move it to the DOM Ready trigger. Why? Because sometimes, on Page view event, the page Title element might not be present yet, thus your tracking occasionally will not work

Caveat: in my case, the solution will only work if visitors DO NOT translate my website. If they do, then “Search:” will also be translated to something different, therefore, the CJS variable will not work.

 

#5.4. Enable Site Search reports in GA view

Once again, you should enable the site search reporting functionality in GA (jump to chapter #1 to learn more).

 

 

Additional things to do

Here are several other things you could do when it comes to tracking site search with Universal Analytics and Google Tag Manager. These are not required but feel free to consider them.

 

Lowercase search terms

Universal Analytics is case-sensitive. This means that a search term Google Tag Manager and google tag manager will be reported as two separate terms (even though they are exactly the same to me and you).

In order to fix this, you could lowercase all the search terms. This can be achieved with a GA filter.

In Universal Analytics, go to Admin > View > Filters and add the following settings:

  • Filter Name: Lowercase – Search Term
  • Filter Type: Custom > Lowercase
  • Filter Field: Search Term

 

Zero-result searches

But what if your visitor sees something like this when he/she enters a search term?

Let’s send a non-interaction event to GA whenever this happens. First, we need to inspect that error message. In my case, its a div with class is archive-subtitle.

Let’s create a DOM element variable with the following CSS Selector div.archive-subtitle. Now, let’s create a trigger with the following settings:

Then, create a trigger that will be activated if the subtitle DOM element contains the words We could not find any results for your search.

Finally, let’s create a GA Event tag with the following settings:

Assign the previously created DOM Ready trigger to this GA Event tag.

With it, we will send the search query that returned 0 searches and will be able to quickly identify which search terms are worth our time to invest.

 

Track Site Search with Google Tag Manager & GA: Final Words

Hopefully, this guide will help you solve most of your challenges related to the site search tracking with GTM. Most often (based on my experience), you will deal with the regular search + query parameter and a search without query parameter (while the search term is still visible in the URL).

Hi, I'm Julius Fedorovicius and I'm here to help you learn Google Tag Manager and Google Analytics. Join thousands of other digital marketers and digital analysts in this exciting journey.Read more
Essential resources


Popular Articles
  • 🔥 GTM Form Tracking: 7 Effective Methods
  • 🔥 dataLayer.push: The Guide
  • 🔥 GTM vs Google Analytics
  • 🔥 99 Things You Can Do with GTM
  • 🔥 Common GTM Mistakes
  • 🔥 Data Layer: Ultimate Guide
  • 🔥 60+ Custom JavaScripts for GTM
Analytics Mania
  • Google Tag Manager Courses
  • Google Tag Manager Recipes
  • Google Tag Manager Resources
  • Google Tag Manager Community
  • Login to courses
Follow Analytics Mania
  • Subscribe to newsletter
  • RSS feed
Recent Posts
  • How to Track Events with Google Analytics 4 and Google Tag Manager
  • How to Use Funnel Analysis Report in Google Analytics 4
  • How to Use Exploration Reports in Google Analytics 4
Analytics Mania - Google Tag Manager and Google Analytics Blog | Privacy Policy
Manage Cookie Settings