mirror of
https://github.com/reactjs/react.dev.git
synced 2026-02-24 20:53:08 +00:00
[Beta] Lazy-load analytics
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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<any> = [];
|
||||
let galite: null | Function = null;
|
||||
let galitePromise: null | Promise<any> = 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 = [];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user