在 GTM 中配置 gtag 之前加载数据层变量

问题描述 投票:0回答:1

我有一个 NextJS 应用程序,它获取页面的 URL,使用实用函数将值设置为

page_category
content_category
的 dataLayer 键值对,这些值在页面上设置为添加为自定义维度值(或者在 gtag 情况下,事件配置)应附加到每个页面视图。

我遇到的问题是,

dataLayer.push()
发生在配置gtag并发送信号之后,这意味着页面浏览量永远不会包含来自dataLayer的值。

我很好奇确保在 gtag 触发之前加载数据层的最佳行动计划是什么。我相信我的 dataLayer 值设置代码是客户端,这可能加载得太晚而无法加载 gtag。也许我需要将其移至服务器端?

这是我的代码:

layout.tsx(使用 GTM 容器标签和组件导入在服务器端加载):

import Script from 'next/script';
import React from 'react';
import Analytics from '../components/Global/Analytics';

const GTM_ID = process.env.GTM_MEASUREMENT_ID;

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang='en'>
      <Script id='google-tag-manager' strategy='afterInteractive'>
        {`
        (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','${GTM_ID}');
        `}
      </Script>

      {/* Load the dataLayer.push() array */}
      <Script id='data-layer-page-scope' strategy='afterInteractive'>
        {`
          (function(w,d,s,l,i){
            w[l]=w[l]||[];
            w[l].push({
              'page': window.location.pathname,
              'content_category': 'default',
              'page_category': 'default'
            });
          })(window,document,'script','dataLayer','${GTM_ID}');
        `}
      </Script>
      <body className={`${inter.variable} ${gelasio.variable}`}>
        <noscript
          dangerouslySetInnerHTML={{
            __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=${GTM_ID}" height="0" width="0" style="display: none; visibility: hidden;"></iframe>`,
          }}
        />
        <Analytics />
        <main>
          {children}
        </main>
      </body>
    </html>
  );
}

Analytics.tsx(客户端辅助函数,用于将 URL 清理为传递到 gtm.tsx 中的 dataLayer 的 content_category 和 page_category 值

'use client';
import { usePathname, useSearchParams } from 'next/navigation';
import { useEffect } from 'react';
import { pageview } from '../../libs/gtm';

export default function Analytics() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  var content = '';
  var page = '';

  // Mapping for "page_category"
  function formatString(inputString: string): string {
    // Extract content between furthest right slashes
    const match = inputString.match(/\/([^/]+)\/$/);

    if (match) {
      // Extract the matched content
      const content = match[1];
      // Check if the trimmed string contains a hyphen
      if (content.includes('-')) {
        // Split the string by "-"
        const words = content.split('-');
        // Capitalize the first letter of each word and join them with a space
        const formattedString = words
          .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
          .join(' ');
        return formattedString;
      } else {
        // If there is no hyphen, simply capitalize the first letter
        return content.charAt(0).toUpperCase() + content.slice(1);
      }
    }

    // Return the input string if no match is found
    return inputString;
  }

  // Mapping for "content_category"
  if (pathname == '/') {
    page = 'Homepage';
    content = 'Homepage';
  } else if (pathname.includes('/tag')) {
    page = 'Tag';
    content = formatString(pathname);
  } else if (pathname.includes('/about')) {
    page = 'About';
    content = 'Connor Phillips';
  } else if (pathname.includes('/page')) {
    page = 'Page';
    content = formatString(pathname);
  } else if (pathname.includes('/portfolio')) {
    page = 'Portfolio';
    content = formatString(pathname);
  } else {
    page = 'Post';
    content = formatString(pathname);
  }

  useEffect(() => {
    if (pathname) {
      return pageview(pathname, content, page);
    }
  }, [pathname, searchParams, content, page]);

  if (process.env.NEXT_PUBLIC_VERCEL_ENV !== 'production') {
    return null;
  }
}

gtm.tsx(设置dataLayer的地方):

type WindowWithDataLayer = Window & {
  dataLayer: Record<string, any>[];
};

declare const window: WindowWithDataLayer;

export const GTM_ID = process.env.GTM_MEASUREMENT_ID;

export const pageview = (url: string, content: string, page: string) => {
  if (typeof window.dataLayer !== 'undefined') {
    console.log(`pageview: ${url} , ${content}, ${page}`);
    window.dataLayer.push({
      page: url,
      content_category: content,
      page_category: page,
    });
  }
};
reactjs next.js google-tag-manager gtag.js
1个回答
0
投票

看起来您的

page_view
活动随着 Gtag 加载而火爆。

可以将其配置为不自动跟踪

page_view

并通过添加事件和值来修改数据层

这是例子:

<Script id='data-layer-page-scope' strategy='afterInteractive'>
        {`
          (function(w,d,s,l,i){
            w[l]=w[l]||[];
            w[l].push({
              'event': "custom_page_view",
              'page': window.location.pathname,
              'content_category': 'default',
              'page_category': 'default'
            });
          })(window,document,'script','dataLayer','${GTM_ID}');
        `}
</Script>

因此您可以创建一个

custom event trigger
设置为
custom_page_view
然后使用
page_view
事件以及您需要的事件参数来触发 GA4 事件代码。

© www.soinside.com 2019 - 2024. All rights reserved.