티스토리 뷰

728x90

서론

서비스를 새로 만들 때마다 매번 GA를 적용하여 고객유입을 확인한다. 기존에 사용하던 프레임워크에 GA를 적용한 레퍼런스가 있으면 이 작업을 상당히 편하게 할 수 있다. NextJS에 GA를 적용하는 레퍼런스가 인터넷에 매우 많다. 다만, NextJS의 버전에 따라, JS인지 TS인지에 따라, 적용할 수 있는 코드에 차이가 있다. 내 기준에 맞게 GA 속성을 생성하고 NextJS에 적용하는 글을 작성한다.

 

My Condition

  • GA의 플랫폼 웹 적용
  • NextJS 14.0.4 버전. App Router 방식 사용. (13버전이라도 App Router 방식이면 가능할 것으로 추정)
  • TypeScript 사용
  • GA를 통해 페이지뷰 자동 적용
  • GA 이벤트 발생
  • 환경변수에 GA 측정ID 유무에 따라 Production 환경과 Development 환경을 구분함

 

 

GA  구글 애널리틱스 생성

1. 구글 애널리틱스( https://analytics.google.com/ ) => 관리자 => 만들기 => 속성

구글 애널리틱스 관리 화면

 

2. 속성만들기 내용 입력

구글 애널리틱스 속성 만들기

 

3. 비즈니스 세부정보 선택

구글 애널리틱스 비즈니스 세부정보

 

4. 비즈니스 목표 선택

구글 애널리틱스 비즈니스 목표 선택

 

5. 데이터 수집 시작. 플랫폼 [웹] 선택

구글 애널리틱스 플랫폼 선택

 

6. 내 웹사이트 URL 입력. 스트림 이름 입력.

구글 애널리틱스 데이터 스트림 설정

 

7. 웹스트림 세부정보 확인.

구글 애널리틱스 웹스트림 세부정보 및 설치안내

 

"G-"로 시작하는 측정ID를 획득하는 것이 목표입니다
ex) G-ABCDEFG1234

 

 

NextJS(TypeScript, AppRouter)에 GA 적용하기

NextJS 예시 Github에 Google Analytics를 적용하는 예시가 있다. 하지만, JavaScript로 되어 있다.

https://github.com/vercel/next.js/tree/canary/examples/with-google-analytics

 

터미널에서 gtag 타입 추가

npm install -D @types/gtag.js

 

 

.env 에 GA 측정ID를 Client 사이드에서 사용가능한 환경변수값으로 추가

NEXT_PUBLIC_GA_ID=G-ABCDEFG1234

 

 

/src/lib/gtag.ts 생성

import { usePathname } from "next/navigation";
import { useEffect, useRef } from "react";

export const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID;

// https://developers.google.com/analytics/devguides/collection/gtagjs/pages
export const pageView = (url: URL) => {
  window.gtag('config', GA_TRACKING_ID as string, {
    page_path: url,
  });
};

// https://developers.google.com/analytics/devguides/collection/gtagjs/events
export const event = (
  action: Gtag.EventNames,
  { event_category, event_label, value }: Gtag.EventParams,
) => {
  if (process.env.NODE_ENV === 'development') return true;
  window.gtag('event', action, {
    event_category,
    event_label,
    value,
  });
  return true;
};

export const useGtag = () => {
  const pathname = usePathname(); // Get current route

  // Save pathname on component mount into a REF
  const savedPathNameRef = useRef(pathname);

  useEffect(() => {
    if (process.env.NODE_ENV === 'development') return;

    const handleRouteChange = (url: URL) => {
      pageView(url);
    };

    if (savedPathNameRef.current !== pathname) {
      handleRouteChange(new URL(pathname, window.location.origin));
      // Update REF
      savedPathNameRef.current = pathname;
    }
  }, [pathname]);
};

 

 

/src/components/ga/google-analytics.tsx 생성

'use client'

import Script from 'next/script';
import * as gtag from '@/lib/gtag';

export default function GoogleAnalytics(){
    gtag.useGtag();
    return (
        <>
            {process.env.NODE_ENV !== 'development' && (
            <>
                {/* Global Site Tag (gtag.js) - Google Analytics */}
                <Script
                    strategy="afterInteractive"
                    src={`https://www.googletagmanager.com/gtag/js?id=${gtag.GA_TRACKING_ID}`}
                />
                <Script
                    id="gtag-init"
                    strategy="afterInteractive"
                    dangerouslySetInnerHTML={{
                        __html: `
                        window.dataLayer = window.dataLayer || [];
                        function gtag(){dataLayer.push(arguments);}
                        gtag('js', new Date());
                        gtag('config', '${gtag.GA_TRACKING_ID}', {
                            page_path: window.location.pathname,
                        });
                        `,
                }}
                />
            </>
            )} 
        </>
    )
}

 

 

/src/app/layout.tsx 에 GoogleAnalytics 추가

import type { Metadata } from 'next'
import './front/globals.css'
import GoogleAnalytics from './components/ga/google-analytics'

export const metadata: Metadata = {
  title: 'title',
  description: 'desc',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        {process.env.NEXT_PUBLIC_GA_ID ? (
          <GoogleAnalytics />
        ) : <div>GA환경변수값필요</div>}
        {children}
      </body>
    </html>
  )
}

 

=> 이렇게만 해둬도 사용자의 페이지 접근에 따른 페이지뷰를 측정해준다.

 

 

앱 내 동작에 따라 GA 이벤트 발생

'use client'

import React from "react";
import {Button} from "@nextui-org/react";
import * as gtag from '@/lib/gtag';

export default function App() {
  return (
    <Button 
      color="primary" 
      size="lg" 
      className="w-full" 
      onClick={(e) => {
        gtag.event("select_item", {
          event_category: "course_button_click",
          event_label: `제출`,
          value: 1
        })
        return true;
      }}
    >
      제출
    </Button> 
  );
}

 

gtag.event 함수를 통해 발생시키려는 event와 param 입력

 

 

 

마무리

부디 이 글로 인해 삽질 시간을 많이 아낄 수 있으시길... 오늘도 고생하십니다.

728x90