1. Intro

1. Google Analytics ?

Google Analytics는 구글 마케팅 플랫폼 브랜드 내의 플랫폼으로서, 웹사이트 트래픽을 추적하고 보고하는 구글이 제공하는 웹 Analytics 서비스입니다.

Screenshot 2023-09-12 at 1.49.29 PM.png

Google Anaytlics(이하 GA)는 위와 같이 이벤트 수, 사용자 수 등 다양한 수치들을 통계내어 데이터를 제공합니다.

2. Next.js 13 이전, Page 라우팅 방식에서 GA를 심는 방법

Next.js 13 이전에는 next/router를 사용할 수 있었습니다.

// app.tsx
import { useRouter } from 'next/router';
import { pageview } from '@utils/gtag';
useEffect(() => {
  const handleRouteChange = (url) => {
    pageview(url);
  };
	const router = useRouter();

  const handleRouteChangeEnd = () => setLoading(false);

  router.events.on('routeChangeStart', handleRouteChange);
  router.events.on('routeChangeComplete', handleRouteChange);
  router.events.on('routeChangeComplete', handleRouteChangeEnd);
  router.events.on('hashChangeComplete', handleRouteChange);
  router.events.on('routeChangeError', handleRouteChangeEnd);

  return () => {
    router.events.off('routeChangeStart', handleRouteChange);
    router.events.off('routeChangeComplete', handleRouteChange);
    router.events.off('routeChangeComplete', handleRouteChangeEnd);
    router.events.off('hashChangeComplete', handleRouteChange);
    router.events.off('routeChangeError', handleRouteChangeEnd);
  };
}, [router.events]);
// gtag.js
import { CONFIG } from '@config';
export const GA_TRACKING_ID = CONFIG.GOOGLE_TAG;

export const pageview = (url) => {
  window.gtag('config', GA_TRACKING_ID, {
    page_path: url,
  });
};

export const event = ({ action, category, label, value }) => {
  window.gtag('event', action, {
    event_category: category,
    event_label: label,
    value: value,
  });
};

위와 같이 next/routerrouter.events.onrouter.events.off를 이용하여 페이지를 이동할 때, gtag를 실행합니다.

하지만 Next.js 13 App router에서는 next/router가 deprecated되어 사용하지 못하고, next/navigation을 사용해야 합니다. 그런데 next/navigation의 useRouter()에는 events가 존재하지 않습니다.

2. 그렇다면 App router에서는?

모든 페이지에서 가장 먼저 실행이 되는 layout컴포넌트입니다.

// src/app/layout.tsx
export default function layout({children}){
	<html>
		<Analytics />
		{/* .. */}
	</html>
}

layout.tsx에 Analytics 컴포넌트를 심습니다. 이 Analytics컴포넌트에 대해 알아보겠습니다.

1. Analytics.tsx

// src/components/Analytics.tsx
export default function Analytics() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  useEffect(() => {
    if (pathname) {
      pageview(pathname);
    }
  }, [pathname, searchParams]);

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

  return (
    <>
      <noscript>
        <iframe
          src={`https://www.googletagmanager.com/ns.html?id=${GA_ID}`}
          height="0"
          width="0"
          style={{ display: 'none', visibility: 'hidden' }}
        />
      </noscript>
      <Script
        id="gtm-script"
        strategy="afterInteractive"
        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', '${GA_ID}');
  `,
        }}
      />
    </>
  );
}

가장 먼저, **usePathname**과 useSearchParams 훅을 사용하여 현재 URL 경로와 검색 파라미터를 가져옵니다. useEffect 훅을 사용하여 경로나 검색 파라미터가 변경될 때마다 pageview 함수를 호출합니다. 이 함수는 GTM의 데이터 레이어에 페이지 뷰 이벤트를 푸시합니다.