remix icon indicating copy to clipboard operation
remix copied to clipboard

remix hydration error when using gtag

Open pullmann4rent opened this issue 1 year ago • 2 comments

Reproduction

Root

import * as gtag from "~/utils/gtag";

export default function App() {
  const { showBanner, gaTrackingId } = useLoaderData<typeof loader>();

  const location = useLocation();

  useEffect(() => {
    if (gaTrackingId?.length) {
      gtag.pageview(location.pathname, gaTrackingId);
    }
  }, [location, gaTrackingId]);


  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width,initial-scale=1" />
        <script async src={`https://www.googletagmanager.com/gtag/js?id=${gaTrackingId}`}></script>
     
        <script async dangerouslySetInnerHTML={{ __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());

            gtag('config', '${gaTrackingId}');
              `
          }} />

      <Suspense fallback={null}>
        <script async dangerouslySetInnerHTML={{ __html: `
        (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
        })(window,document,'script','dataLayer','xxxx');
                      `
                  }} />
        </Suspense>


        <Meta />
        <Links />
        <ExternalScripts />
 
     
      </head>
      <body>
      <>
      <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=XXXX"
height="0" width="0" style={{display: 'none',visibility:'hidden'}}></iframe></noscript>

        <Whatsapp />
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
      </body>
    </html>
  );
}

export async function loader({ request }: LoaderArgs) {
  const cookieHeader = request.headers.get("Cookie");
  const cookie = await userPrefs.parse(cookieHeader);
  return json({ showBanner: cookie ?? null, gaTrackingId: 'xxx' });
}

gtag util

declare global {
  interface Window {
    gtag: (
      option: string,
      gaTrackingId: string,
      options: Record<string, unknown>,
    ) => void;
  }
}

/**
 * @example
 * https://developers.google.com/analytics/devguides/collection/gtagjs/pages
 */
export const pageview = (url: string, trackingId: string) => {
  if (!window.gtag) {
    console.warn(
      "window.gtag is not defined. This could mean your google analytics script has not loaded on the page yet.",
    );
    return;
  }
  window.gtag("config", trackingId, {
    page_path: url,
  });
};

/**
 * @example
 * https://developers.google.com/analytics/devguides/collection/gtagjs/events
 */
export const event = ({
  action,
  category,
  label,
  value,
}: Record<string, string>) => {
  if (!window.gtag) {
    console.warn(
      "window.gtag is not defined. This could mean your google analytics script has not loaded on the page yet.",
    );
    return;
  }
  window.gtag("event", action, {
    event_category: category,
    event_label: label,
    value: value,
  });
};

System Info

System:
    OS: Windows 10 10.0.19045
    CPU: (4) x64 AMD FX(tm)-4170 Quad-Core Processor
    Memory: 1.75 GB / 7.98 GB
  Binaries:
    Node: 18.18.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.21 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 10.2.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (123.0.2420.97)
    Internet Explorer: 11.0.19041.3636
  npmPackages:
    @remix-run/css-bundle: ^2.0.1 => 2.7.1
    @remix-run/dev: ^1.15.0 => 1.19.3
    @remix-run/eslint-config: ^1.15.0 => 1.19.3
    @remix-run/express: ^1.15.0 => 1.19.3
    @remix-run/node: ^1.15.0 => 1.19.3
    @remix-run/react: ^1.15.0 => 1.19.3
    @remix-run/serve: ^1.15.0 => 1.19.3
    @remix-run/vercel: ^1.15.0 => 1.19.3

Used Package Manager

npm

Expected Behavior

That I got no hydration err

Actual Behavior

Google analatiycs works but not google tag manager. I got hydration error when I use this code:

      <Suspense fallback={null}>
        <script async dangerouslySetInnerHTML={{ __html: `
        (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
        })(window,document,'script','dataLayer','xxxx');
                      `
                  }} />
        </Suspense>

pullmann4rent avatar Apr 15 '24 01:04 pullmann4rent

To fix this, we recommend the using the ClientOnly component in the remix-utils community package. An example of its usage can be found in the examples repository.

suhaotian avatar Apr 26 '24 11:04 suhaotian

To fix this, we recommend the using the ClientOnly component

Can you please show an example actually uses GTag scripts? Because using it with ClientOnly prevents firing of that script. So It renders but does not sends any data to google. Does not works.

Or any other tracking scripts. Meta(Facebook) Events, GTag, Ms Clarity.

emirefek avatar Jun 17 '24 08:06 emirefek