🚀 Add automatic deployment system
- Add auto-deploy.sh script with full CI/CD pipeline - Add quick-deploy.sh for fast development deployments - Add Git post-receive hook for automatic deployment on push - Add comprehensive deployment documentation - Add npm scripts for easy deployment management - Include health checks, logging, and cleanup - Support for automatic rollback on failures
This commit is contained in:
112
lib/analytics.ts
Normal file
112
lib/analytics.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
// Analytics utilities for Umami with Performance Tracking
|
||||
declare global {
|
||||
interface Window {
|
||||
umami?: {
|
||||
track: (event: string, data?: Record<string, unknown>) => void;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface PerformanceMetric {
|
||||
name: string;
|
||||
value: number;
|
||||
url: string;
|
||||
timestamp: number;
|
||||
userAgent?: string;
|
||||
}
|
||||
|
||||
export interface WebVitalsMetric {
|
||||
name: 'CLS' | 'FID' | 'FCP' | 'LCP' | 'TTFB';
|
||||
value: number;
|
||||
delta: number;
|
||||
id: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
// Track custom events to Umami
|
||||
export const trackEvent = (event: string, data?: Record<string, unknown>) => {
|
||||
if (typeof window !== 'undefined' && window.umami) {
|
||||
window.umami.track(event, {
|
||||
...data,
|
||||
timestamp: Date.now(),
|
||||
url: window.location.pathname,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Track performance metrics
|
||||
export const trackPerformance = (metric: PerformanceMetric) => {
|
||||
trackEvent('performance', {
|
||||
metric: metric.name,
|
||||
value: Math.round(metric.value),
|
||||
url: metric.url,
|
||||
userAgent: metric.userAgent,
|
||||
});
|
||||
};
|
||||
|
||||
// Track Web Vitals
|
||||
export const trackWebVitals = (metric: WebVitalsMetric) => {
|
||||
trackEvent('web-vitals', {
|
||||
name: metric.name,
|
||||
value: Math.round(metric.value),
|
||||
delta: Math.round(metric.delta),
|
||||
id: metric.id,
|
||||
url: metric.url,
|
||||
});
|
||||
};
|
||||
|
||||
// Track page load performance
|
||||
export const trackPageLoad = () => {
|
||||
if (typeof window === 'undefined') return;
|
||||
|
||||
const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
|
||||
|
||||
if (navigation) {
|
||||
trackPerformance({
|
||||
name: 'page-load',
|
||||
value: navigation.loadEventEnd - navigation.fetchStart,
|
||||
url: window.location.pathname,
|
||||
timestamp: Date.now(),
|
||||
userAgent: navigator.userAgent,
|
||||
});
|
||||
|
||||
// Track individual timing phases
|
||||
trackEvent('page-timing', {
|
||||
dns: Math.round(navigation.domainLookupEnd - navigation.domainLookupStart),
|
||||
tcp: Math.round(navigation.connectEnd - navigation.connectStart),
|
||||
request: Math.round(navigation.responseStart - navigation.requestStart),
|
||||
response: Math.round(navigation.responseEnd - navigation.responseStart),
|
||||
dom: Math.round(navigation.domContentLoadedEventEnd - navigation.responseEnd),
|
||||
load: Math.round(navigation.loadEventEnd - navigation.domContentLoadedEventEnd),
|
||||
url: window.location.pathname,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Track API response times
|
||||
export const trackApiCall = (endpoint: string, duration: number, status: number) => {
|
||||
trackEvent('api-call', {
|
||||
endpoint,
|
||||
duration: Math.round(duration),
|
||||
status,
|
||||
url: window.location.pathname,
|
||||
});
|
||||
};
|
||||
|
||||
// Track user interactions
|
||||
export const trackInteraction = (action: string, element?: string) => {
|
||||
trackEvent('interaction', {
|
||||
action,
|
||||
element,
|
||||
url: window.location.pathname,
|
||||
});
|
||||
};
|
||||
|
||||
// Track errors
|
||||
export const trackError = (error: string, context?: string) => {
|
||||
trackEvent('error', {
|
||||
error,
|
||||
context,
|
||||
url: window.location.pathname,
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user