diff --git a/package.json b/package.json index c2be9ad3..b1d4f85b 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "quill-divider": "^0.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-ga4": "^2.1.0", "react-helmet-async": "^2.0.5", "react-quill": "^2.0.0", "react-router-dom": "^6.26.1", diff --git a/src/App.tsx b/src/App.tsx index da1c166f..f907f1d7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,7 +6,9 @@ import { HelmetProvider } from 'react-helmet-async'; import { RouterProvider } from 'react-router-dom'; import ResponsiveProvider from './components/commons/Responsive/ResponsiveProvider'; import Loading from './pages/loading/Loading'; + import router from './routers/Router'; +import RouteTracker from './routers/RouteTracker'; import { MOBILE_MEDIA_QUERY } from './styles/mediaQuery'; const App = () => { @@ -17,14 +19,15 @@ const App = () => { }, }, }); + return ( - {/*
*/} }> + @@ -44,7 +47,6 @@ const DesktopWrapper = styled.div` scroll-behavior: smooth; @media ${MOBILE_MEDIA_QUERY} { - /* width: 100%; */ width: 100%; max-width: 83rem; } diff --git a/src/routers/RouteTracker.tsx b/src/routers/RouteTracker.tsx new file mode 100644 index 00000000..98a47a59 --- /dev/null +++ b/src/routers/RouteTracker.tsx @@ -0,0 +1,27 @@ +import { useEffect, useState } from 'react'; +import ReactGA from 'react-ga4'; +import { useLocation } from 'react-router-dom'; + +const RouteTracker = () => { + const [isInitialized, setIsInitialized] = useState(false); + + const location = useLocation(); + + useEffect(() => { + if (!window.location.href.includes('localhost')) { + ReactGA.initialize(import.meta.env.VITE_GOOGLE_ANALYTICS_ID); + + setIsInitialized(true); + } + }, []); + + useEffect(() => { + if (isInitialized) { + ReactGA.send({ hitType: 'pageview', page: location.pathname }); + } + }, [isInitialized, location]); + + return null; +}; + +export default RouteTracker; diff --git a/yarn.lock b/yarn.lock index 04adeea8..b88c4493 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6091,6 +6091,11 @@ react-fast-compare@^3.2.2: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== +react-ga4@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/react-ga4/-/react-ga4-2.1.0.tgz#56601f59d95c08466ebd6edfbf8dede55c4678f9" + integrity sha512-ZKS7PGNFqqMd3PJ6+C2Jtz/o1iU9ggiy8Y8nUeksgVuvNISbmrQtJiZNvC/TjDsqD0QlU5Wkgs7i+w9+OjHhhQ== + react-helmet-async@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-2.0.5.tgz#cfc70cd7bb32df7883a8ed55502a1513747223ec" @@ -6756,7 +6761,16 @@ string-convert@^0.2.0: resolved "https://registry.yarnpkg.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97" integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6830,7 +6844,14 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -7390,7 +7411,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -7408,6 +7429,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"