1. Intro
1. Google Analytics ?
Google Analytics는 구글 마케팅 플랫폼 브랜드 내의 플랫폼으로서, 웹사이트 트래픽을 추적하고 보고하는 구글이 제공하는 웹 Analytics 서비스입니다.
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/router의 router.events.on과 router.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의 데이터 레이어에 페이지 뷰 이벤트를 푸시합니다.
개발 환경이 아닌, 즉 프로덕션 환경에서만 Google Tag Manager 코드를 로드합니다. 이는 process.env.NEXT_PUBLIC_VERCEL_ENV 환경 변수를 확인하여 결정합니다. noscript 태그 내에는 GTM을 위한 iframe이 포함되어 있어, 자바스크립트가 비활성화된 경우에도 GTM이 작동할 수 있습니다. Script 컴포넌트를 사용하여 GTM 스크립트를 페이지에 동적으로 삽입합니다. 이 스크립트는 GTM 컨테이너 ID (GA_ID)를 사용하여 GTM 서버에 연결합니다.
2. utils/gtm.ts
// utils/gtm.ts
type WindowWithDataLayer = Window & {
dataLayer: Array<Record<string, any>>;
};
declare const window: WindowWithDataLayer;
export const pageview = (url: string) => {
if (typeof window.dataLayer !== 'undefined') {
window.dataLayer.push({
event: 'pageview',
page: url,
});
}
};
pageview 함수는 주어진 URL을 GTM의 데이터 레이어에 푸시합니다. 이 함수는 window.dataLayer 배열에 pageview 이벤트와 함께 페이지 URL을 추가합니다. 이를 통해 GTM은 사용자가 방문한 페이지를 추적할 수 있습니다.
최신 버전
@next/third-parties/google의 GoogleAnaytics컴포넌트를 사용하면 손쉽게 추가할 수 있다.
import { GoogleAnalytics } from '@next/third-parties/google'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
<GoogleAnalytics gaId="G-XYZ" />
</html>
)
}