
주제 선정
요즘 개인 프로젝트나 사이드 프로젝트를 진행하다 보면 "사용자가 어떻게 서비스를 사용하고 있는가?" 에 대한 궁금중이 컸고, 해당 데이터가 중요하다는걸 많은 순간에 느끼게 된다.
단순히 화면을 잘 만들고 기능을 구현하는게 끝이 아니라 실제로 어떤 페이지가 자주 방문되는지? 어디에서 이탈이 발생하는지? 어떤 행동 흐름을 보이는지? 를 기반으로 개선 방향을 잡아야 하기 떄문이다.
이런 맥락에서 가장 많이 활용되는 도구가 바로 Google Analytics 4(GA4) 이다.
GA4는 기존 Universal Analytics와 달리 이벤트 중 심의 분석 구조를 가지고 있고, 사용자 행동을 더 유연하고 세밀하게 추적할 수 있다는 장점이 있다.
하지만 막상 프론트엔트 프로젝트에 적용하려고 하면 초기 설정부터 이벤트 연동 단계에서 생각보다 어렵게 느껴진다.
이번 글에서는 React + Vite로 구성된 프로젝트 이며 FSD 관점을 기준으로 GA4를 어덯게 연동하고 기본적인 설정을 진행할 수 있는지 정리해 보려고한다.
GA4 이벤트 중심 모델 이해하기
GA4의 가증 큰 특징은 모든 데이터가 이벤트 기반이라는 점이다.
기존 Universal Analytics 에서는
- 페이지뷰
- 이벤트
- 사용사 속성
이 비교적 명확하게 구분되어 있었지만
반면 GA4에서는 페이지뷰 조차 하나의 이벤트로 취급된다.
이렇게 이벤트로 취급하게 되면 오는 이점이
- 페이지가 아닌 행동 중심 분석이 가능하다
- 동일한 방식으로 클릭, 전환, 에러, 스크롤 등을 추적할 수 있다.
- 커스텀 이벤트 설계가 훨씬 자유롭다
하지만 이렇게 장점만 있는건 아니고
아무 이벤트나 막 보내게되면 나중에 분석하기 오히려 더 어려워진다.
그러므로 프론트엔트 코드 레벨에서 이벤트 구조를 적절하게 통제하는 것이 중요하다.
Google Analytics 만들기
기본적인 GA4를 사용하기위해서는 Google Analytics 에 접속해서 속성을 생성해주오야한다.
1. 속성 이름 설정
속성에서 사용할 이름을 설정해준다.

2. 업종 및 카테고리, 규모 설정
업종 및 카테고리와
비즈니스의 규모를 목적에 맞게 설정해준다

3. 비즈니스 목표 설정
아래의 항목에서 나에게 맞는 비즈니스 목표를 설정해주면 된다

4. 데이터 스트림 설정
내가 적용하고자 하는 웹사이트의 주소와 별칭을 입력해준다

5. 스트림 ID, 측정 ID 확인
위의 단계를 거치면 다음과 같이 웹 스트림 세부정보를 얻을 수 있는데
여기서 측저에 필요한 스트림 ID, 측정 ID를 가져올 수 있다.
해당 ID값들을 가지고 이제 React와 연결해주도록한다.

왜 GA4를 코드 레벨에서 관리해야 할까?
GA4는 단순히 붙여두면 알아서 수집되는 분석 도구가 아니다.
실제로 Google Analytics에 접속해서 속성을 만들게 되면 코드를 index.html 에 붙여넣으라고 안내를 받는다.
하지만 그렇게 하면 실제로 어떤 이벤트에 대한 세세한 설정이 어렵다는 단점이 있다.
그래서 단순하게 GA4 코드 붙여넣기가 아니라 FSD 구조에서 GA4를 어디에 두는게 적절한지
페이지뷰, 이벤트, 사용자 속성은 어떻게 분리하면 좋은지
에 대한 고민을 하게되면 코드 레벨에서 관리를 해야 이점이 있다고 느끼게된다.
React와 연결하기
이제 FSD 아키텍쳐 구조에 맞게 파일을 구성해보려고한다.
ID값 같은 경우 노출에 대해서는 최대한 피하는 방향으로 .env파일 안에 위치시키려고한다.
.env 파일 안에는 이전에 받아온 G로 시작하는 측정 ID를 넣어주면 된다
VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXX
GA4와 관련된 내용은 Shared 레이어로 src/shared/analytics 의 폴더를 만들고 그 하단에 구성해보려고한다.
여기서 왜 Shared 레이어에 넣는지 의문이 들수도 있다.
이벤트들은 어디서든 발생하게 된다.
유저가 로그인할때 (로그인 페이지)
유저가 페이지 이동할때 (각 페이지)
API에 대한 에러를 추적할때 (각 API)
이렇게 다양하게 애플리케이션 전반적으로 사용되는 공통 인프라에 가깝다.
그래서 Shared 레이어에 위치 시켰다.
react-ga4 설치
https://www.npmjs.com/package/react-ga4
정확한 측정을 위해서 react-ga4라이 브러리를 설치한다
yarn add react-ga4
or
npm i react-ga4
이벤트 타입 정의
위치 : src/shared/analytics/types.ts
라이브러리의 작성된 값을 토대로 파라미터를 정의해 준다.
이벤트 구조를 명시적으로 통제하고 설계가 산발적으로 퍼지는 것을 방지하고 추후 이벤트 네이밍 컨벤션 통일을 위해 별도의 타입으로 정의해주었다.

// 이벤트 파라미터 타입 정의
export interface GAEvent {
category: string;
action: string;
label?: string;
value?: number;
}
export interface GAPageView {
path: string;
title?: string;
}
GA4 초기화 및 핵심 함수
위치 : src/shared/analytics/ga4.ts
타입을 정의했다면 이제 GA4를 사용하기 위해 초기화를 시키고 그 안에서 사용할 핵심 함수에 대해서 정의를 해줘야한다.
import ReactGA from "react-ga4";
import { GAEvent } from "./types";
// GA4 측정 ID (환경변수로 관리)
const GA_MEASUREMENT_ID = import.meta.env.VITE_GA_MEASUREMENT_ID || "";
/**
* GA4 초기화
*/
export const initGA = () => {
if (!GA_MEASUREMENT_ID) {
console.warn("GA4 Measurement ID가 설정되지 않았습니다.");
return;
}
ReactGA.initialize(GA_MEASUREMENT_ID, {
gaOptions: {
// 디버그 모드 (개발 환경에서만)
debug_mode: import.meta.env.DEV,
},
gtagOptions: {
// 쿠키 설정
cookie_flags: "SameSite=None;Secure",
},
});
console.log("GA4 초기화 완료");
};
/**
* 페이지뷰 추적
*/
export const trackPageView = (path: string, title?: string) => {
if (!GA_MEASUREMENT_ID) return;
ReactGA.send({
hitType: "pageview",
page: path,
title: title || document.title,
});
console.log("GA4 PageView:", path, title);
};
/**
* 이벤트 추적
*/
export const trackEvent = (event: GAEvent) => {
if (!GA_MEASUREMENT_ID) return;
ReactGA.event({
category: event.category,
action: event.action,
label: event.label,
value: event.value,
});
console.log("GA4 Event:", event);
};
/**
* 사용자 속성 설정
*/
export const setUserProperties = (properties: Record<string, string | number>) => {
if (!GA_MEASUREMENT_ID) return;
ReactGA.gtag("set", "user_properties", properties);
};
App.tsx에서 GA4 초기화
App.tsx에서 이전에 만들었던 ga4.ts 의 initGa를 호출해주어 초기화를 시켜주어야 한다.
import { useEffect } from "react";
import { AppRouter } from "./router";
import { ToastProvider, AlertProvider } from "@shared/ui";
import { initGA } from "@shared/analytics";
export function App() {
useEffect(() => {
initGA();
}, []);
useEffect(() => {
const handleContextMenu = (e: MouseEvent) => {
e.preventDefault();
};
document.addEventListener("contextmenu", handleContextMenu);
return () => {
document.removeEventListener("contextmenu", handleContextMenu);
};
}, []);
return (
<ToastProvider>
<AlertProvider>
<AppRouter />
</AlertProvider>
</ToastProvider>
);
}
정상적으로 호출이 완료되었다면 다음과 같이 초기화 완료 메시지가 뜨고

Google Analytics에 들어가게되면 다음 이미지와 같이 활성 사용자가 잡히게된다

Router에서 페이지뷰 추적
이렇게 기초적인 세팅을 끝내고 난 다음 해야되는게 무엇일까?
유저가 어던 페이지에 접속하여있는지 알아내야한다.
그러기 위해선 Router 내부에서 어떤 페이지에 접근하는지 알려주도록한다.
아래 코드와 같이 필요 훅들과 컴포넌트를 작성해주고
AppRouter 의 BrowserRouter의 하단에 작성하도록 한다
Router 레벨에서 페이지뷰를 추적하는 이유는
SPA환경에서는 페이지가 바꿔도 브라우저의 새로고침이 발생하지 않기 때문에
GA입장에서는 사용자가 페이지를 이동했다는 사실을 명시적으로 알려줘야 하기 떄문이다.
import { trackPageView } from "@shared/analytics";
// 페이지뷰 추적 훅
function usePageTracking() {
const location = useLocation();
useEffect(() => {
trackPageView(location.pathname + location.search);
}, [location]);
}
// 페이지 추적 컴포넌트
function PageTracker() {
usePageTracking();
return null;
}
export function AppRouter() {
return (
<BrowserRouter>
<PageTracker />
</BrowserRouter>
);
}
이렇게 페이지 뷰를 추적하도록 했다면
trackingPageView에 따라서 어떤 페이지에 접근했는지 확인할 수 있다.

이벤트 추적하기
사용자가 특정 버튼을 누른경우, 특정 폼을 제출한 경우, 또는 에러를 추적하는 경우에 다음과 같이 추적할 수 있다.
import { trackEvent } from "@shared/analytics";
// 버튼 클릭 추적
const handleLoginClick = () => {
trackEvent({
category: "User",
action: "Login",
label: "Login Button",
});
// 로그인 로직...
};
// 폼 제출 추적
const handleFormSubmit = () => {
trackEvent({
category: "Form",
action: "Submit",
label: "Timetable Creation",
});
// 폼 제출 로직...
};
// 에러 추적
const handleError = (error: Error) => {
trackEvent({
category: "Error",
action: "API Error",
label: error.message,
});
};
그럼 여기서 이벤트 추적은 언제, 어디까지 할까 의문이 들 수 있다.
무조건 많은 이벤트를 추적한다고 해서 좋은 코드는 아니다.
- 핵심 CTA 클릭
- 전환과 직접적으로 연결된 액션
- 사용자가 의사결정 을 하는 순간
- 에러, 실패 케이스
와 같은 경우에는 추적하면 분석에 좋은 포인트들이다.
하지만 모든 버튼, 단순 UI 인터렉션, 분석 목적이 불분명한 이벤트는 피하는 방향이 좋다.
이벤트 하나하나가 나중에 이 데이터를 보고 어떤 판단을 할 수 있는가? 에 대해서 답변이 가능한 이벤트 들에만 사용하는 것이 좋은 방식이다.
결론
GA4는 단순히 방문자 수를 확인하는 도구가 아니라,
사용자의 실제 행동을 이해하기 위한 도구에 가깝다.
내 프로젝트에서 어떤 기능이 자주 사용되는지, 어느 지점에서 이탈이 발생하는지
그리고 우리가 의도한 흐름이 실제 사용자에게도 자연스럽게 이어지고 있는지를 데이터로 확일할 수 있게 해준다.
이번 글에서는 React + Vite 환경에서 Ga4를 단순히 연동하는 방법을 FSD 구조를 기준으로 분석 로직을 어떻게 분리하고 관리할 수 있는지 초점을 맞췄다.
shared/analytics 레이어에 GA4관련 로직을 모아두면서 페이지뷰, 이벤트, 사용자 속성을 공통 인터페이스로 관리하면 프로젝트가 커지더라고 추적 구조가 유지된다.
또한 Router 레벨에서 페이지 뷰를 추적하고 필요한 지점에서만 명확한 의미를 가진 이벤트를 정의함 으로써 불필요한 로그를 줄이고 실제로 판단에 도움이 되는 데이터에 집줄할 수 있다.
이번 세팅을 시작으로 전환 이벤트, 커스텀 디멘션, 퍼널 분석을 위한 이벤트 설계의 단계까지 확장해 나아간다면 단순한 로그 수집을 넘어 의사결정을 돕는분석 환경을 만들 수 있다.
참고
https://github.com/codler/react-ga4/blob/HEAD/src/ga4.test.js
react-ga4/src/ga4.test.js at d50684824f5d155c772721d93ff2be7ea65767bf · codler/react-ga4
React Google Analytics 4. Contribute to codler/react-ga4 development by creating an account on GitHub.
github.com
https://www.npmjs.com/package/react-ga4
https://velog.io/@slight-snow/React.js-GA4Google-Analytics-API-%ED%98%B8%EC%B6%9C%ED%95%98%EA%B8%B0
[React.js] GA4(Google Analytics) - ②API 호출하기
React에서 GA4(Google Analytics) 보고서 API를 다루는 방법을 알아보고자 한다.
velog.io
'Web > React' 카테고리의 다른 글
| React에서 이미지와 파일 관리 public vs. src/assets (0) | 2025.08.29 |
|---|---|
| Vite 기반 React 프로젝트에서 Path Alias 설정하기 (1) | 2025.07.09 |
| React + Vite + TypeScript + Tailwind CSS(4.0 이상) 설정 방법 (0) | 2025.07.04 |