@leetlytics/sdk for Next.js apps.
Use the NPM package for page views, product events, and fetch breakage tracking. Day zero is a few lines of client code — not an analytics warehouse project.
SDK surface
Page views, events, and breakages.
- createLeetLyticsClient with a public workspace key and ingest endpoint
- Page views and trackEvent for key product moments
- installSpaPageViewTracking for App Router client navigations
- installFetchBreakageTracking for 400/500-class request failures
- Optional server-side POST /api/conversions with a private conversion key
Run pnpm add @leetlytics/sdk, then mount this provider once from your root App Router layout.
// app/leetlytics-provider.tsx
"use client";
import { useEffect, type ReactNode } from "react";
import {
createLeetLyticsClient,
installFetchBreakageTracking,
installSpaPageViewTracking,
type JourneyStepEventInput,
type LeetLyticsClient,
} from "@leetlytics/sdk";
declare global {
interface Window {
__leetlyticsRuntime?: {
client?: LeetLyticsClient;
cleanup?: () => void;
initialPageViewSent: boolean;
};
}
}
export function LeetLyticsProvider({ children }: { children: ReactNode }) {
useEffect(() => {
const runtime = window.__leetlyticsRuntime ?? { initialPageViewSent: false };
window.__leetlyticsRuntime = runtime;
// Fast Refresh can replace this module before React runs its prior cleanup.
runtime.cleanup?.();
const leetlytics = createLeetLyticsClient({
workspaceKey: process.env.NEXT_PUBLIC_LEETLYTICS_WORKSPACE_KEY!,
endpoint: "https://leetlytics.com/api/ingest",
});
const restoreSpaPageViews = installSpaPageViewTracking(leetlytics);
const restoreFetchBreakageTracking = installFetchBreakageTracking(leetlytics);
runtime.client = leetlytics;
if (!runtime.initialPageViewSent) {
runtime.initialPageViewSent = true;
void leetlytics.trackEvent({ name: "page_view" });
}
const cleanup = () => {
// Start delivery before destroy clears the queued event and its flush timer.
const delivery = leetlytics.flush();
if (runtime.client === leetlytics) runtime.client = undefined;
restoreFetchBreakageTracking();
restoreSpaPageViews();
void delivery.finally(() => leetlytics.destroy());
};
runtime.cleanup = cleanup;
return () => {
if (runtime.cleanup === cleanup) {
cleanup();
runtime.cleanup = undefined;
}
};
}, []);
return children;
}
export function trackKeyAction(name: string) {
return window.__leetlyticsRuntime?.client?.trackEvent({ name }) ?? Promise.resolve();
}
export function trackJourneyStep(event: JourneyStepEventInput) {
return window.__leetlyticsRuntime?.client?.trackJourneyStep(event) ?? Promise.resolve();
}Out of scope for day zero
Keep the client surface small.
- Automatic GTM container wiring
- Session replay or full APM traces
- Warehouse export connectors on day zero