구글 애널리틱스 react / next 최적화

5o_hyun·2024년 10월 29일
0
post-thumbnail

구글 애널리틱스로 통계와 유입양을 보며 프로젝트 유지보수를 해야겠다고 생각했습니다.
근데 SPA방식인데 singlepage인데 어떻게 page넘어가는걸 구분할까? 하고 의문이 들었습니다.
방법은 router의 페이지 이동을 감지하는것입니다. 리액트는 useLocation 넥스트는 useRouter을 사용해 url을 가져와 페이지 변경시 호출을 하게 개발을 하였습니다.

1. 구글애널리틱스 계정생성후 태그추가

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>

2. GA 초기화 코드 모듈화

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 객체에 있다는 것을 알지 못하기 때문입니다.
이를 해결하기 위해 gtagwindow에 선언해주어야 합니다. 이를 위해 전역 타입 선언 파일을 사용하여 gtagwindow 객체에 추가할 수 있습니다.

해결 방법: 타입 선언 파일 생성

1. 전역 타입 선언 파일 작성

프로젝트 루트에 global.d.ts 파일을 생성하고 다음과 같이 gtag 함수를 window 객체에 추가합니다.

// 루트에 global.d.ts 생성

export {};

declare global {
  interface Window {
    gtag: (
      type: string,
      action: string,
      params: { [key: string]: unknown },
    ) => void;
  }
}

2. 타입 선언 파일 인식 확인

tsconfig.json에서 "include" 배열에 global.d.ts 파일 경로를 추가하여 TypeScript가 인식하도록 합니다.

// tsconfig.json

"include": ["global.d.ts", "**/*.ts", "**/*.tsx"]

이렇게하면 gtag 오류가 잡힌것을 확인할 수 있습니다.

3. 페이지 경로 변경 감지

React 방법

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 방법

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>
  );
}
profile
학생 점심 좀 차려
post-custom-banner

0개의 댓글