Fix: guard Umami tracking and web vitals performance APIs

Avoid calling undefined umami.track, add safe checks for Performance APIs, and clean up load listeners to prevent .call() crashes in Chrome.
This commit is contained in:
Cursor Agent
2026-01-14 02:09:22 +00:00
parent ba99889782
commit abfb710c4b
3 changed files with 26 additions and 4 deletions

View File

@@ -69,6 +69,10 @@ export const AnalyticsProvider: React.FC<AnalyticsProviderProps> = ({ children }
// Track performance metrics to our API
const trackPerformanceToAPI = async () => {
try {
if (typeof performance === "undefined" || typeof performance.getEntriesByType !== "function") {
return;
}
// Get current page path to extract project ID if on project page
const path = window.location.pathname;
const projectMatch = path.match(/\/projects\/([^\/]+)/);
@@ -266,6 +270,8 @@ export const AnalyticsProvider: React.FC<AnalyticsProviderProps> = ({ children }
// Cleanup
return () => {
try {
// Remove load handler if we added it
window.removeEventListener('load', trackPerformanceToAPI);
window.removeEventListener('popstate', handleRouteChange);
document.removeEventListener('click', handleClick);
document.removeEventListener('submit', handleSubmit);

View File

@@ -25,12 +25,21 @@ export interface WebVitalsMetric {
// Track custom events to Umami
export const trackEvent = (event: string, data?: Record<string, unknown>) => {
if (typeof window !== 'undefined' && window.umami) {
window.umami.track(event, {
if (typeof window === "undefined") return;
const trackFn = window.umami?.track;
if (typeof trackFn !== "function") return;
try {
trackFn(event, {
...data,
timestamp: Date.now(),
url: window.location.pathname,
});
} catch (error) {
// Silently fail - analytics must never break the app
if (process.env.NODE_ENV === "development") {
console.warn("Error tracking Umami event:", error);
}
}
};

View File

@@ -208,6 +208,13 @@ export const useWebVitals = () => {
// Wrap everything in try-catch to prevent errors from breaking the app
try {
const safeNow = () => {
if (typeof performance !== "undefined" && typeof performance.now === "function") {
return performance.now();
}
return Date.now();
};
// Store web vitals for batch sending
const webVitals: Record<string, number> = {};
const path = window.location.pathname;
@@ -233,7 +240,7 @@ export const useWebVitals = () => {
cls: webVitals.CLS || 0,
fid: webVitals.FID || 0,
ttfb: webVitals.TTFB || 0,
loadTime: performance.now()
loadTime: safeNow()
}
})
});
@@ -307,7 +314,7 @@ export const useWebVitals = () => {
setTimeout(() => {
trackPerformance({
name: 'page-load-complete',
value: performance.now(),
value: safeNow(),
url: window.location.pathname,
timestamp: Date.now(),
userAgent: navigator.userAgent,