sumini dev

posts

Nextjs 프로젝트에 Google Analytics 깔끔하게 붙이기

profile-image

Choi su min

유저들의 데이터를 수집 및 분석하기 위해서 구글 애널리틱스 도입은 필수죠.

next-ga 라이브러리는 글로벌 getInitialProps 적용으로 automiatic static optimization을 opt out 하므로 사용하지 않고, react-ga를 사용하겠습니다.

0. 가입, key 발급

구글 애널리틱스에 접속해 서비스를 생성하고, ID를 발급 받습니다.

vercel을 통해 배포중인 경우 다음 명령어를 이용해 secret을 추가해줍니다.

$ vercel secrets add <service-name>-ga-app-id <ga-app-id>

1. 설치

$ yarn add react-ga
$ yarn add --dev debug

2. analytics modules

src/lib/ga/analytics 경로에 다음 파일들을 추가합니다.

import ReactGA from 'react-ga';

// server / client 구분을 위한 변수
const IS_BROWSER = typeof window !== 'undefined';

export function init(code) {
  // client-side에서만, GA가 initialize되지 않았을 때만 init
  if (IS_BROWSER && !window.GA_INITIALIZED && code) {
    ReactGA.initialize(code);
  }
}

export function pageview() {
  ReactGA.set({ page: window.location.pathname });
  ReactGA.pageview(window.location.pathname);
}

export function event(category = '', action = '') {
  if (category && action) {
    ReactGA.event({ category, action });
  }
}

export function exception(description = '', fatal = false) {
  if (description) {
    ReactGA.exception({ description, fatal });
  }
}
src/lib/ga/analytics/prod.js
// development 환경일 땐 logging만 합니다.
import debug from 'debug';

const log = debug('analytics');

export function init(code) {
  log(`Analytics init triggered for ${code}`);
}

export function pageview() {
  log(`Pageview triggered for ${window.location.pathname}`);
}

export function event(category = '', action = '') {
  log(`Event for category ${category} and action ${action} triggered`);
}

export function exception(description = '', fatal = false) {
  log(
    `${fatal ? 'Fatal exception' : 'Exception'} with description ${description}`
  );
}
src/lib/ga/analytics/dev.js

3. ga modules

src/lib/ga/index.js 파일을 추가합니다. 내용은 다음과 같습니다.

import * as prodLytics from './analytics/prod';
import * as devLytics from './analytics/dev';

const isLocal = () => {
  return location.hostname === 'localhost';
};

const isDev = () => {
  return process.env.NODE_ENV !== 'production';
};

const initGA = (code, Router) => {
  // local이거나 development 환경일 땐 ga를 실행하지 않습니다.
  const shouldNotTrack = isLocal() || isDev();
  // production or dev analytics
  const analytics = shouldNotTrack ? devLytics : prodLytics;

  // init
  analytics.init(code);
  // log page
  analytics.pageview();

  // previouseCallback을 저장합니다.
  const previousCallback = Router.onRouteChangeComplete;
  // Router.onRouteChangeComplete는 라우팅 주소 변경시 트래킹을 하기 위해 필요합니다.
  Router.onRouteChangeComplete = () => {
    // previouseCallback function이 정의되어 있었으면 실행시켜 줍니다.
    if (typeof previousCallback === 'function') {
      previousCallback();
    }
    // log page
    analytics.pageview();
  };
};

export default initGA;
src/lib/ga/index.js

4. 적용

pages/_app.js에 다음 코드를 추가합니다.

...
import Router from 'next/router';
...

import initGA from '../src/lib/ga';

...

class PickkApp extends App {
  componentDidMount() {
    initGA(process.env.GA_APP_ID, Router);
  }
  ...
pages/_app.js

NEXTJS4개 더보기

모든 글 보기

이전 글

Nextjs+Typescript 프로젝트에 styled-components 추가하기

다음 글

초보 리액트 개발자를 위한 팁 13가지

profile-image

Choi su min

Sogang Univ.

AWESOME.DEV Lead

Anyang, Gyeong-gi, Republic of Korea

github-iconmail-iconrss-icon