
April 8, 2020
5 Ways to Track Site Search with Google Tag Manager and Google Analytics
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 Google Tag Manager and Google Analytics.
You should choose the option based on how the site search is implemented on your site.
Note: this blog post teaches how to track events with Universal Analytics. If you want to get familiar with event tracking in Google Analytics 4, you can also refer to this blog post.

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
- #3. Track auto-complete search
- #4. Track site search with the developer’s help
- #5. Track site search with DOM scraping
- Additional things to do
- 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 the 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 Google 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 first example, you should enter search. In the case of the second example, you should enter s. If you website is using another query parameter, enter its value.
Also, I recommend ticking the checkbox Strip query parameters out of 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
- Will will add it as a query parameter to the Page Path
- We will send this new value as the Page Path to Google Analytics

#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 Google 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 Google 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 Google 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 Google 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 you 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.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.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.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 search term consists of multiple words, the spaces between them will be encoded (thanks to encoreURI method).
function() { var searchTitle = {{DOM - h1.archive-title}}; if (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, Google 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 Google Tag Manager and Google Analytics. These are not required but feel free to consider them.
Lowercase search terms
Google 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 Google 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 challenged 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).
Got any other questions? Let me know.

13 COMMENTS
Hi Julius!
I am working on an ionic framework to build a hybrid application. I have integrated google tag manager also.
When I run the application in the desktop browser, I can see the relevant data flowing into the UI of google analytics. But, when the application is opened in mobile using APK, I don't see data reflecting on google analytics end.
Hi, not enough information. Please provide more. Check whether your does not behave differently on mobile devices.
Nice article Julius, really covers a wide scope of scenario a measurement marketer can be faced with, but will love to throw in another option for non technical and people, in the part of the article that talks about don scraping the search term, non technical marketers can just push in that query that way into GA and the. Clean em up with filters, though this is not recommended, because it doesn't make the search variables reusable in other analytics tools like amplitude, Mixpanel, FB analytics, etc.
Once again, thanks Julius
Hi, Julius,
Thank you for this great article!
I'm trying to activate Site Search for a website with Option #2. The site displays the following parameters: https://mysite.com/search/query. In this case, I think the search term is not a query parameter.
I did it step by step through the article and custom JS variable return 'undefined'(and you wrote that it would happen).
My question is: what changes should I make in Custom JS? Or am I wrong elsewhere?
Thanks again for the article
Hi, please read chapter 2.1. It explains what needs to be changed.
Thanks! The problem was a mistake in JS. It works. Thank you again!
It amazes me the number of Google Analytics audits we do where someone has taken the time and effort to setup site search and then forgets to lower case the search terms
This makes it harder to spot the patterns and quite a few times the person who has to do the analysis ends up using the search tools analytics rather than Google Analytics
The downside to this is the search tools analytics rarely has the same level of functionality that Google Analytics has
Hey Julius, great post. Is there any way we can get the values of a search when the search bar isin JS? So when you type you're getting results instantly. No search results urls, no "s" queries...
Thanks!
It looks like you haven't read the guide carefully. Have you tried option #3?
oh, yes, I think this is it. Thanks for the heads up, sometime just read too quick ;-)
Great article!
i'm struggeling with setting up site search in GA.
My search form works with GET and places the searchquery in the url
https://www.coachview.net/?s=test
I've activated site search with queryparamater 's', but results aren't showing up in GA. Am I missing something?
Did you wait for 24 hours?
Hi Julius,
Thanks for the reply, Yes i've waited 72 hours now. Still no results.