Skip to content

Track Internal Search

Internal site search reveals what users are looking for that they could not find through navigation. It is one of the highest-signal events you can track: search queries show intent, zero-results searches show content gaps, and repeated searches show friction.

Before implementing, identify how your search results page works:

  1. URL parameter — most common: /search?q=term, /results?query=pricing, /search?s=term
  2. dataLayer push from the search results template — best when you control the CMS
  3. Hash-based or SPA routing/search#term or dynamic route

Option A — URL parameter reading (no code required)

Section titled “Option A — URL parameter reading (no code required)”

If your search results appear at a URL like /search?q=your+query, GTM can read the query from the URL using a built-in URL variable.

  1. Create a URL Variable for the Search Query

    In GTM → Variables → New:

    • Variable type: URL
    • Component type: Query
    • Query key: q (replace with your site’s actual search parameter — check the URL in your browser)
    • Name: URL - Search Query
  2. Create a Page View Trigger for Search Results

    • Trigger type: Page View
    • Fire on: Some Page Views
    • Condition: Page Path contains /search (adjust to match your search URL pattern)
    • Add a second condition: {{URL - Search Query}} does not equal “ (empty string)
  3. Create a GA4 Event Tag

    • Tag type: Google Analytics: GA4 Event
    • Event name: search
    • Parameters:
      • search_term{{URL - Search Query}}
      • page_path{{Page Path}}
    • Trigger: the Page View trigger above
  4. Test in Preview Mode

    Perform a search on your site. Verify the URL contains your parameter, then check the Summary pane for the search event with the correct search_term value.

Tag Configuration

GA4 - search

Type
Google Analytics: GA4 Event
Trigger
Page View - search results page
Variables
URL - Search QueryPage Path
Section titled “Option B — dataLayer push (recommended for full control)”

Push from your search results template for zero-results tracking and result count metadata.

dataLayer.push() search

Push this on your search results page after results are loaded.

// Add this to your search results page template
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'search',
search_term: 'your-term-from-server', // Replace with server-side template variable
search_results_count: 42, // Replace with actual count from server
search_has_results: true, // false if 0 results
search_category: 'all' // if your search has category filtering
});

In a Next.js or similar SSR application:

// In your search results page component
useEffect(() => {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'search',
search_term: router.query.q,
search_results_count: results.total,
search_has_results: results.total > 0
});
}, [results]);
  1. Add the dataLayer push to your search results template. Push after results are loaded, not on page load.

  2. Create a Custom Event Trigger

    • Trigger type: Custom Event
    • Event name: search
  3. Create Data Layer Variables

    • DLV - search_termsearch_term
    • DLV - search_results_countsearch_results_count
    • DLV - search_has_resultssearch_has_results
  4. Create a GA4 Event Tag

    • Event name: search
    • Parameters:
      • search_term{{DLV - search_term}}
      • search_results_count{{DLV - search_results_count}}
      • search_has_results{{DLV - search_has_results}}
    • Trigger: the Custom Event trigger
  5. Test in Preview Mode

    Perform searches with and without results. Each should fire a search event with the correct search_term and search_results_count.

Zero-results searches are content gaps. Create a separate GA4 conversion event or audience for them:

In GA4 → Admin → Events → Mark as Key Event: create a filtered event for searches where search_has_results = false.

Or use a Custom Audience in GA4: users who triggered search with parameter search_has_results = false.

Export these queries to a spreadsheet weekly and review them with your content team.

  1. Open GTM Preview and perform a search on your site
  2. Check the Summary pane for the search event
  3. Verify search_term matches what you searched
  4. If using the dataLayer approach, verify search_results_count is correct
  5. Perform a search that returns no results and verify search_has_results is false
  6. Check GA4 DebugView for the search event with parameters

URL parameter is different per search integration. WordPress uses s=, Algolia uses query=, Elasticsearch uses various parameters. Check your search URL before configuring the URL variable.

Search query contains PII. If users search for their own email addresses or account numbers, those values flow into GA4. Consider scrubbing PII patterns from search_term before pushing. See the PII Detection recipe.

Autocomplete results never load a search page. If your search uses live autocomplete without a results page navigation, the Page View trigger will not fire. Use a custom event from your autocomplete component’s onSelect handler.