In Next.js, the @next/third-parties library makes it straightforward to hook up Google Tag Manager (GTM), keep your analytics in one place, and send custom events for important user actions to Google Analytics 4 (GA4), like tracking when someone clicks a “Subscribe to newsletter” button. That’s exactly the kind of event setup I’ll walk you through in this tutorial.

In this tutorial you will:
- Install GTM using @next/third-parties/google in a Next.js App Router project.
- Send a custom event (subscribe_newsletter) from your Next.js code with a page_location parameter.
- Configure GTM so that it forwards that event to GA4.
- Configure GA4 so you can see how many contact clicks you get per page.
This guide assumes:
- You already have a Next.js App Router project.
- You already have a GA4 property.
- You already created a GTM Web container (ID like GTM-XXXXXXX).

1. Install Google Tag Manager in your Next.js app
If you do not have the @next/third-parties package installed yet, add it first:
npm i @next/third-parties1.1 Add GTM to app/layout.tsx
Open app/layout.tsx (or app/layout.jsx) and import GoogleTagManager from @next/third-parties/google.
Here is an example layout:
import { GoogleTagManager } from "@next/third-parties/google";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<GoogleTagManager gtmId="GTM-XXXXXXX" />
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}
Replace GTM-XXXXXXX with your own container ID.
Now that GTM is wired into our Next.js app, we can move on to sending our first event.
If you do not plan to add custom events, you can skip ahead to step 3 and only follow step 3.1.
2. Send a custom event from Next.js with sendGTMEvent
Now that Google Tag Manager is wired into the layout, we can send a custom event whenever a user clicks a key CTA. For this example, we will track when someone clicks the “Subscribe” button in a newsletter signup section.
The flow:
- NewsletterCta renders the UI for the newsletter signup.
- SuscribeButton (the button component) sends a subscribe_newsletter event to GTM.
- The event includes a page_location parameter so you know where the subscription came from.

2.1 Build the NewsletterCta component
Create components/NewsletterCta.tsx and add the following:
import SuscribeButton from "./SuscribeButton";
const NewsletterCta = () => {
return (
<div className="mt-16 mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="rounded-3xl bg-gray-900 py-10 px-6 sm:py-16 sm:px-12 lg:flex lg:items-center lg:p-20">
<div className="lg:w-0 lg:flex-1">
<h2 className="text-3xl font-bold tracking-tight text-white">
Sign up for our newsletter
</h2>
<p className="mt-4 max-w-3xl text-lg text-gray-100">
Join many others and subscribe to get product updates, market
insights, tips & tricks to selling software, and more.
</p>
</div>
<div className="mt-12 sm:w-full sm:max-w-md lg:mt-0 lg:ml-8 lg:flex-1">
<form method="post" className="sm:flex space-y-2">
<label htmlFor="name" className="sr-only">
Name
</label>
<label htmlFor="email-address" className="sr-only">
Email address
</label>
<input
id="name"
type="name"
className="w-full rounded-md sm:mr-3 border border-white px-5 py-3 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-1 focus:ring-offset-gray-700"
placeholder="Your name"
/>
<input
id="email-address"
type="email"
className="w-full rounded-md border border-white px-5 py-3 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-1 focus:ring-offset-gray-700"
placeholder="Your email"
/>
<input type="checkbox" value="1" className="hidden" tabIndex={-1} />
<SuscribeButton />
</form>
<p className="mt-3 text-sm text-gray-100">
We care about the protection of your data. Read our{" "}
<a href="" className="font-medium text-white underline">
Privacy Policy.
</a>
</p>
</div>
</div>
</div>
);
};
export default NewsletterCta;
This is a standard newsletter block: name, email, a hidden field, and the SuscribeButton (taken from TailwindFlex) that will fire the GTM event.
2.2 Add the GTM event to the SuscribeButton
Create components/SuscribeButton.tsx and wire the GTM event there:
"use client";
import { sendGTMEvent } from "@next/third-parties/google";
import { usePathname } from "next/navigation";
const SuscribeButton = () => {
const path = usePathname();
return (
<button
onClick={() =>
sendGTMEvent({
event: "subscribe_newsletter",
page_location: path,
})
}
type="submit"
className="mt-3 flex w-full items-center justify-center rounded-md border border-transparent bg-gray-500 px-5 py-3 text-base font-medium text-white hover:bg-gray-400 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-700 sm:mt-0 sm:ml-3 sm:w-auto sm:flex-shrink-0"
>
Subscribe
</button>
);
};
export default SuscribeButton;
Now every time someone clicks the Subscribe button, GTM receives a subscribe_newsletter event with the page path attached.
2.3 Render the CTA on the homepage
In this example, the homepage imports and renders the NewsletterCta. It also links to the full tutorial and GTM docs.
import NewsletterCta from "@/components/NewsletterCta";
import Image from "next/image";
export default function Home() {
return (
<div className="flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black">
<main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-between bg-white py-32 px-16 dark:bg-black sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={100}
height={20}
priority
/>
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
<h1 className="max-w-xl text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
Google Tag Manager in Next.js 16.
</h1>
<p className="max-w-xl text-lg leading-8 text-zinc-600 dark:text-zinc-400">
This example shows how to install Google Tag Manager with
<code className="mx-1 rounded bg-zinc-100 px-1.5 py-0.5 text-sm dark:bg-zinc-900">
@next/third-parties/google
</code>
and send a custom event using{" "}
<code className="mx-1 rounded bg-zinc-100 px-1.5 py-0.5 text-sm dark:bg-zinc-900">
sendGTMEvent
</code>
. Use it as a starting point to wire your own CTAs to GA4.
</p>
</div>
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
{/* Full tutorial button – update href to your actual tutorial URL */}
<a
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-black px-5 text-white transition-colors hover:bg-zinc-800 dark:bg-zinc-50 dark:text-black dark:hover:bg-zinc-200 md:w-[190px]"
href="/gtm-nextjs-tutorial"
>
View full tutorial
</a>
<a
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 text-black transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:text-zinc-50 dark:hover:bg-[#1a1a1a] md:w-[190px]"
href="https://developers.google.com/tag-platform/tag-manager/web"
target="_blank"
rel="noopener noreferrer"
>
GTM Web docs
</a>
</div>
<NewsletterCta />
</main>
</div>
);
}
At this point:
- GTM is installed in
RootLayout. - The homepage renders
NewsletterCta. - Clicking the Subscribe button sends
subscribe_newsletter+page_locationto GTM.
3. Configure GTM to send the event to GA4
Now you need GTM to take the subscribe_newsletter event from the data layer and forward it to GA4, including the page_location parameter.
You will:
- Add a GA4 configuration tag.
- Create a data layer variable for
page_location. - Create a custom event trigger for
subscribe_newsletter. - Create a GA4 Event tag that uses that trigger and forwards
page_location.
3.1 Create a GA4 Configuration tag
In Google Tag Manager:
- Go to Tags → New.
- Name it:
GA4 – Config. - Click Tag Configuration and choose Google Analytics: GA4 Configuration.
- In Measurement ID, paste your GA4 stream ID (starts with
G-). - Under Triggering, select All Pages.
- Save.
This is what your screen should look like:

This tag boots GA4 on every page and is reused by your event tags.
If you are only setting up the tag and not tracking any events, you can skip the remaining steps.
3.2 Create a Data Layer variable for the page location
- Go to Variables → New.
- Name it:
DLV – page_location. - Click Variable Configuration and choose Data Layer Variable.
- In Data Layer Variable Name, enter
page_location. - Keep Data Layer Version as Version 2.
- Save.

This variable will pull the page_location value from each incoming event.
3.3 Create a Custom Event trigger for subscribe_newsletter
- Go to Triggers → New.
- Name it:
EV – subscribe_newsletter. - Click Trigger Configuration and choose Custom Event.
- In Event name, enter
subscribe_newsletter. - Under This trigger fires on, keep All Custom Events.
- Save.

This trigger will fire whenever your Next.js code sends event: "subscribe_newsletter"
3.4 Create the GA4 Event tag
- Go to Tags → New.
- Name it:
GA4 Event – subscribe_newsletter. - Click Tag Configuration and choose Google Analytics: GA4 Event.
- In Measurement ID, enter your Google Analytics Measurement ID.
- In Event Name, enter
subscribe_newsletter. - Under Event Parameters, click Add parameter:
- Parameter name:
page_location - Value:
{{DLV – page_location}}
- Parameter name:
- Under Triggering, select
EV – subscribe_newsletter. - Save.

Now, every time a user clicks the Subscribe button, GTM will send a GA4 event named subscribe_newsletter with a page_location parameter.
4. Test the setup with GTM Preview
Before publishing, verify everything with Tag Assistant. These steps are skippable; you can move to the 5th step if you don't want to test it.
- In GTM, click Preview.
- Enter your site URL (for example
https://localhost:3000or your deployed URL) and start the preview. - Your site opens in a new tab, and Tag Assistant opens in another.
- On your site, click the Subscribe button in the newsletter section.
- In Tag Assistant:
- In the left sidebar, look for an event called
subscribe_newsletter. - Click it.
- Under Tags, confirm that
GA4 Event – subscribe_newsletterfired. - Under Variables, check that
page_locationis set to the current route (for example/).
- In the left sidebar, look for an event called

If the tag did not fire:
- Confirm the event name in your code is exactly
subscribe_newsletter. - Confirm the Custom Event trigger also uses
subscribe_newsletter. - Make sure the GA4 event tag is using the correct trigger and configuration tag.
Once everything looks correct, you can publish.
4.1 Publish the GTM container
- In GTM, click Submit.
- Add a version name and description, for example:
Add subscribe_newsletter GA4 event. - Click Publish.
Your live site now sends subscribe_newsletter events through GTM to GA4.
5. Configure GA4 to use the event and parameter
GTM is now forwarding the event to GA4. Next you:
- Confirm GA4 is receiving
subscribe_newsletter. - Register
page_locationas a custom dimension. - Optionally mark
subscribe_newsletteras a key event (conversion).
5.1 Confirm in GA4 Realtime
- In GA4, go to Reports → Realtime overview.
- Open your site and click the Subscribe button a few times.
- In Realtime, look for Event count by Event name.
- You should see
subscribe_newsletterwith a growing count.

5.2 Register page_location as a custom dimension
- In GA4, go to Admin → Data display → Custom definitions → Custom dimensions.
- Click Create custom dimension.
- Fill in:
- Dimension name:
Newsletter subscribe page location(or similar). - Scope:
Event. - Event parameter:
page_location.
- Dimension name:
- Save.

From now on, new subscribe_newsletter events with page_location will store that value as a custom dimension.
5.3 Mark subscribe_newsletter as a key event (conversion)
If you want newsletter subscriptions to count as a conversion, you can mark this event as a key event for better reporting—but this step is optional and you can skip it if you do not need that level of tracking yet.
- In GA4, go to Admin → Data display → Events.
- Find
subscribe_newsletterin the events list. - Toggle the Mark as key event (star) column.
Future subscribe_newsletter events will be treated as key events.
If you can't find subscribe_newsletter in the events list, but you see it in the real-time overview, don't worry, it usually takes time for it to show up. You can try a couple of hours later.
6. Use the data in GA4 reports
Once there is some data, you can analyze it in GA4.
6.1 Events report
- Go to Reports → Engagement → Events.
- Filter or search for
subscribe_newsletter. - Review:
- Total event count.
- Key events (if marked).
- Engagement metrics around those events.
Conclusion
By combining @next/third-parties/google with GTM and GA4, you can track important user actions from your Next.js App Router project without cluttering your codebase with tracking logic.
Thank you for reading this tutorial. I first wrote a version for Next.js 14, but this time I wanted to go deeper and actually show how to set up a custom event as well. I kept things detailed and step by step so you are not stuck guessing between instructions. If you’d rather have a shorter, more to-the-point version, let me know.