diff --git a/src/components/common/Layout/SubLayout.tsx b/src/components/common/Layout/SubLayout.tsx
index a18d3837..c8fba9a4 100644
--- a/src/components/common/Layout/SubLayout.tsx
+++ b/src/components/common/Layout/SubLayout.tsx
@@ -1,6 +1,9 @@
import { Outlet } from 'react-router-dom';
+import usePageViewTracking from '@/hooks/usePageViewTracking';
export default function SubLayout() {
+ usePageViewTracking();
+
return (
diff --git a/src/components/poll-detail/Button/PollButton.tsx b/src/components/poll-detail/Button/PollButton.tsx
index 3b0459e0..b8d3d5a9 100644
--- a/src/components/poll-detail/Button/PollButton.tsx
+++ b/src/components/poll-detail/Button/PollButton.tsx
@@ -1,4 +1,5 @@
import { useQueryClient } from '@tanstack/react-query';
+import ReactGA from 'react-ga4';
import usePost from '@/api/usePost';
import { Button } from '@/components/common/Button/Button';
import useToast from '@/components/common/Toast/hooks';
@@ -16,6 +17,10 @@ export default function PollButton({ postId, checkedItems }: PollButtonProps) {
const { mutate: vote, isPending } = usePost({
onSuccess: () => {
+ ReactGA.event('poll_voted', {
+ post_id: postId,
+ });
+
queryClient.invalidateQueries({ queryKey: ['post', String(postId)] });
queryClient.invalidateQueries({
queryKey: ['postResult', String(postId)],
@@ -26,7 +31,6 @@ export default function PollButton({ postId, checkedItems }: PollButtonProps) {
description: '투표가 성공적으로 완료되었어요.',
});
- // voteMode 종료
setVoteMode(false);
},
});
diff --git a/src/hooks/usePageViewTracking.ts b/src/hooks/usePageViewTracking.ts
new file mode 100644
index 00000000..23dc32fc
--- /dev/null
+++ b/src/hooks/usePageViewTracking.ts
@@ -0,0 +1,14 @@
+import { useEffect } from 'react';
+import ReactGA from 'react-ga4';
+import { useLocation } from 'react-router-dom';
+
+export default function usePageViewTracking() {
+ const location = useLocation();
+
+ useEffect(() => {
+ ReactGA.send({
+ hitType: 'pageview',
+ page: location.pathname + location.search,
+ });
+ }, [location]);
+}
diff --git a/src/pages/OnBoarding/OnBoardingPage.tsx b/src/pages/OnBoarding/OnBoardingPage.tsx
index bc18b0b3..54ebebd6 100644
--- a/src/pages/OnBoarding/OnBoardingPage.tsx
+++ b/src/pages/OnBoarding/OnBoardingPage.tsx
@@ -1,4 +1,5 @@
import { useEffect, useState } from 'react';
+import ReactGA from 'react-ga4';
import { useNavigate } from 'react-router-dom';
import useGetMyInfo from '@/api/useGetMyInfo';
import onboardingImage from '@/assets/images/onboarding/onboarding.png';
@@ -22,6 +23,12 @@ export default function OnBoardingPage() {
}, 2500);
}, []);
+ useEffect(() => {
+ if (!showSplash) {
+ ReactGA.event('onboarding_viewed');
+ }
+ }, [showSplash]);
+
if (showSplash) {
return (
diff --git a/src/pages/PollDetail/PollResultPage.tsx b/src/pages/PollDetail/PollResultPage.tsx
index 34d64a42..9cb210ac 100644
--- a/src/pages/PollDetail/PollResultPage.tsx
+++ b/src/pages/PollDetail/PollResultPage.tsx
@@ -1,3 +1,5 @@
+import { useEffect } from 'react';
+import ReactGA from 'react-ga4';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { useGetNotificationPresent } from '@/api/useGetNotificationPresent';
import { useGetPost } from '@/api/useGetPost';
@@ -29,6 +31,14 @@ export default function PollResultPage() {
},
});
+ useEffect(() => {
+ if (post && result) {
+ ReactGA.event('poll_result_viewed', {
+ post_id: postId,
+ });
+ }
+ }, [post, result, postId]);
+
if (isPostLoading || isResultLoading) return ;
if (!post || !result) return ;