feat: integrate observability
All checks were successful
Monorepo Pipeline / 🧪 Quality Assurance (push) Successful in 3m50s
Monorepo Pipeline / 🚀 Release (push) Successful in 3m38s
Monorepo Pipeline / 🐳 Build & Push Images (push) Successful in 7m6s

This commit is contained in:
2026-02-07 10:23:51 +01:00
parent 6501eac38a
commit 61e78ea672
34 changed files with 1632 additions and 14 deletions

View File

@@ -0,0 +1,23 @@
"use client";
import { useEffect } from "react";
import { usePathname, useSearchParams } from "next/navigation";
import { useAnalytics } from "./context";
/**
* Automatically tracks pageviews on client-side route changes in Next.js.
*/
export function AnalyticsAutoTracker() {
const pathname = usePathname();
const searchParams = useSearchParams();
const analytics = useAnalytics();
useEffect(() => {
if (!pathname) return;
const url = `${pathname}${searchParams?.size ? `?${searchParams.toString()}` : ""}`;
analytics.trackPageview(url);
}, [pathname, searchParams, analytics]);
return null;
}

View File

@@ -0,0 +1,50 @@
"use client";
import { createContext, useContext, ReactNode, useMemo } from "react";
import type { AnalyticsService } from "@mintel/observability";
import {
NoopAnalyticsService,
UmamiAnalyticsService,
} from "@mintel/observability";
const AnalyticsContext = createContext<AnalyticsService>(
new NoopAnalyticsService(),
);
export interface AnalyticsContextProviderProps {
service?: AnalyticsService;
config?: {
enabled: boolean;
websiteId?: string;
apiEndpoint: string;
};
children: ReactNode;
}
export function AnalyticsContextProvider({
service,
config,
children,
}: AnalyticsContextProviderProps) {
const activeService = useMemo(() => {
if (service) return service;
if (config) return new UmamiAnalyticsService(config);
return new NoopAnalyticsService();
}, [service, config]);
return (
<AnalyticsContext.Provider value={activeService}>
{children}
</AnalyticsContext.Provider>
);
}
export function useAnalytics() {
const context = useContext(AnalyticsContext);
if (!context) {
throw new Error(
"useAnalytics must be used within an AnalyticsContextProvider",
);
}
return context;
}