remix-run / remix

Build Better Websites. Create modern, resilient user experiences with web fundamentals.

Home Page:https://remix.run

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

remix hydration error when using gtag

pullmann4rent opened this issue · 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>
commented

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.