vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.23k stars 26.77k forks source link

Google Tag Manager event "History change" is no longer fired in Next.js 14.0.3 #58924

Open manuelseisl opened 10 months ago

manuelseisl commented 10 months ago

Link to the code that reproduces this issue

https://github.com/manuelseisl/next-js-demo

To Reproduce

  1. Change GTM ID in layout.jsx
  2. Start application
  3. Go to GTM preview mode
  4. Navigate between pages

Current vs. Expected behavior

The Google Tag Manager event "History change" is no longer fired in Next.js 14.0.3.

Verify canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.1.0: Mon Oct  9 21:28:45 PDT 2023; root:xnu-10002.41.9~6/RELEASE_ARM64_T6020
Binaries:
  Node: 20.10.0
  npm: 10.2.3
  Yarn: 1.22.19
  pnpm: 8.8.0
Relevant Packages:
  next: 14.0.3
  eslint-config-next: 14.0.3
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

App Router, Routing (next/router, next/navigation, next/link)

Additional context

I tested my reproduction against different versions and canary releases, and the first one that introduced the bug was “14.0.3”, when switching back to “14.0.2” it works.

vKongv commented 10 months ago

I thought this was the default behavior when I first using Nextjs with 14.0.3. I added a template.tsx to trigger GTM track event manually :/

cduff commented 10 months ago

I just checked and this was breaking Google Tag Manager / Analytics for me. Rolling back to 14.0.2 fixes for now.

Bart3kL commented 10 months ago

@cduff @vKongv @manuelseisl Are you having trouble keeping track of all the pages? I use import { GoogleTagManager } from "@next/third-parties/google"; and for the page to appear in Google Analytics panel, I have to refresh page manually to see that someone has visited some page

cduff commented 10 months ago

@cduff @vKongv @manuelseisl Are you having trouble keeping track of all the pages? I use import { GoogleTagManager } from "@next/third-parties/google"; and for the page to appear in Google Analytics panel, I have to refresh page manually to see that someone has visited some page

@Bart3kL Do you have it set up to trigger on History Change? This is required due to hydration.

Bart3kL commented 10 months ago

@cduff Do you have it done somewhere and can you show it?

vKongv commented 10 months ago

@cduff @vKongv @manuelseisl Are you having trouble keeping track of all the pages? I use import { GoogleTagManager } from "@next/third-parties/google"; and for the page to appear in Google Analytics panel, I have to refresh page manually to see that someone has visited some page

@Bart3kL Do you have it set up to trigger on History Change? This is required due to hydration.

I did it in app/template.tsx like the doc said, thought it was a default behavior to do this until I see this issue

'use client';
import { useEffect } from 'react';
import { sendGTMEvent } from '@next/third-parties/google';

export default function Template({ children }: { children: React.ReactNode }) {
  const isProd = process.env.NODE_ENV === 'production';

  useEffect(() => {
    isProd && process.env.NEXT_PUBLIC_GTM_ID && sendGTMEvent({ event: 'page_view' });
  }, [isProd]);

  return <div>{children}</div>;
}
philwolstenholme commented 10 months ago

The GTM history change event should 'just work', but recently Next patched history pushState and replaceState, presumably causing this bug.

cduff commented 10 months ago

@cduff Do you have it done somewhere and can you show it?

@Bart3kL I just have GTM set up in the root layout like: https://nextjs.org/docs/app/building-your-application/optimizing/third-party-libraries#google-tag-manager

And the tag is configured like this:

image

philwolstenholme commented 9 months ago

This issue should be resolved by https://github.com/vercel/next.js/commit/8ff1368fdbba5f8425ce9913a2f13dc6ce1dd994, I think. It'll be in the next non-canary release which I am guessing will be some time in the next week or two.

cduff commented 9 months ago

Fixed in 14.0.4 for me.

oalexdoda commented 9 months ago

Fixed on 14.0.4 but that version (and 14.0.5-canary) has a bug where all imports break.

And because of the complexity of the setup there's no way to add a minimal repro, so can't open an issue:

Gonna be stuck on 14.0.3 for a while or revert to 14.0.2.

benyaminl commented 6 months ago

@vKongv Hello, I tried yours and use different variable for the useEffect, but seems it won't re-render between pages using Component, is there other thing that I need to set in order to re-render the Template.tsx on /app/template.tsx?

I only able to fire it using usePathName(), as the Template.tsx seems not rerendered or recalled

eg like in https://medium.com/@codingbeautytutorials/nextjs-detect-route-change-bb8e6c316d1

'use client';
import { useEffect } from 'react';
import { sendGTMEvent } from '@next/third-parties/google';
import { usePathname } from 'next/navigation';

export default function Template({ children }: { children: React.ReactNode }) {
  const isProd = usePathname();

  useEffect(() => {
    sendGTMEvent({ event: 'page_view', what: "huh" });
    console.log("Firing the page view", new Date(), window.location.pathname);
  }, [isProd]);

  return <>{children}</>;
}

I do look into the documentation that the state always not same each time we change to other page, but in this case seems it isn't, or I'm looking or interpret the docs and your answer wrongly?

Thank you

dominicfallows commented 6 months ago

I'm on 14.1.4 and noticed this still isn't working - that is I get no History Change trigger in GTM.

BTW, by following a similar app/template.tsx as discussed in this issue, I was able to trigger the GTM/GoogleTag/GA4 automatic collection of page data

app/template.tsx

"use client";
import { useEffect } from "react";
import { usePathname } from "next/navigation";

export default function Template({ children }: { children: React.ReactNode }) {
  const pathname = usePathname();

  useEffect(() => {
    if (window?.dataLayer) {
      if (process.env.NODE_ENV === "development") {
        console.log(`page_view`, window.location.href);
      }

      window.dataLayer.push({
        event: "page_view",
      });
    }
  }, [pathname]);

  return <>{children}</>;
}

GTM

Screenshot 2024-03-28 at 15 22 38
catlan commented 6 months ago

I'm on 14.1.4 and noticed this still isn't working - that is I get no History Change trigger in GTM

Haven't retested with the latest version, but had to move the GoogleTagManager into head at some point for History Change trigger to work.

      <head>
        <GoogleTagManager gtmId="GTM-XXXXXXXX" />
      </head>
HarveyPeachey commented 3 months ago

14.2.3 doesn't seem to be working automatically for page views, even when following the docs.

Borgo99 commented 3 months ago

14.2.4 it's still not working