diff --git a/client/index.html b/client/index.html index 9b7b8a5a..c942e856 100644 --- a/client/index.html +++ b/client/index.html @@ -11,6 +11,21 @@ + + + + + + + <%= process.env.META_PIXEL_CODE %> +
diff --git a/client/package-lock.json b/client/package-lock.json index c7177704..be3aad1a 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -32,6 +32,7 @@ "@storybook/react-webpack5": "^7.4.5", "@storybook/testing-library": "0.2.1", "@types/google.maps": "^3.54.0", + "@types/gtag.js": "^0.0.16", "@types/react": "^18.2.14", "@types/react-dom": "^18.2.6", "@typescript-eslint/eslint-plugin": "^5.61.0", @@ -6738,6 +6739,12 @@ "@types/node": "*" } }, + "node_modules/@types/gtag.js": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.16.tgz", + "integrity": "sha512-TefTCQWiQYc1F7zF7KKLOd5E645me+9CjfPwJLNxWxaTK3ITKmCxtHRVH7EhSo1dl+sVGmu2h2htCOZrjWQRrQ==", + "dev": true + }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", diff --git a/client/package.json b/client/package.json index 940ad104..1bf752dc 100644 --- a/client/package.json +++ b/client/package.json @@ -42,6 +42,7 @@ "@storybook/react-webpack5": "^7.4.5", "@storybook/testing-library": "0.2.1", "@types/google.maps": "^3.54.0", + "@types/gtag.js": "^0.0.16", "@types/react": "^18.2.14", "@types/react-dom": "^18.2.6", "@typescript-eslint/eslint-plugin": "^5.61.0", diff --git a/client/src/components/CafeCard.tsx b/client/src/components/CafeCard.tsx index 4993c613..c40e6fc3 100644 --- a/client/src/components/CafeCard.tsx +++ b/client/src/components/CafeCard.tsx @@ -9,6 +9,7 @@ import useCafeLikes from '../hooks/useCafeLikes'; import useClipboard from '../hooks/useClipboard'; import useUser from '../hooks/useUser'; import type { Cafe } from '../types'; +import { withGAEvent } from '../utils/GoogleAnalytics'; import Resource from '../utils/Resource'; import CafeDetailBottomSheet from './CafeDetailBottomSheet'; import CafeMenuBottomSheet from './CafeMenuBottomSheet'; @@ -42,34 +43,34 @@ const CafeCard = (props: CardProps) => { setCurrentImageIndex(index); }, []); - const handleShare = async () => { + const handleShare = withGAEvent('share', { cafeName: cafe.name }, async () => { try { await clipboard.copyToClipboard(`https://yozm.cafe/cafes/${cafe.id}`); showToast('success', 'URL이 복사되었습니다!'); } catch (error) { showToast('error', `URL 복사 실패: ${error}`); } - }; + }); - const handleLikeCountIncrease = () => { + const handleLikeCountIncrease = withGAEvent('click_like_button', { cafeName: cafe.name }, () => { if (!user) { showToast('error', '로그인이 필요합니다!'); return; } setLiked({ isLiked: !isLiked }); - }; + }); - const handleDetailOpen = () => { + const handleDetailOpen = withGAEvent('click_detail_button', { cafeName: cafe.name }, () => { setIsShowDetail(true); - }; + }); const handleDetailClose = () => { setIsShowDetail(false); }; - const handleMenuOpen = () => { + const handleMenuOpen = withGAEvent('click_menu_button', { cafeName: cafe.name }, () => { setIsMenuOpened(true); - }; + }); const handleMenuClose = () => { setIsMenuOpened(false); diff --git a/client/src/pages/HomePage.tsx b/client/src/pages/HomePage.tsx index 38c3f510..24daab61 100644 --- a/client/src/pages/HomePage.tsx +++ b/client/src/pages/HomePage.tsx @@ -1,8 +1,9 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import CafeCard from '../components/CafeCard'; import ScrollSnap from '../components/ScrollSnap'; import useCafes from '../hooks/useCafes'; import type { Cafe } from '../types'; +import { withGAEvent } from '../utils/GoogleAnalytics'; import { easeOutExpo } from '../utils/timingFunctions'; const PREFETCH_OFFSET = 2; @@ -24,6 +25,8 @@ const HomePage = () => { const itemRenderer = (cafe: Cafe) =>