구글 애널리틱스로 통계와 유입양을 보며 프로젝트 유지보수를 해야겠다고 생각했습니다.
근데 SPA방식인데 singlepage인데 어떻게 page넘어가는걸 구분할까? 하고 의문이 들었습니다.
방법은 router의 페이지 이동을 감지하는것입니다. 리액트는 useLocation
넥스트는 useRouter
을 사용해 url을 가져와 페이지 변경시 호출을 하게 개발을 하였습니다.
head에 script추가
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9BZTF7BZ9S"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-9BZTF7BZ9S');
</script>
GA 초기화 코드를 별도의 유틸리티 함수로 만들어 불필요한 로딩을 방지할 수 있습니다.
// lib/utils/ga.ts 생성
export const GA_TRACKING_ID = 'YOUR_GA_TRACKING_ID';
// 페이지 조회 함수 타입 정의
export const pageview = (url: string) => {
window.gtag('config', GA_TRACKING_ID, {
page_path: url,
});
};
interface Event {
action: string;
category: string;
label: string;
value?: number;
}
// 이벤트 함수 타입 정의
export const event = ({ action, category, label, value }: Event) => {
window.gtag('event', action, {
event_category: category,
event_label: label,
value,
});
};
그런데 이때, 타입스크립트를 사용하시는 분들이라면 window에 gtag값이 없다 라는 에러를 보실 수 있으실겁니다.
window.gtag
가 TypeScript에서 오류를 발생시키는 이유는 TypeScript가 gtag
함수가 window
객체에 있다는 것을 알지 못하기 때문입니다.
이를 해결하기 위해 gtag
를 window
에 선언해주어야 합니다. 이를 위해 전역 타입 선언 파일을 사용하여 gtag
를 window
객체에 추가할 수 있습니다.
프로젝트 루트에 global.d.ts
파일을 생성하고 다음과 같이 gtag
함수를 window
객체에 추가합니다.
// 루트에 global.d.ts 생성
export {};
declare global {
interface Window {
gtag: (
type: string,
action: string,
params: { [key: string]: unknown },
) => void;
}
}
tsconfig.json
에서 "include" 배열에 global.d.ts
파일 경로를 추가하여 TypeScript가 인식하도록 합니다.
// tsconfig.json
"include": ["global.d.ts", "**/*.ts", "**/*.tsx"]
이렇게하면 gtag
오류가 잡힌것을 확인할 수 있습니다.
nextjs에 비해 react는 간단합니다.
App.tsx
에서 페이지가 변경될 때마다 sendPageview
를 호출합니다.
function App() {
useEffect(() => {
const sendPageview = () => {
ga.pageview(window.location.pathname + window.location.search);
};
// 초기 페이지 로드 시 한 번 실행
sendPageview();
// 경로 변경마다 페이지뷰 전송
const unsubscribe = router.subscribe((state) => {
if (state.location) {
sendPageview();
}
});
return (
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
<ToastContainer />
<ReactQueryDevtools />
</QueryClientProvider>
);
}
Next.js의 App.tsx
에서 Router
이벤트를 사용해 페이지 이동마다 pageview
함수를 호출하도록 설정합니다.
function App() {
const router = useRouter();
useEffect(() => {
const handleRouteChange = (url: string) => {
ga.pageview(url);
};
router.events.on('routeChangeComplete', handleRouteChange);
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
};
}, [router.events]);
return (
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
<ToastContainer />
<ReactQueryDevtools />
</QueryClientProvider>
);
}