From 19203baee262b3a78f60353d42415015c7013291 Mon Sep 17 00:00:00 2001 From: oyuns-wishket Date: Sun, 25 Jan 2026 19:31:48 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat=20:=20ga4=20=EC=9D=B4=EB=B2=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20spa=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EB=B7=B0=20=ED=8A=B8=EB=9E=98=ED=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Layout/DefaultLayout.tsx | 3 +++ src/components/common/Layout/SubLayout.tsx | 3 +++ src/components/poll-detail/Button/PollButton.tsx | 6 +++++- src/hooks/usePageViewTracking.ts | 14 ++++++++++++++ src/pages/OnBoarding/OnBoardingPage.tsx | 7 +++++++ src/pages/PollDetail/PollResultPage.tsx | 10 ++++++++++ 6 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/hooks/usePageViewTracking.ts diff --git a/src/components/common/Layout/DefaultLayout.tsx b/src/components/common/Layout/DefaultLayout.tsx index c57ecae8..7d4aaed3 100644 --- a/src/components/common/Layout/DefaultLayout.tsx +++ b/src/components/common/Layout/DefaultLayout.tsx @@ -1,7 +1,10 @@ import { Outlet } from 'react-router-dom'; import Navigation from '@/components/common/Navigation/Navigation'; +import usePageViewTracking from '@/hooks/usePageViewTracking'; export default function DefaultLayout() { + usePageViewTracking(); + return (
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 ; From 220b24dc94b777e96f8acc9b9384e331f70a2b89 Mon Sep 17 00:00:00 2001 From: oyuns-wishket Date: Sun, 25 Jan 2026 19:41:09 +0900 Subject: [PATCH 2/2] =?UTF-8?q?chore=20:=20ga4=20=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A6=BC=20id=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 2f390167..bf9f9275 100644 --- a/index.html +++ b/index.html @@ -29,7 +29,7 @@ >