구글 애널리틱스 Google Analytics는 웹 응용프로그램의 사용 데이터를 수집에 많이 사용됩니다.
웹사이트 이용에 대한 추적 데이터를 기반으로 무엇을 어떻게 … 가 시작될 수 있습니다.
구글 애널리틱스에서 기본적으로 제공하는 코드는 웹 응용프로그램 특정 페이지에 요청을 보내면 응답하는 페이지에 코드를 추가해서 처리가 가능합니다.
그런데, 싱글 페이지 응용프로그램이라면 어떻게 클라이언트 경로 이동을 추적할 수 있을지에 대한 내용을 간략하게 작성했습니다.
구글 애널리틱스 속성 추가
구글 애널리틱스에 추적할 웹 응용프로그램에 대한 속성을 추가합니다.
추적 속성을 추가하면 범용 사이트에서 사용가능한 추적코드를 얻을 수 있습니다.
추적코드
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXX-X"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-XXXXXXXX-X');
</script>
범용 사이트 태그(gtag.js)에 대한 설명에 의하면, 위 코드를 추적할 모든 웹페이지의 <head>
에 첫번째 항목으로 붙여넣으면 됩니다.
그런데, SPA 의 경우 실제 페이지는 하나만 존재합니다.
클라이언트 코드에서 경로를 변경한 경우에도 추적코드를 실행해야 구글 애널리틱스에서 유효한 통계자료를 얻을 수 있습니다.
측정: gtag.js
측정 관련 API 는 Google Analytics Measurement gtag.js 페이지에서 찾을 수 있습니다.
클라이언트 측 경로 탐색시 경로 이동 추적을 위한 기능 확인은 Pageviews 관련 API 에서 찾을 수 있습니다.
config 명령으로 경로 탐색에 대한 추적이 가능합니다.
gtag('config', 'GA_MEASUREMENT_ID', { /* pageview parameters */});
Pageview parameters 의 정의는 아래와 같습니다.
interface PageviewParameters {
page_title?: string;
page_location?: string;
page_path?: string;
}
예제
공통
예를 들어 https://blog-service.bbon.me/users/@bbonkr/posts/hello-world 페이지로 이동하면 페이지가 로드된 후 아래 코드가 실행되면 되겠습니다.
gtag('config', 'UA-XXXXXXXX-X', {
page_title: 'Hello world',
page_location: 'https://blog-service.bbon.me/users/@bbonkr/posts/hello-world'
page_path: '/users/@bbonkr/posts/hello-world'
});
페이지 제목은 window.document.title
속성으로 찾을 수 있습니다.
페이지 전체 경로는 window.location.href
속성으로 찾을 수 있습니다.
페이지 경로는 window.location.pathname
속성으로 찾을 수 있습니다.
next.js + React 로 작성된 웹 응용프로그램
편리한 SSR Server-side Rendering , 편리한 클라이언트 경로 처리 등의 이유로 next.js 와 React 로 작성된 웹 응용프로그램의 경우 아래와 같이 처리할 수 있습니다.
_document 를 재작성해서 _gtag.js 파일을 포함하도록 코드를 작성합니다.
ga.ts
파일의 내용
export const gaTraceId: string = 'UA-XXXXXXXX-X';
_document.tsx
파일의 내용
import { gaTraceId } from './ga'
class MyDocument extends Document<IMyDocumentProps> {
// 생략
addGoogleAnalyticsScript(){
return {
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gaTraceId}');
`,
};
}
// 생략
render() {
const gaTraceId = 'UA-XXXXXXXX-X'
return (
<html lang='ko'>
<Head>
{/* ... */}
</Head>
<body>
<Main />
<NextScript />
<script async src={`https://www.googletagmanager.com/gtag/js?id=${gaTraceId}`}></script>
<script
dangerouslySetInnerHTML={this.addGoogleAnalyticsScript()}
/>
</body>
</html>
);
}
}
모든 페이지에 포함되는 컴포넌트를 작성합니다.
import React, {
FunctionComponent,
useEffect,
} from 'react';
import Router from 'next/router';
import { gaTraceId } from './ga'
export interface AppLayourProps {
children: React.ReactNode;
};
export const AppLayout: FunctionComponent<AppLayoutProps> = ({children}) => {
useEffect(() => {
const handleRouteChangeComplete = (url) => {
if(typeof window === 'object'){
const { title } = window.document;
const { href, pathname } = window.location;
window.gtag('config', gaTraceId, {
page_title: title,
page_location: href,
page_path: pathname,
});
}
};
Router.events.on('routeChangeComplete', handleRouteChangeComplete);
return () => {
Router.events.off('routeChangeComplete', handleRouteChangeComplete);
};
}, [])
return (
<div>
{children}
</div>
);
};
gtag 함수를 위한 정의파일 작성
@types/global.d.ts
파일의 내용
export declare global {
interface PageViewParameter {
page_title: string;
page_location: string;
page_path: string;
}
interface Window {
gtag: (action: string, gaId: string, parameter: PageViewParameter) => void;
}
}
@types/gtag.js 패키지를 설치해서 gtag 함수 정의를 참조할 수 있습니다.
위와 같이 컴포넌트로 분리하면 모든 페이지 컴포넌트에서 Pageviews 측정을 위한 코드를 추가하지 않고 처리할 수 있습니다.
next.js 의 경로 처리 이벤트는 https://github.com/zeit/next.js/#router-events 페이지에서 확인할 수 있습니다.
useEffect
또는 componentDidMount
함수에서 window 객체의 속성값을 참조할 때, 문제가 있는 경우 setTimeout 함수로 조금 후에 실행되도록 조정할 수 있습니다.
GitHub
GitHub: bbonkr/sample-next.js-google-analytics 저장소에서 코드를 확인하세요.
이 사이트는 광고를 포함하고 있습니다.
광고로 발생한 수익금은 서버 유지 관리에 사용되고 있습니다.This site contains advertisements.
Revenue generated by the ad servers are being used for maintenance.