{"id":1802,"date":"2025-11-20T11:46:28","date_gmt":"2025-11-20T11:46:28","guid":{"rendered":"https:\/\/daveashworth.co\/blog\/?p=1802"},"modified":"2026-09-23T03:55:44","modified_gmt":"2026-09-23T02:55:44","slug":"how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm","status":"publish","type":"post","link":"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/","title":{"rendered":"How To: Track Internal Link Clicks in GA4 Using Google Tag Manager"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>TL;DR:<\/strong> <br>GA4 doesn&#8217;t automatically track ordinary internal link clicks with its default <code>click<\/code> event. Enhanced Measurement uses the <code>click<\/code> event for outbound links, so if you want to track which internal links users click, including menu, content and footer links, you&#8217;ll need additional tracking. This guide shows how I use Google Tag Manager to send a custom <code>click_internal_link<\/code> event to GA4, including the link text, destination path, source page and page section.<br><\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_89 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Does_GA4_Track_Internal_Link_Clicks_Automatically\" >Does GA4 Track Internal Link Clicks Automatically?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Setting_Up_Internal_Link_Click_Tracking_in_GA4\" >Setting Up Internal Link Click Tracking in GA4<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Step_1_Create_the_click_internal_link_GA4_Event\" >Step 1: Create the click_internal_link GA4 Event<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Step_2_Configure_the_Internal_Link_Event_Parameters\" >Step 2: Configure the Internal Link Event Parameters<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Step_3_Create_the_Internal_Link_Click_Trigger\" >Step 3: Create the Internal Link Click Trigger<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Step_4_Test_the_Internal_Link_Event_and_Trigger\" >Step 4: Test the Internal Link Event and Trigger<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Step_5_Create_Custom_Definitions_for_the_Event_Parameters\" >Step 5: Create Custom Definitions for the Event Parameters<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Step_6_Create_an_Internal_Link_Click_Report\" >Step 6: Create an Internal Link Click Report<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Report_internal_link_clicks_in_Looker_Studio\" >Report internal link clicks in Looker Studio<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Report_internal_link_clicks_in_GA4_Explorations\" >Report internal link clicks in GA4 Explorations<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/daveashworth.co\/blog\/how-to-track-internal-link-clicks-in-google-analytics-4-via-gtm\/#Why_Track_Internal_Link_Clicks_in_GA4\" >Why Track Internal Link Clicks in GA4?<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Does_GA4_Track_Internal_Link_Clicks_Automatically\"><\/span>Does GA4 Track Internal Link Clicks Automatically?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">No. GA4 doesn&#8217;t automatically record ordinary internal link clicks using its default <code>click<\/code> event. With Enhanced Measurement enabled, the <code>click<\/code> event is used for <strong>outbound link clicks<\/strong>, where somebody clicks a link that takes them away from your domain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are many ways you can <a href=\"https:\/\/daveashworth.co\/skills\/analytics-and-ad-tracking-consultant\/google-analytics-4\/\">enhance your GA4 tracking<\/a> with bespoke events <a href=\"https:\/\/daveashworth.co\/skills\/google-tag-manager-consultant\/\">implemented using Google Tag Manager<\/a>, and internal link tracking is one of my favourites.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It lets you see how users navigate around your website, including which links they click within your menus, main content and footer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to know <strong>which internal links users actually click<\/strong>, rather than simply seeing the subsequent page view, you need to implement additional tracking.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The following is the approach I use on client websites following a standard <a href=\"https:\/\/daveashworth.co\/services-and-consultancy\/website-tracking-audits-consultant\/\">website tracking audit<\/a>. It uses Google Tag Manager to send a custom <code>click_internal_link<\/code> event into GA4, along with useful information about the link and where it was clicked.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Setting_Up_Internal_Link_Click_Tracking_in_GA4\"><\/span>Setting Up Internal Link Click Tracking in GA4<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The setup uses Google Tag Manager to detect clicks on links that point to your own website and send them to GA4 as a custom <code>click_internal_link<\/code> event.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Rather than simply recording that a click happened, I also pass additional parameters with the event so I can see <strong>which link was clicked, where it pointed, which page the click happened on and where on the page the link appeared<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This gives you much more useful data for analysing how people navigate around your website, including interactions with menu links, contextual links within your content and links in the footer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s how I set it up.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_1_Create_the_click_internal_link_GA4_Event\"><\/span>Step 1: Create the <code>click_internal_link<\/code> GA4 Event<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The first step is to create the GA4 event that will be sent whenever somebody clicks an internal link.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In Google Tag Manager, create a GA4 event with the event name:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>click_internal_link<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Configure the event as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"695\" height=\"423\" src=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/click_internal_link_event.png\" alt=\"Event Tag Config\" class=\"wp-image-1803\" srcset=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/click_internal_link_event.png 695w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/click_internal_link_event-300x183.png 300w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/click_internal_link_event-150x91.png 150w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_2_Configure_the_Internal_Link_Event_Parameters\"><\/span>Step 2: Configure the Internal Link Event Parameters<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Recording the event tells us that an internal link was clicked, but the parameters are what make the data genuinely useful.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I use the following parameters to capture information about the link, its destination, the page it was clicked from and its position on the page:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>click_text<\/code><br><\/li>\n\n\n\n<li><code>click_path<\/code><br><\/li>\n\n\n\n<li><code>page_path<\/code><br><\/li>\n\n\n\n<li><code>page_section<\/code><br><\/li>\n\n\n\n<li><code>click_class<\/code><br><\/li>\n\n\n\n<li><code>click_id<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You don&#8217;t necessarily need every parameter for every implementation, but this is the setup I use because it gives me plenty of flexibility when I come to analyse and report on internal link clicks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code><strong>click_text<\/strong><\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This captures the anchor text of the internal link that was clicked. For example:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"761\" height=\"164\" src=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link.png\" alt=\"\" class=\"wp-image-1804\" srcset=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link.png 761w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link-300x65.png 300w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link-150x32.png 150w\" sizes=\"(max-width: 761px) 100vw, 761px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can capture this using GTM&#8217;s built-in <code>{{Click Text}}<\/code> variable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is useful when the same destination is linked from multiple places or using different anchor text, because you can see <strong>which particular internal links users are actually interacting with<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><code>click_path<\/code><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This captures the path of the page that the internal link points to.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">GTM already provides the built-in <code>{{Click URL}}<\/code> variable, but this returns the full URL, including the domain. For example:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/daveashworth.co\/skills\/analytics-and-ad-tracking-consultant\/cookie-consent-compliance\/\">https:\/\/daveashworth.co\/skills\/analytics-and-ad-tracking-consultant\/cookie-consent-compliance\/<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can track the full URL if you prefer, but because we already know this is an internal link, I generally find the path more useful for reporting.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To remove the domain, create a <a href=\"https:\/\/daveashworth.co\/skills\/google-tag-manager-consultant\/\">Custom JavaScript variable<\/a> using:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function()\n{\n  var a = document.createElement('a');\n  a.href = {{Click URL}};\n  return a.pathname + a.search + a.hash;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This converts the full clicked URL into:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>\/skills\/analytics-and-ad-tracking-consultant\/cookie-consent-compliance\/<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I then pass this value to GA4 as the <code>click_path<\/code> parameter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Keeping the query string and fragment in the returned value also means you can distinguish between internal links that point to different URL parameters or anchors on the same page.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><code>page_path<\/code><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This captures the path of the page <strong>where the internal link was clicked<\/strong>, rather than the destination of the link.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can capture this using GTM&#8217;s built-in <code>{{Page Path}}<\/code> variable. For example:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>\/skills\/google-tag-manager-consultant\/<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This means that when you analyse the event in GA4, you can see both:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>page_path<\/code> &#8211; the page the user was on when they clicked<br><\/li>\n\n\n\n<li><code>click_path<\/code> &#8211; the page the internal link pointed to<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Together, these make it possible to analyse how users navigate <strong>from one page to another<\/strong> through your internal links.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;d prefer to capture the complete source URL rather than just the path, you can use <code>{{Page URL}}<\/code> instead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><code>page_section<\/code><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is one of the most useful parameters for me. As well as knowing which internal link somebody clicked, I want to know <strong>where on the page that link appeared<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, was it:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>a navigation or menu link in the header<br><\/li>\n\n\n\n<li>a contextual link within the main content<br><\/li>\n\n\n\n<li>a link in the footer<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This means the same internal link event can also be used to analyse things such as <strong>menu clicks in GA4<\/strong>, rather than requiring a completely separate tracking implementation for your navigation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Similar approaches can also be used to <a href=\"https:\/\/daveashworth.co\/blog\/how-to-track-link-and-banner-clicks-with-google-tag-manager\/\">track clicks on banners<\/a>, CTAs and other important content areas. Combined with <a href=\"https:\/\/daveashworth.co\/blog\/how-to-track-form-field-values-in-ga4-using-google-tag-manager\/\">form tracking<\/a>, this can give you much deeper insight into how users engage with your content and conversion paths.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To capture the page section, I use the following Custom JavaScript variable:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function() {\n  \/\/ Function to check if an element matches a given selector\n  function matchesSelector(element, selector) {\n    var matchFn = element.matches || element.webkitMatchesSelector || element.mozMatchesSelector || element.msMatchesSelector;\n    return matchFn ? matchFn.call(element, selector) : false;\n  }\n\n  \/\/ Get the clicked element from GTM's built-in variable\n  var clickedElement = {{Click Element}};\n\n  \/\/ Selectors for different sections\n  var headerSelector = \"nav, nav *, #mbl-menu, #mbl-menu *\";\n  var contentSelector = \".container, .container *\";\n  var footerSelector = \"footer, footer *\";\n\n  \/\/ Check if the clicked element or any of its parents match the selectors\n  while (clickedElement) {\n    if (matchesSelector(clickedElement, headerSelector)) {\n      return \"header\";\n    } else if (matchesSelector(clickedElement, contentSelector)) {\n      return \"content\";\n    } else if (matchesSelector(clickedElement, footerSelector)) {\n      return \"footer\";\n    }\n    clickedElement = clickedElement.parentElement;\n  }\n\n  \/\/ Default return if no section is matched\n  return \"unknown\";\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ll probably need to amend the selectors to match the way your own website is structured.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The important lines are:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>headerSelector<\/code><br><code>contentSelector<\/code><br><code>footerSelector<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your site uses standard semantic elements such as <code>&lt;nav&gt;<\/code>, <code>&lt;main&gt;<\/code> and <code>&lt;footer&gt;<\/code>, you can target those elements directly. For example:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>var contentSelector = \"main, main *\";<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first selector targets the element itself, while <code>main *<\/code> also matches elements contained within it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your layout uses IDs or classes instead, you can target those in the same way. For example, an ID:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>#mbl-menu, #mbl-menu *<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Or a class:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>.container, .container *<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, these lines determine the value sent to GA4:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>return \"header\";<\/code><br><code>return \"content\";<\/code><br><code>return \"footer\";<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can change these values or add additional page sections if you need more granular reporting.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><code>click_class<\/code> and <code>click_id<\/code><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You may also want to capture the CSS class or ID of the element that was clicked.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This can be useful when you want to distinguish between particular types of internal links, such as a &#8220;read more&#8221; component, a specific CTA or links within a particular part of your navigation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">GTM already provides built-in variables for both, so you can simply pass:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>{{Click Classes}}<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">and:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>{{Click ID}}<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">into the corresponding <code>click_class<\/code> and <code>click_id<\/code> event parameters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I treat these as optional parameters. Whether they&#8217;re useful will depend on how your website is built and how granular you want your internal link reporting to be.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_3_Create_the_Internal_Link_Click_Trigger\"><\/span>Step 3: Create the Internal Link Click Trigger<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Next, create the trigger that determines when the <code>click_internal_link<\/code> event should fire.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In Google Tag Manager, select the trigger type:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Click &#8211; Just Links<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then set the condition to:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Click URL &#8211; starts with &#8211; your domain<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/daveashworth.co\">https:\/\/daveashworth.co<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This means the trigger will fire when somebody clicks a link pointing to a URL on your own domain, rather than an external website.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"693\" height=\"189\" src=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/trigger_config.png\" alt=\"Trigger Config\" class=\"wp-image-1805\" srcset=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/trigger_config.png 693w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/trigger_config-300x82.png 300w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/trigger_config-150x41.png 150w\" sizes=\"(max-width: 693px) 100vw, 693px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your website operates across multiple subdomains that you also want to treat as internal, you can use a regular expression instead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if I wanted to capture internal link clicks across both <code>www<\/code> and <code>shop<\/code> subdomains, I could use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>^https:\\\/\\\/(www|shop)\\.daveashworth\\.co\\\/.*<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"693\" height=\"184\" src=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/trigger_config_regex.png\" alt=\"Trigger Config Regex\" class=\"wp-image-1817\" srcset=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/trigger_config_regex.png 693w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/trigger_config_regex-300x80.png 300w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/trigger_config_regex-150x40.png 150w\" sizes=\"(max-width: 693px) 100vw, 693px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Adjust this condition to match your own domain and website setup. The important thing is that the trigger captures the internal destinations you consider part of the site without also firing for outbound links.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_4_Test_the_Internal_Link_Event_and_Trigger\"><\/span>Step 4: Test the Internal Link Event and Trigger<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Before publishing the changes, use <strong>Preview<\/strong> mode in Google Tag Manager to make sure the event fires as expected.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Click several different internal links on your website, ideally from different page sections such as the header, main content and footer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If everything is configured correctly, you should see the <code>click_internal_link<\/code> event fire in the GTM debugger with the parameters you&#8217;ve configured.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"508\" src=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/gtm_debugger-1024x508.png\" alt=\"GTM Debugger\" class=\"wp-image-1807\" srcset=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/gtm_debugger-1024x508.png 1024w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/gtm_debugger-300x149.png 300w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/gtm_debugger-150x74.png 150w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/gtm_debugger-768x381.png 768w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/gtm_debugger.png 1257w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Check the parameter values as well as the event itself. For example, make sure:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>click_text<\/code> contains the expected anchor text<br><\/li>\n\n\n\n<li><code>click_path<\/code> contains the destination path<br><\/li>\n\n\n\n<li><code>page_path<\/code> contains the page the click originated from<br><\/li>\n\n\n\n<li><code>page_section<\/code> correctly identifies the header, content or footer<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;d also test an <strong>external link<\/strong> to confirm that the internal link trigger does <strong>not<\/strong> fire.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once you&#8217;re happy that everything is working correctly, publish the GTM container.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_5_Create_Custom_Definitions_for_the_Event_Parameters\"><\/span>Step 5: Create Custom Definitions for the Event Parameters<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Once the event is live and sending data to GA4, you&#8217;ll need to create custom definitions for any custom event parameters you want to use in your GA4 reports and Explorations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if you want to report on the <code>page_section<\/code> parameter, go to:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Admin \u2192 Data display \u2192 Custom definitions \u2192 Create custom dimension<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Give the dimension a clear name, select <strong>Event<\/strong> as the scope, and enter the corresponding event parameter, such as:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>page_section<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"754\" height=\"357\" src=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/new_custom_definition.png\" alt=\"\" class=\"wp-image-1808\" srcset=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/new_custom_definition.png 754w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/new_custom_definition-300x142.png 300w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/new_custom_definition-150x71.png 150w\" sizes=\"(max-width: 754px) 100vw, 754px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Step_6_Create_an_Internal_Link_Click_Report\"><\/span>Step 6: Create an Internal Link Click Report<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Now that the event and parameters are being collected, you can use the data to analyse <strong>which internal links users click and how they navigate between pages<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can do this directly in GA4 using Explorations, or build a more flexible report in Looker Studio.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Report_internal_link_clicks_in_Looker_Studio\"><\/span><strong>Report internal link clicks in Looker Studio<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">To create an internal link click report in <a href=\"https:\/\/daveashworth.co\/skills\/looker-studio-consultant\/\">Looker Studio<\/a>, add the dimensions you want to analyse, such as the source page, destination path, link text and page section.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use <strong>Event count<\/strong> as the metric, then add a filter so the report only includes:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Event name = <code>click_internal_link<\/code><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"392\" src=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_looker_studio-1024x392.png\" alt=\"\" class=\"wp-image-1809\" srcset=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_looker_studio-1024x392.png 1024w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_looker_studio-300x115.png 300w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_looker_studio-150x57.png 150w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_looker_studio-768x294.png 768w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_looker_studio.png 1221w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This gives you a useful way to analyse which internal links are receiving clicks, where those links appear and how users are navigating through the site.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, you could compare <strong>header or menu clicks against contextual links within the main content<\/strong>, or identify which destination pages receive the most internal click-throughs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once your <a href=\"https:\/\/daveashworth.co\/blog\/how-to-configure-events-and-conversions-for-google-analytics-4\/\">events and parameters<\/a> are configured correctly, you can also use them within broader GA4 reporting where appropriate.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Report_internal_link_clicks_in_GA4_Explorations\"><\/span><strong>Report internal link clicks in GA4 Explorations<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">If you don&#8217;t need a separate Looker Studio report, you can analyse the same event directly within a GA4 Exploration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create an Exploration using the relevant dimensions and metrics, then filter the report to:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Event name = <code>click_internal_link<\/code><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"608\" src=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_ga4_explore-1024x608.png\" alt=\"\" class=\"wp-image-1810\" srcset=\"https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_ga4_explore-1024x608.png 1024w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_ga4_explore-300x178.png 300w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_ga4_explore-150x89.png 150w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_ga4_explore-768x456.png 768w, https:\/\/daveashworth.co\/blog\/wp-content\/uploads\/2025\/11\/internal_link_report_ga4_explore.png 1333w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Which reporting method you use is largely down to preference. The important part is that you&#8217;re no longer limited to knowing that somebody viewed another page. You can analyse <strong>the actual internal link they clicked to get there<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Why_Track_Internal_Link_Clicks_in_GA4\"><\/span>Why Track Internal Link Clicks in GA4?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Internal link tracking gives you a level of behavioural data that you don&#8217;t get from standard GA4 page view reporting alone.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of only seeing that somebody moved from one page to another, you can see <strong>which internal link they clicked, where that link appeared and which page it took them to<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I find this particularly useful for understanding how people interact with navigation menus, contextual links, calls to action and other routes through a website.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can then use that data to answer questions such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Which internal links get the most clicks?<br><\/li>\n\n\n\n<li>Are users navigating through the links within the main content?<br><\/li>\n\n\n\n<li>Which pages receive the most internal click-throughs?<br><\/li>\n\n\n\n<li>Do users interact more with header, content or footer links?<br><\/li>\n\n\n\n<li>Which menu links are actually being used?<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s a relatively simple addition to a GA4 and GTM setup, but it can give you much more useful insight into <strong>how people actually navigate around your website<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you need help implementing custom GA4 event tracking or configuring GTM for more advanced reporting, take a look at my <a href=\"https:\/\/daveashworth.co\/skills\/analytics-and-ad-tracking-consultant\/\">analytics and tracking consultancy services<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>GA4 doesn&#8217;t automatically track ordinary internal link clicks, but you can capture them with Google Tag Manager. This guide shows how I track internal links, including the link text, destination, source page and page section, then report on the data in GA4 and Looker Studio.<\/p>\n","protected":false},"author":1,"featured_media":1820,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,15],"tags":[],"class_list":["post-1802","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tag-manager","category-analytics"],"_links":{"self":[{"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/posts\/1802","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/comments?post=1802"}],"version-history":[{"count":0,"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/posts\/1802\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/media\/1820"}],"wp:attachment":[{"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/media?parent=1802"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/categories?post=1802"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daveashworth.co\/blog\/wp-json\/wp\/v2\/tags?post=1802"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}