Google Analytics 4 Setup on Kentico | OpsBlu Docs

Google Analytics 4 Setup on Kentico

Step-by-step guide to installing and configuring Google Analytics 4 on Kentico Xperience websites

This guide covers how to install and configure Google Analytics 4 (GA4) on Kentico Xperience websites using both MVC and Portal Engine development models.

Prerequisites

  • Google Analytics 4 property created
  • GA4 Measurement ID (format: G-XXXXXXXXXX)
  • Admin access to Kentico
  • Access to edit layout files or master pages

For MVC Development Model (Kentico 12+)

  1. Locate Your Layout File

    • Navigate to ~/Views/Shared/_Layout.cshtml in your project
    • Or your custom layout file if using a different structure
  2. Add GA4 Tracking Code to Layout

Add this code in the <head> section:

<!-- Google Analytics 4 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-XXXXXXXXXX', {
    'send_page_view': true,
    'cookie_flags': 'SameSite=None;Secure'
  });
</script>
  1. Make It Dynamic with Kentico Settings

First, create a setting in Kentico:

  • Go to SettingsIntegrationGoogle
  • Create a new setting key: GoogleAnalyticsMeasurementID
  • Enter your GA4 Measurement ID

Then update your layout file:

@using CMS.Helpers
@{
    var gaId = SettingsKeyInfoProvider.GetValue("GoogleAnalyticsMeasurementID", SiteContext.CurrentSiteID);
}

@if (!string.IsNullOrEmpty(gaId))
{
    <!-- Google Analytics 4 -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=@gaId"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());

      gtag('config', '@gaId', {
        'send_page_view': true,
        'cookie_flags': 'SameSite=None;Secure'
      });
    </script>
}

For Portal Engine (Legacy)

  1. Access Master Page

    • Go to DesignMaster pages
    • Edit your root master page (typically the one used site-wide)
  2. Add Code to Master Page

In the Master page code section, add to <head>:

<!-- Google Analytics 4 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-XXXXXXXXXX');
</script>
  1. Using Kentico Macros for Dynamic Values
{% raw %}{%
var gaId = SettingsKeyInfoProvider.GetValue("GoogleAnalyticsMeasurementID");
if (!String.IsNullOrEmpty(gaId)) {
%}
<!-- Google Analytics 4 -->
<script async src="https://www.googletagmanager.com/gtag/js?id={% gaId %}"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', '{% gaId %}');
</script>
{% } %}{% endraw %}

Method 2: Using a Custom Web Part (Portal Engine)

Create a reusable Web Part for GA4 tracking:

  1. Create Custom Web Part

    • Go to DevelopmentWeb partsNew web part
    • Name: GoogleAnalytics4
    • Parent category: Choose or create "Analytics"
  2. Web Part Properties

Add these properties:

  • MeasurementID (Text) - GA4 Measurement ID
  • EnablePageView (Boolean) - Enable automatic page view tracking
  • DebugMode (Boolean) - Enable debug mode
  1. Web Part Code
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="GoogleAnalytics4.ascx.cs" Inherits="CustomWebParts.GoogleAnalytics4" %>

<% if (!String.IsNullOrEmpty(MeasurementID)) { %>
<!-- Google Analytics 4 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= MeasurementID %>"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', '<%= MeasurementID %>', {
    'send_page_view': <%= EnablePageView.ToString().ToLower() %>,
    'debug_mode': <%= DebugMode.ToString().ToLower() %>
  });
</script>
<% } %>
  1. Add to Master Page
    • Drag the Web Part into your master page
    • Configure the properties
    • Save and publish

Method 3: Using Custom Module (Advanced)

For enterprise implementations requiring centralized control:

  1. Create Custom Module

    • Go to DevelopmentModulesNew module
    • Name: GoogleAnalyticsIntegration
  2. Add Module Class

using CMS;
using CMS.Base;
using CMS.DataEngine;
using CMS.Helpers;
using CMS.SiteProvider;

[assembly: RegisterModule(typeof(GoogleAnalyticsModule))]

public class GoogleAnalyticsModule : Module
{
    public GoogleAnalyticsModule() : base("GoogleAnalyticsIntegration") { }

    protected override void OnInit()
    {
        base.OnInit();

        // Register event handler for page rendering
        RequestEvents.PostMapRequestHandler.Execute += PostMapRequestHandler_Execute;
    }

    private void PostMapRequestHandler_Execute(object sender, EventArgs e)
    {
        // Add GA4 script to page head
        var measurementId = SettingsKeyInfoProvider.GetValue("GoogleAnalyticsMeasurementID", SiteContext.CurrentSiteID);

        if (!string.IsNullOrEmpty(measurementId))
        {
            string gaScript = $@"
                <script async src='https://www.googletagmanager.com/gtag/js?id={measurementId}'></script>
                <script>
                  window.dataLayer = window.dataLayer || [];
                  function gtag(){{dataLayer.push(arguments);}}
                  gtag('js', new Date());
                  gtag('config', '{measurementId}');
                </script>";

            CMS.Base.Web.UI.ScriptHelper.RegisterClientScriptBlock(
                typeof(string),
                "GA4Tracking",
                gaScript,
                false
            );
        }
    }
}

Multi-Site Configuration

For Kentico installations managing multiple sites:

  1. Create Site-Specific Settings

    • Go to Settings[Your Site]Integration
    • Add GoogleAnalyticsMeasurementID setting at site level
    • Enter different GA4 IDs for each site
  2. Layout Code for Multi-Site

@using CMS.Helpers
@using CMS.SiteProvider
@{
    var currentSite = SiteContext.CurrentSite;
    var gaId = SettingsKeyInfoProvider.GetValue("GoogleAnalyticsMeasurementID", currentSite.SiteID);
}

@if (!string.IsNullOrEmpty(gaId))
{
    <!-- Google Analytics 4 for @currentSite.SiteName -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=@gaId"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());

      gtag('config', '@gaId', {
        'custom_map': {
          'dimension1': 'site_name'
        },
        'site_name': '@currentSite.SiteName'
      });
    </script>
}

Excluding Staging/Development Environments

Prevent tracking on non-production environments:

@{
    var isProduction = SiteContext.CurrentSite.SiteName == "ProductionSite";
    var gaId = SettingsKeyInfoProvider.GetValue("GoogleAnalyticsMeasurementID", SiteContext.CurrentSiteID);
}

@if (isProduction && !string.IsNullOrEmpty(gaId))
{
    <!-- GA4 code here -->
}

Or use macro expressions:

{% raw %}{% if(CurrentSite.SiteName == "ProductionSite") { %}
<!-- GA4 code here -->
{% } %}{% endraw %}

Enhanced Measurement Configuration

Configure GA4 enhanced measurement features:

gtag('config', 'G-XXXXXXXXXX', {
  // Enhanced measurement
  'send_page_view': true,
  'enhanced_measurement': {
    'scrolls': true,
    'outbound_clicks': true,
    'site_search': true,
    'video_engagement': true,
    'file_downloads': true
  },

  // Custom parameters
  'custom_map': {
    'dimension1': 'kentico_page_type',
    'dimension2': 'kentico_document_type',
    'dimension3': 'user_authenticated'
  },

  // Page-specific data
  'kentico_page_type': '@ViewBag.PageType',
  'kentico_document_type': '@ViewBag.DocumentType',
  'user_authenticated': '@(User.Identity.IsAuthenticated ? "yes" : "no")'
});

User ID Tracking

Track authenticated users across devices:

@using CMS.Membership
@{
    var currentUser = MembershipContext.AuthenticatedUser;
    var userId = currentUser != null && !currentUser.IsPublic()
        ? currentUser.UserID.ToString()
        : null;
}

<script>
  gtag('config', 'G-XXXXXXXXXX', {
    @if (userId != null) {
      <text>'user_id': '@userId',</text>
    }
    'send_page_view': true
  });
</script>

Testing Your Implementation

  1. Use GA4 DebugView

    • Add debug_mode: true to your config
    • Open GA4 → Configure → DebugView
    • Navigate your site and verify events
  2. Browser Developer Tools

    • Open Network tab
    • Filter by "collect" or "google-analytics"
    • Verify requests are being sent
  3. GA4 Realtime Reports

    • Open GA4 → Reports → Realtime
    • Navigate your site
    • Check for active users and page views
  4. Tag Assistant (Chrome Extension)

    • Install Google Tag Assistant
    • Click the extension while on your site
    • Verify GA4 tag is firing

Common Issues

GA4 Not Tracking

  • Verify Measurement ID is correct (format: G-XXXXXXXXXX)
  • Check browser console for errors
  • Ensure scripts are in <head> or before </body>
  • Verify no ad blockers are interfering

Duplicate Page Views

  • Check if tracking code appears multiple times
  • Verify not implementing both direct and GTM GA4
  • Check for multiple layout files loading the same code

Staging Environment Tracking Production

  • Implement environment-based conditional loading
  • Use different GA4 properties for staging/production
  • Add staging domain to referral exclusion list

Next Steps

Additional Resources