diff --git a/app/root.tsx b/app/root.tsx index 5b8fef4e4..60cdc061a 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -35,11 +35,15 @@ import { COMMON_PREVIEW_IMAGE } from "./utils/urls"; import { ConditionalScrollRestoration } from "./components/ConditionalScrollRestoration"; import { type SendouRouteHandle } from "~/utils/remix"; import generalI18next from "i18next"; -import * as gtag from "~/utils/gtags.client"; import { Theme, ThemeHead, useTheme, ThemeProvider } from "./modules/theme"; import { getThemeSession } from "./modules/theme/session.server"; import { isTheme } from "./modules/theme/provider"; import { useIsMounted } from "./hooks/useIsMounted"; +import { load, trackPageview } from "fathom-client"; +import invariant from "tiny-invariant"; + +const FATHOM_ID = "MMTSTBEP"; +const FATHOM_CUSTOM_URL = "https://cheeky-efficient.sendou.ink"; export const unstable_shouldReload: ShouldReloadFunction = ({ url }) => { // reload on language change so the selected language gets set into the cookie @@ -90,6 +94,8 @@ export const loader: LoaderFunction = async ({ request }) => { const locale = await i18next.getLocale(request); const themeSession = await getThemeSession(request); + invariant(process.env["BASE_URL"], "BASE_URL env var is not set"); + return json( { locale, @@ -131,6 +137,7 @@ function Document({ useChangeLanguage(locale); usePreloadTranslation(); + useFathom(); return ( @@ -223,6 +230,22 @@ export const ErrorBoundary: ErrorBoundaryComponent = ({ error }) => { ); }; +function useFathom() { + const location = useLocation(); + + React.useEffect(() => { + if (process.env.NODE_ENV !== "production") return; + + load(FATHOM_ID, { url: FATHOM_CUSTOM_URL }); + }, []); + + React.useEffect(() => { + if (process.env.NODE_ENV !== "production") return; + + trackPageview(); + }, [location.pathname, location.search]); +} + function HydrationTestIndicator() { const isMounted = useIsMounted(); diff --git a/app/utils/gtags.client.ts b/app/utils/gtags.client.ts deleted file mode 100644 index 6cbb57960..000000000 --- a/app/utils/gtags.client.ts +++ /dev/null @@ -1,22 +0,0 @@ -declare global { - interface Window { - gtag: ( - option: string, - gaTrackingId: string, - options: Record - ) => void; - } -} - -/** - * @example - * https://developers.google.com/analytics/devguides/collection/gtagjs/pages - */ -export const pageview = (url: string, trackingId: string) => { - if (!window.gtag) { - return; - } - window.gtag("config", trackingId, { - page_path: url, - }); -}; diff --git a/package-lock.json b/package-lock.json index 9446cfc79..9adc5ebf5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "clsx": "^1.2.1", "countries-list": "^2.6.1", "date-fns": "^2.29.3", + "fathom-client": "^3.5.0", "fuse.js": "^6.6.2", "gray-matter": "^4.0.3", "i18next": "^21.9.2", @@ -8711,6 +8712,11 @@ "reusify": "^1.0.4" } }, + "node_modules/fathom-client": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fathom-client/-/fathom-client-3.5.0.tgz", + "integrity": "sha512-BiRDS9Q9a8Zma0H717FWC5cvf545K/CsxBpxKT22TcSl1EbRhhlHWIJgrdeiQUfdorBK2ppy09TwMOhRsbos/A==" + }, "node_modules/fault": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", @@ -23606,6 +23612,11 @@ "reusify": "^1.0.4" } }, + "fathom-client": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fathom-client/-/fathom-client-3.5.0.tgz", + "integrity": "sha512-BiRDS9Q9a8Zma0H717FWC5cvf545K/CsxBpxKT22TcSl1EbRhhlHWIJgrdeiQUfdorBK2ppy09TwMOhRsbos/A==" + }, "fault": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", diff --git a/package.json b/package.json index 028f4468b..2412119f5 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "clsx": "^1.2.1", "countries-list": "^2.6.1", "date-fns": "^2.29.3", + "fathom-client": "^3.5.0", "fuse.js": "^6.6.2", "gray-matter": "^4.0.3", "i18next": "^21.9.2",