How to Implement Google Tag Manager and Consent Mode in NextJS 15
by Spencer, Co-Founder / CTO
Introduction
Web analytics have become indispensable for modern businesses. Whether you’re tracking user interactions, evaluating campaign performance, or understanding your audience, tools like Google Tag Manager (GTM) and Google Analytics (GA) are essential. But as users demand greater control over their data, and as regulations like GDPR and CCPA enforce stricter compliance, integrating analytics without compromising privacy is more important than ever.
Why This Tutorial?
Despite its importance, implementing Google Tag Manager with Consent Mode in NextJS 15 can be challenging:
- NextJS’s Limitations: Tools like
@next/third-parties
lack robust support for Consent Mode, especially when default consent states need to be set in sequence before cached consent values are loaded. - Documentation Gaps: While individual libraries provide usage guides, there’s no comprehensive tutorial on integrating GTM, Consent Mode, and a cookie banner in a NextJS 15 project.
- A Proven Approach: Through hands-on experience, we developed a solution that builds on best practices and extends the functionality of existing tools. This tutorial shares our step-by-step approach, ensuring you achieve both analytics precision and privacy compliance.
Important NextJS Version Compatibility Note
The implementation this tutorial provides also works with NextJS 14 🚀
What You’ll Achieve
By following this guide, you’ll:
- Implement Google Tag Manager in your NextJS application.
- Add Consent Mode for privacy-first tracking.
- Build a cookie consent banner to capture and manage user preferences.
- Gain insights into how to configure GTM to respect consent states dynamically.
At the end of this tutorial, you’ll have a fully functional solution that respects user privacy while collecting valuable analytics data.
Prerequisites
Before diving into the technical steps, ensure your environment and knowledge are ready for the implementation.
Technical Knowledge
To follow this guide effectively, you should be familiar with:
- JavaScript and React: Understanding of components, hooks, and JSX.
- NextJS Framework: Familiarity with features like server-side rendering (SSR) and file-based routing.
- Environment Variables: Experience setting up
.env
files for sensitive data.
While this tutorial includes detailed instructions, some familiarity with these concepts will ensure a smoother learning process.
Tools and Setup
Ensure your development environment includes:
- Node.js (v16 or newer): Install it from Node.js.
- Code Editor: Visual Studio Code is recommended for its robust ecosystem.
- Google Tag Manager Account: Create one at Google Tag Manager.
- GTM ID: Example:
GTM-XXXXXX
.
Already Have a GTM Account?
Ensure you have a valid Google Tag Manager ID (e.g., GTM-XXXXXX) to follow along. If not, create one at Google Tag Manager.
Navigating the Tutorial Repository
To streamline this tutorial, we’ve structured the accompanying repository into phases. Each branch corresponds to a step in the process, allowing you to follow along or compare your implementation at any time.
Repository Overview
Branch Name | Description |
---|---|
phase/0-initial-boilerplate | The starting point: a clean NextJS 15 app. |
phase/1-add-libs | Adds tracking utilities for GTM and Consent Mode. |
phase/2-add-gtm-components | Implements GTM scripts and a wrapper for cached consent handling. |
phase/3-integrate-gtm | Fully integrates GTM, Consent Mode, and the cookie banner. |
phase/complete-implementation | Finalized project with all features implemented. |
Steps to Use the Repository
- Clone the Repository:
- Navigate to the Project Directory:
- Checkout the Initial Phase:
- Install Dependencies:
- Switch Between Phases:
By following these steps, you can incrementally build the project while ensuring each phase works as expected.
Use Branches for Comparison
Each branch is designed to help you compare your work. If something isn’t working, check the corresponding branch for reference.
With the groundwork laid, we’re ready to begin building the project. In the next section, we’ll set up the initial NextJS application and configure it for analytics integration.
Run the Initial Boilerplate
To ensure you’re starting with a clean and functional project, checkout the phase/0-initial-boilerplate
branch and run the development server. This will serve as the foundation for the Google Tag Manager (GTM) integration.
Step 1: Checkout and Run the Initial Boilerplate
Use the following commands to switch to the phase/0-initial-boilerplate
branch and start the project:
Once the server is running, open your browser and navigate to http://localhost:3000
to view the boilerplate project.
Step 2: Confirm the Boilerplate Setup
At this phase, the project includes a minimal Next.js 15 application with placeholder content and no GTM or analytics functionality implemented yet. You should see a homepage resembling the image below:
This clean foundation ensures a smooth transition to the subsequent implementation steps.
Start Simple
The phase/0-initial-boilerplate
branch provides a reliable starting point.
By running and reviewing this base setup, you can identify any issues early
and focus on the GTM and Consent Mode integration with confidence.
With the boilerplate confirmed, you’re ready to move on to Step 1: Adding TypeScript Types to establish a structured framework for GTM interactions.
Phase 1: Setting Up Tracking Utilities in NextJS
In this phase, we’ll establish the foundational tracking utilities for Google Tag Manager (GTM) in your NextJS 15 application. These utilities will ensure a scalable, maintainable way to manage tracking events and consent preferences.
What We’ll Cover
This section is divided into three main steps:
- Adding TypeScript Types: Define global types and interfaces to ensure consistency when interacting with GTM.
- Creating a Configuration Module: Centralize GTM-related settings for ease of use across your app.
- Implementing Tracking Utilities: Build reusable functions for managing GTM interactions, sending events, and handling consent.
By the end of this phase, you’ll have a robust framework for analytics integration, ready to be embedded into your application.
Step 1: Adding TypeScript Types
The first step is to define TypeScript types for GTM-related events and configurations. These types enforce structure and reduce errors when working with tracking data.
Add types.tracking.d.ts
Create a new file at src/libs/tracking/types.tracking.d.ts
with the following content:
Update tsconfig.json
To ensure TypeScript recognizes the new types, we need to include the types.tracking.d.ts
file. Open your tsconfig.json
file and add the following under "include"
:
Explanation
-
Global Namespace Extension:
- Adds
gtag
to theWindow
interface, enabling TypeScript to recognize GTM-specific global properties.
- Adds
-
Standardized Event Types:
- The
EventName
,EventParams
, andCustomParams
interfaces define the expected structure for GTM events. - The
SendGAEventDto
type is tailored for custom event tracking, ensuring consistency across your app.
- The
-
Benefits:
- Centralized definitions make it easy to manage and extend event types.
- Strong typing reduces runtime errors by catching issues during development.
Step 2: Creating a Configuration Module
Next, we’ll set up a configuration file to manage GTM-related settings, including enabling/disabling GTM and storing cookie preferences.
Add config.tracking.ts
Create a new file at src/libs/tracking/config.tracking.ts
with the following content:
Setting Up Environment Variables
To ensure the config.tracking.ts
file works as intended, you need to set up your local environment variables by creating a .env.local
file in the root of your project.
-
Create
.env.local
: In the root of your project, create a new file named.env.local
. -
Add the GTM ID: Add the following line to your
.env.local
file, replacingGTM-XXXXXX
with your actual Google Tag Manager ID:- The
NEXT_PUBLIC_
prefix makes this variable accessible on the client-side, which is required for GTM integration.
- The
-
Save the File: Save your
.env.local
file and restart your development server to ensure the environment variable is loaded.
Explanation
-
Dynamic GTM Toggle:
- The
IS_GTM_ENABLED
constant checks ifNEXT_PUBLIC_GTM_ID
is defined and not empty. This allows you to easily enable or disable GTM, especially in local or staging environments.
- The
-
Centralized Settings:
trackingConfig
consolidates the GTM ID and cookie banner preferences into a single object for reusability.
-
Best Practices:
- Avoid hardcoding sensitive values like GTM IDs directly into your code. Use environment variables (
NEXT_PUBLIC_GTM_ID
) instead for security and flexibility. - Never commit your
.env.local
file to version control to keep your sensitive information secure.
- Avoid hardcoding sensitive values like GTM IDs directly into your code. Use environment variables (
Step 3: Implementing Tracking Utilities
With the types and configuration in place, we’ll create utility functions for interacting with GTM, including sending events, granting consent, and recording page views.
Add utils.tracking.ts
Create a new file at src/libs/tracking/utils.tracking.ts
with the following content:
Explanation
-
Error Handling:
- The
logGAWarning
andgetGtag
functions ensure clear error messages when GTM is not enabled orgtag
is unavailable.
- The
-
Reusable Logic:
withGtag
abstracts error handling, simplifying the implementation of tracking functions likesendGAEvent
andpageview
.
-
Key Functions:
sendGAEvent
: Tracks custom events (e.g., button clicks, form submissions) using the structuredGtagEvent
type.grantConsentForEverything
: Updates consent settings, granting all tracking permissions.pageview
: Records page views for navigation analytics.
-
Scalability:
- These utilities can be reused throughout your app, ensuring consistent tracking behavior.
Summary
In this phase, we achieved the following:
- Added TypeScript Types:
- Defined global GTM properties and event structures for type safety.
- Created a Configuration Module:
- Centralized GTM settings with dynamic enable/disable functionality.
- Implemented Tracking Utilities:
- Built reusable functions for sending events, managing consent, and tracking page views.
With these utilities in place, you’re ready to integrate GTM into your NextJS application. In the next phase, we’ll add GTM components to your app and connect them to the utilities created here.
Need Help Implementing GTM in Your NextJS App?
Partner with Aclarify to accelerate your analytics integration. Our team of experts specializes in NextJS development, Google Tag Manager, and compliance solutions tailored to your business needs.
Phase 2: Adding Google Tag Manager Components
In this phase, we’ll integrate Google Tag Manager (GTM) into your NextJS 15 application by creating components to load GTM scripts dynamically and handle cached consent states. This integration ensures compliance with privacy regulations while maintaining robust analytics capabilities.
What We’ll Cover
- Adding GTM Script Component: Embed GTM into the application with
GoogleTagManagerScripts
, ensuring that GTM scripts are loaded correctly and efficiently. - Creating Consent-Aware GTM Wrapper: Build a
GoogleTagManager
component to manage cached consent preferences and initialize GTM accordingly.
At the end of this phase, your app will have a reusable GTM integration that respects user consent.
Step 1: Adding GTM Script Component
We’ll start by creating the GoogleTagManagerScripts
component. This component is responsible for embedding GTM scripts into the app and tracking page views dynamically.
Create GoogleTagManagerScripts.tsx
Create a new file at src/components/tracking/GoogleTagManagerScripts.tsx
and add the following:
Explanation
-
Dynamic Script Loading:
- The
Script
component from NextJS dynamically loads the GTM scripts using thesrc
attribute. TheonLoadCallback
ensures the app is notified when GTM finishes loading.
- The
-
Default Consent States:
- The inline script (
dangerouslySetInnerHTML
) initializesdataLayer
and sets default consent states (denied
) for all categories (ad storage, personalization, etc.).
- The inline script (
-
Pageview Tracking:
- The
useEffect
hook listens for route changes and triggers thepageview
utility to track navigation events.
- The
-
Feature Usage Marking:
- The
markFeatureUsage
function records the usage of GTM analytics for debugging or performance monitoring.
- The
Be Careful with GTM Script Integration
Embedding scripts dynamically requires careful handling to avoid negatively impacting performance or violating compliance regulations.
- Performance Impact: Ensure scripts are loaded asynchronously to avoid blocking the rendering of critical page elements.
- Compliance Risks: Double-check that default consent states (e.g., denied for ad personalization and analytics) are correctly configured to comply with GDPR and CCPA.
If unsure, consider testing script loading behavior in a staging environment before deploying to production.
Fortunately, our implementation addresses these concerns by loading all gtm-related scripts asynchronously and also setting default consent states immediately.
Step 2: Creating Consent-Aware GTM Wrapper
To handle cached consent preferences and integrate GTM scripts into your app, we’ll create a higher-level wrapper component, GoogleTagManager
.
Install Dependencies
First, add the required dependencies for managing cookies and animations:
Add GoogleTagManager.tsx
Create a new file at src/components/tracking/GoogleTagManager.tsx
and add the following:
Explanation
-
Consent Management:
- The
useEffect
hook retrieves the stored consent value (getCookieConsentValue
) and grants full consent (grantConsentForEverything
) if the user has previously opted in.
- The
-
Suspense for Navigation:
- To track route changes, the
GoogleTagManagerScripts
component usesuseSearchParams
, requiring aSuspense
boundary due to NextJS's data fetching requirements.
- To track route changes, the
-
Fallback for NoScript Environments:
- A
<noscript>
block ensures GTM functionality in browsers with JavaScript disabled by embedding an invisible iframe.
- A
Summary
In this phase, we implemented GTM components to embed analytics scripts and manage user consent:
- GoogleTagManagerScripts:
- Dynamically loads GTM scripts, initializes
dataLayer
, and tracks page views.
- Dynamically loads GTM scripts, initializes
- GoogleTagManager:
- Handles consent preferences, ensures scripts load correctly, and integrates smoothly with NextJS features.
With these components, your app is now ready to manage user consent and track events dynamically. In the next phase, we’ll integrate a cookie consent banner to enhance compliance and improve the user experience.
Phase 3: Integrating Google Tag Manager into the Global Layout
In this final phase, we’ll integrate the Google Tag Manager (GTM) and cookie consent banner directly into the global layout of the application. This ensures that tracking and consent management are accessible throughout the app, providing a seamless user experience.
What We’ll Cover
- Adding the Client-Side Inner Layout: Create a reusable
RootInnerLayout
component to manage the cookie consent banner. - Embedding GTM in the Global Layout: Modify the global
layout.tsx
to include GTM and the inner layout for cookie consent.
By the end of this phase, your application will have a robust and privacy-compliant analytics integration that is active across all pages.
Step 1: Adding the Client-Side Inner Layout
The RootInnerLayout
component handles the cookie consent banner using the react-cookie-consent
library. It provides a clean structure for managing global UI elements like modals or banners.
Create RootInnerLayout.tsx
Add a new file at src/components/layouts/RootInnerLayout.tsx
with the following code:
Explanation
-
Cookie Consent Management:
- The
react-cookie-consent
library is used to display a consent banner at the bottom of the page. When the user clicks "Acknowledge," it calls thegrantConsentForEverything
utility to grant full consent for tracking.
- The
-
Animations:
- The
framer-motion
library animates the appearance of the cookie banner for a smooth user experience.
- The
Step 2: Embedding GTM in the Global Layout
To enable GTM and the RootInnerLayout
, we’ll update the global layout file (layout.tsx
) to include these components.
Modify layout.tsx
Update the existing src/app/layout.tsx
file with the following code:
Explanation
-
GTM Integration:
- The
GoogleTagManager
component is conditionally rendered based on theIS_GTM_ENABLED
configuration flag, ensuring GTM scripts only load when a valid GTM ID is provided.
- The
-
Cookie Consent Banner:
- The
RootInnerLayout
wraps the entire application and includes the consent banner, ensuring it is displayed consistently across all pages.
- The
Summary
In this phase, we integrated GTM and the cookie consent banner into the global layout:
- RootInnerLayout:
- A reusable component for managing cookie consent and global UI elements.
- GTM in Global Layout:
- GTM scripts are conditionally embedded across the app, ensuring analytics functionality while respecting user preferences.
With this integration complete, your application is now fully equipped with analytics, user consent management, and a scalable global layout structure. Congratulations on completing the tutorial! 🎉
Testing the Full Integration
After completing the implementation, it’s essential to test the integration to ensure everything functions as expected. Google Tag Manager (GTM) events, such as consent initialization and updates, must be verified to confirm proper tracking and consent mechanisms.
In this section, we’ll guide you through visual testing, verifying consent mechanisms, and inspecting event tracking using Google Tag Assistant. Additionally, we recommend referring to Google’s official guide for detailed instructions on setting up and using Tag Assistant effectively.
Step 1: Perform a Visual Test
Start by visually inspecting your implementation in the browser to confirm the behavior of the cookie banner and consent mechanism:
-
Open the Site:
- Navigate to your application in the browser (e.g.,
http://localhost:3000
).
- Navigate to your application in the browser (e.g.,
-
Confirm the Cookie Banner:
- On the first load, the cookie banner should appear at the bottom of the page.
- The banner will display the consent message and the acknowledgment button.
-
Acknowledge the Banner:
- Click the acknowledgment button. This action will:
- Write consent information to the cookie specified in your configuration.
- Trigger the
grantConsentForEverything
function to update the consent state.
- Click the acknowledgment button. This action will:
-
Refresh the Page:
- Reload the page. The cookie banner should no longer appear, as the consent state is now stored in the cookie.
-
Repeat for Testing:
- Clear your cookies and reload the site to ensure the cookie banner reappears, confirming the consent state depends on cookie storage.
Verify Cookie Behavior
Make sure the consent cookie is written correctly and persists between page
reloads. Use your browser’s developer tools to inspect the cookieConsent
cookie value under the "Application" tab.
Step 2: Setting Up Google Tag Assistant
After confirming the visual behavior, use Google Tag Assistant to verify GTM event tracking and consent initialization. Follow these steps to configure and connect the debugger:
-
Access Tag Assistant:
- Open Google Tag Assistant.
- Log in with your Google account if prompted.
-
Enable Tag Assistant Debug Mode:
- Click the Enable Debug Mode button.
- Enter the URL of your development environment (e.g.,
http://localhost:3000
). - Click Start to launch a new browser tab with debugging enabled.
-
Verify the Debug Connection:
- Return to the Tag Assistant interface and confirm the debugger is connected to your development environment.
For more details on configuring Tag Assistant, refer to Google's official setup guide.
Step 3: Examining Key Events
Once Tag Assistant is running, you’ll use the debug interface to inspect the GTM events triggered by your application. Below are two key events to verify:
Event: Consent Default
The Consent Default event initializes when the application loads. By default, all consent options (e.g., analytics and ad personalization) are set to Denied, ensuring compliance with privacy regulations such as GDPR and CCPA.
- Expected Behavior:
- The "On-page Default" column should display Denied for all options (e.g.,
ad_storage
,analytics_storage
). - The corresponding
gtag
function call should indicate"consent": "default"
.
- The "On-page Default" column should display Denied for all options (e.g.,
Here’s a visual example of the Consent Default event:
Event: Consent Update
The Consent Update event occurs when a user interacts with the cookie banner and provides consent. When this happens, the consent status transitions to Granted, enabling analytics tracking and other services.
- Expected Behavior:
- The "On-page Update" column should display Granted for all options (e.g.,
ad_storage
,analytics_storage
). - The corresponding
gtag
function call should indicate"consent": "update"
with granted permissions.
- The "On-page Update" column should display Granted for all options (e.g.,
Here’s a visual example of the Consent Update event:
Step 4: Validating the Integration
After verifying the events, ensure that GTM is functioning as intended across your site:
-
Navigate the Site:
- Use your site as a typical user would, navigating between pages and interacting with elements.
- Confirm that the
pageview
event is triggered on route changes.
-
Check the Data Layer:
- In the Tag Assistant debugger, inspect the Data Layer tab to verify that all expected variables (e.g.,
gtm.start
,page_path
) are populated.
- In the Tag Assistant debugger, inspect the Data Layer tab to verify that all expected variables (e.g.,
-
Verify Consent Persistence:
- Reload the site and ensure that the consent state (e.g., Granted or Denied) persists based on the user’s prior input.
-
Debug Any Issues:
- If you notice discrepancies, revisit your GTM setup, or refer to Google’s troubleshooting guide.
Next Steps
With the testing phase complete, your GTM and Consent Mode integration should now be ready for production. By using tools like Tag Assistant, you ensure compliance with privacy regulations while maintaining robust analytics tracking.
If you encounter any issues or need to scale this implementation further, consider adding additional GTM triggers, refining your cookie banner design, or consulting the Google Tag Manager Help Center.
Conclusion: Achieving Analytics and Compliance Harmony in NextJS
That's it! You've successfully integrated Google Tag Manager (GTM) with Consent Mode in your NextJS 15 application, creating a privacy-compliant analytics solution that respects user consent 🥳
Here's a quick recap of what we accomplished:
- Setting Up Tracking Utilities:
- Configured GTM for environment-based flexibility.
- Implemented reusable utilities for sending events, granting consent, and tracking user behavior.
- Adding GTM Components:
- Built a script loader and wrapper for cached consent management.
- Enabled dynamic route-based page tracking and event initialization.
- Integrating GTM into the Application:
- Added a global cookie consent banner with react-cookie-consent.
- Seamlessly incorporated GTM tracking into the app layout.
- Testing the Integration:
- Verified consent states and event triggers using Google Tag Assistant.
- Ensured compliance with GDPR/CCPA while maintaining robust analytics.
By implementing these steps, you've created a scalable solution that respects user consent while enabling powerful data collection for actionable insights.
Next Steps
Now that you've laid the foundation, here are some suggestions for further enhancement:
- Advanced Analytics Configuration: Add triggers for custom events like button clicks, video plays, or form submissions.
- Dynamic Consent Preferences: Allow users to modify their consent settings via a dedicated preferences center.
- Multi-Language Support: Localize your cookie banner to provide a consistent experience for global audiences.
- A/B Testing Integration: Incorporate tools like Google Optimize to conduct data-driven experiments.
- Performance Optimization: Monitor and optimize your implementation to minimize impact on page load speeds.
Expanding your integration with these features ensures you stay ahead in delivering value to users while maintaining compliance.
Partner with Aclarify for Your NextJS Success
Implementing GTM and Consent Mode is just the beginning. Scaling analytics while adhering to privacy regulations can be challenging, but that's where Aclarify can help. Our expert team specializes in building custom NextJS solutions tailored to your business needs.
Why Choose Aclarify?
- Proven Expertise: We bring years of experience in integrating analytics and compliance solutions with NextJS, ensuring a seamless implementation.
- Tailored Solutions: Every business is unique, and we deliver personalized solutions designed to meet your specific requirements.
- Ongoing Support: From deployment to optimization, we provide continuous support to ensure your system performs at its best.
Let's Build Something Exceptional Together
Imagine having an analytics system that not only respects user consent but also empowers your team with actionable insights. Picture a future where your website becomes a data-driven powerhouse while remaining fully compliant with global privacy standards.
At Aclarify, we make this vision a reality.
Partner with Aclarify for Your NextJS Integration Needs
Our team at Aclarify specializes in NextJS integrations with Google Tag Manager, Consent Mode, and more. Let us help you create a compliant, data-driven, and high-performing web experience tailored to your goals.