umami-analytics-react
Version:
React hooks (useUmami, useUmamiView) and UmamiProvider for seamless Umami analytics integration, supporting page views, custom event tracking, and session identification.
64 lines (63 loc) • 2.51 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { useEffect, useRef, useCallback } from "react";
import { UmamiProviderContext } from "./context";
import { createScript } from "../utils/create-script";
import { tryUmami } from "../utils/try-umami";
export function UmamiProvider({ children, websiteId, autoLoad = true, scriptSrc = "https://cloud.umami.is/script.js", scriptAttributes = {}, }) {
const umami = useRef(null);
const eventQueue = useRef([]);
const flushQueue = useCallback(() => {
if (!umami.current)
return;
eventQueue.current.forEach(({ eventName, args }) => {
tryUmami(umami, eventName, args);
});
eventQueue.current = [];
}, []);
const onScriptLoad = useCallback((_event) => {
umami.current = window.umami;
flushQueue();
}, [flushQueue]);
const register = useCallback((props = {}) => {
if (umami.current) {
console.warn("Umami Provider: Script already loaded");
return;
}
const attrs = {
...(props.scriptAttributes || scriptAttributes),
"data-website-id": props.websiteId || websiteId,
// "data-auto-track": false,
async: true,
defer: true,
onload: onScriptLoad,
};
if (!attrs["data-website-id"]) {
console.error("Umami Provider: No websiteId provided");
return;
}
const script = createScript(props.scriptSrc || scriptSrc, attrs);
document.head.appendChild(script);
}, [onScriptLoad, websiteId, scriptSrc, scriptAttributes]);
useEffect(() => {
if (!autoLoad || umami.current)
return;
register();
}, [register, autoLoad]);
const onUmamiInvoke = useCallback((eventName, args) => {
const isSuccess = tryUmami(umami, eventName, args);
if (isSuccess) {
return;
}
eventQueue.current.push({ eventName: eventName, args });
}, []);
const track = useCallback((...args) => onUmamiInvoke("track", args), [onUmamiInvoke]);
const identify = useCallback((...args) => onUmamiInvoke("identify", args), [onUmamiInvoke]);
const view = useCallback((...args) => onUmamiInvoke("track", args), [onUmamiInvoke]);
return (_jsx(UmamiProviderContext.Provider, { value: {
register,
umamiRef: umami,
track,
identify,
view,
}, children: children }));
}