Google Analystic 등 웹(앱) 서비스를 이용하는 유저의 행동을 분석하는 마케팅 툴을 팀 프로젝트에 이식하게 되었다. 이중 내가 당담했던 툴들을 Google Analytics와 Google Adsence, 네이버 프리미엄 로그 분석이었다.
이 중 Google의 마케팅 툴을 이식하는 방법에 대해 포스팅을 진행하려 한다.
Google Analytics
구글 에널리스틱스는 웹(앱)에 대한 방문자의 데이터를 수집해서 분석함으로써 온라인 비즈니스의 성과를 측정하고 개선하는데 사용하는 로그분석 툴이다.
React 프로젝트에서 GA를 이식할때 많이들 react-ga
라이브러리를 사용하고는 한다. 그러나, GA가 업그레이드 되면서 이전 GA의 베이스가 되었던 유니버셜 에널리스틱스 속성을 사용하려면 GA 계정에서 별도 세팅을 해주어야 한다. 이에 따라 GA 추적 코드 형식도 UA-XXXXXXXX-X
에서 G-XXXXXXXXXX
로 변경되었다.
유럽권에서 개인정보를 활용한 마케팅에 대해 규제를 진행하고 있어 향후 구글은 기존의 방식을 버리고 새로운 방식으로 마케팅 지원을 할 수 있도록 방향을 전환하고 있다. 따라서, 변화에 대응할 수 있도록 보수적으로 이식을 진행하고자 라이브러리 없이 GA를 이식하는 방향으로 작업을 진행했다.
.env
파일에 GA 추적 코드 복사하기.env.local
NEXT_PUBLIC_GOOGLE_ANALYTICS="code"
_app.js
파일에 GA 추적 코드 추가하기Next.js에서 태그나 태그 안에 들어갈 내용들을 커스텀할 때는 주로 _document.js
파일을 사용한다. 아마 대부분 포스팅에서도 엘리먼트에 GA 관련 코드를 이식하기 위해 _document.js
를 커스텀 하고 있을 것이다.
하지만, vercel/Next.js의 샘플 코드를 확인하면 _app.js
에서 커스텀을 진행하고 있다.
직접 프로젝트에서 _document.js
파일에 이식을 진행해보면 린트에서 다음과 같이 경고하는 것을 확인할 수 있다.
아마 이것은 Next 11이 릴리즈 되고나서 추가된 next/Script 때문인것으로 보이는데, Next.js 공식 홈페이지는 이에 관해서 이렇게 설명하고 있다.
Next.js는 SSR(ServerSideRendering) 구현하고 있는 프레임웍이고 서버단에서 실행되는 코드에서 window객체를 참고하는 코드를 실행하면 window is not defined
란 에러를 띄운다.
// ga 관련 태그
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gtag.GA_TRACKING_ID}', {
page_path: window.location.pathname,
});
따라서, 윈도우를 참조하고 있는 코드가 클라이언트 단에서 안정적으로 실행될 수 있도록 개선된 것으로 보인다.
_app.js
와 next/Scriptvercel에서 제안하는 샘플 코드는 아래와 같다.
import { useEffect } from 'react'
import Script from 'next/script'
import { useRouter } from 'next/router'
import * as gtag from '../lib/gtag'
const App = ({ Component, pageProps }) => {
const router = useRouter()
return (
<>
{/* 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,
});
`,
}}
/>
<Component {...pageProps} />
</>
)
}
next/Script
는 개발자들이 third-party 스크립트들의 로딩 우선순위를 설정할 수 있어 로딩 성능을 향상시킬 수 있다. next/Head
를 _document.js
에서만 사용할 수 있다면, next/Script
는 _app.js
에서만 위치시킬 수 있다.
next/Script를 어떻게 적용시킬 것인지(Strategy)에 대한 옵션 값들은 다음과 같다.
이외에도 다양하게 적용할 수 있도록 지원하고 있다. 공식문서 살펴보기
useEffect(() => {
const handleRouteChange = (url) => {
gtag.pageview(url)
}
router.events.on('routeChangeComplete', handleRouteChange)
router.events.on('hashChangeComplete', handleRouteChange)
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
router.events.off('hashChangeComplete', handleRouteChange)
}
}, [router.events])
위 코드를 _app.js
컴포넌트에 위치 시킴으로써 이벤트(유입, 이탈) 유형에 따라 조회수를 측정할 수 있다.
만일 GA 뿐만 아니라, 구글 애드센스 등의 다른 툴을 프로젝트에 적용시켜야 한다면 마찬가지로 _app.js
에
next/Script 컴포넌트를 사용해 적용할 수 있다.
만일 GoogleAds를 붙여야 한다면, GA가 적용된 코드 최하단에 gtag('confing', 'Google ADS코드')를 삽입하면 적용 가능하다. 각 트래킹 코드를 분석해 관련 툴에서 로그를 파싱해 기록한다.
<Script
id="gtag-init"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${ga.GA_TRACKING_ID}', {
page_path: window.location.pathname,
});
gtag('config', 'GOOGLE_ADS_TRACKINGCODE'); <-
`,
}}
/>
GA는 마케터였던 과거에도 날 애먹이더니, 이번에도 쉽지 않았다. 여러가지 포스팅에서 이전의 방식으로 GA를 적용하도록 안내하고 있어 적잖히 혼동을 주었기 때문이다.
공식 문서에 안내하는 방식 외에도 GA 등 마케팅 툴을 적용하는 방식은 다양하다. 하지만, 향후 보수성과 퍼포먼스를 고려한다면 공식문서가 제안하는 방향으로 이식을 진행하는 것이 합리적인 결정이라는 생각이 들었다.
이번에도 다시 한 번 더 공식문서의 중요성을 확인했다.
안녕하세요~ 글 잘 읽었습니다. 궁금한 점이 하나 있는데, 혹시 추적 코드를 const로 주는게 아니라 env에 넣어두는 이유가 있을까요?