diff --git a/beta/src/components/Layout/Feedback.tsx b/beta/src/components/Layout/Feedback.tsx index 2a46cb0a..acba8c81 100644 --- a/beta/src/components/Layout/Feedback.tsx +++ b/beta/src/components/Layout/Feedback.tsx @@ -4,8 +4,7 @@ import * as React from 'react'; import {useRouter} from 'next/router'; -// @ts-ignore -import galite from 'ga-lite'; +import {ga} from '../../utils/analytics'; export function Feedback({onSubmit = () => {}}: {onSubmit?: () => void}) { const {pathname} = useRouter(); @@ -48,7 +47,7 @@ const thumbsDownIcon = ( function sendGAEvent(isPositive: boolean) { // Fragile. Don't change unless you've tested the network payload // and verified that the right events actually show up in GA. - galite( + ga( 'send', 'event', 'button', diff --git a/beta/src/pages/_app.tsx b/beta/src/pages/_app.tsx index eae136ce..9f867b63 100644 --- a/beta/src/pages/_app.tsx +++ b/beta/src/pages/_app.tsx @@ -5,8 +5,7 @@ import * as React from 'react'; import {AppProps} from 'next/app'; import {useRouter} from 'next/router'; -// @ts-ignore -import galite from 'ga-lite'; +import {ga} from '../utils/analytics'; import '@docsearch/css'; import '../styles/algolia.css'; import '../styles/index.css'; @@ -17,11 +16,11 @@ const EmptyAppShell: React.FC = ({children}) => <>{children}; if (typeof window !== 'undefined') { if (process.env.NODE_ENV === 'production') { - galite('create', process.env.NEXT_PUBLIC_GA_TRACKING_ID, 'auto'); + ga('create', process.env.NEXT_PUBLIC_GA_TRACKING_ID, 'auto'); } const terminationEvent = 'onpagehide' in window ? 'pagehide' : 'unload'; window.addEventListener(terminationEvent, function () { - galite('send', 'timing', 'JS Dependencies', 'unload'); + ga('send', 'timing', 'JS Dependencies', 'unload'); }); } @@ -29,8 +28,8 @@ export default function MyApp({Component, pageProps}: AppProps) { const router = useRouter(); React.useEffect(() => { const handleRouteChange = (url: string) => { - galite('set', 'page', url); - galite('send', 'pageview'); + ga('set', 'page', url); + ga('send', 'pageview'); }; router.events.on('routeChangeComplete', handleRouteChange); return () => { diff --git a/beta/src/utils/analytics.ts b/beta/src/utils/analytics.ts index 34e3fc39..c2cc623b 100644 --- a/beta/src/utils/analytics.ts +++ b/beta/src/utils/analytics.ts @@ -2,77 +2,25 @@ * Copyright (c) Facebook, Inc. and its affiliates. */ -const createFunctionWithTimeout = ( - callback: () => void, - opt_timeout = 1000 -) => { - let called = false; - const raceCallback = () => { - if (!called) { - called = true; - callback(); - } - }; - setTimeout(raceCallback, opt_timeout); - return raceCallback; -}; +let buffer: Array = []; +let galite: null | Function = null; +let galitePromise: null | Promise = null; -interface CustomEvent { - /** The value that will appear as the event action in Google Analytics Event reports. */ - action: string; - /** The category of the event. */ - category?: string; - /** The label of the event. */ - label?: string; - /** A non-negative integer that will appear as the event value. */ - value: number; - /** - * Whether the even is non-interactive - * @see https://support.google.com/analytics/answer/1033068#NonInteractionEvents - * @default false - */ - nonInteraction?: boolean; - /** - * A function that gets called as soon as an event has been successfully sent. - * @see https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data - */ - hitCallback?: () => void; - /** - * Max ms timeout for callback - * @default 1000 - */ - callbackTimeout?: number; -} -/** - * This allows the user to create custom events within their Next projects. - * - * @see https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#events - */ -export function trackCustomEvent({ - category, - action, - label, - value, - nonInteraction = false, - hitCallback, - callbackTimeout = 1000, -}: CustomEvent) { - if (typeof window !== `undefined` && (window as any).gtag) { - const trackingEventOptions: any = { - event_category: category, - event_action: action, - event_label: label, - value, - non_interaction: nonInteraction, - }; - - if (hitCallback && typeof hitCallback === `function`) { - trackingEventOptions.event_callback = createFunctionWithTimeout( - hitCallback, - callbackTimeout - ); - } - - (window as any).gtag(`event`, trackingEventOptions); +export function ga(...args: any[]): void { + if (typeof galite === 'function') { + galite.apply(null, args); + return; + } + buffer.push(args); + if (!galitePromise) { + // @ts-ignore + galitePromise = import('ga-lite').then((mod) => { + galite = mod.default; + galitePromise = null; + buffer.forEach((args) => { + mod.default.apply(null, args); + }); + buffer = []; + }); } }