Add analytics to a Next.js app
Real-time visitor tracking, automatic Core Web Vitals, and React error capture — wired into the App Router in under 5 minutes. This is the same integration pattern metrictrail.io itself runs in production.
1. Install
npm install @metrictrail/react @metrictrail/tracker
2. Wrap your root layout
MetricTrailProvider is a Client Component — put it inside a small client wrapper and render that wrapper from app/layout.tsx. autoWebVitals and autoErrors turn on automatic LCP/INP/CLS capture and unhandled error reporting with no extra code.
// app/telemetry-provider.tsx
'use client';
import { MetricTrailProvider } from '@metrictrail/react';
export function TelemetryProvider({ children }: { children: React.ReactNode }) {
return (
<MetricTrailProvider
options={{
projectId: '<PROJECT_ID>',
writeKey: '<WRITE_KEY>',
autoWebVitals: true,
autoErrors: true,
}}
>
{children}
</MetricTrailProvider>
);
}
// app/layout.tsx
import { TelemetryProvider } from './telemetry-provider';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<TelemetryProvider>{children}</TelemetryProvider>
</body>
</html>
);
}3. Track route changes
The App Router has no built-in "route changed" event — usePathname from next/navigation is the standard way to detect a client-side navigation. Add a small tracker component and mount it once in the root layout, alongside the provider:
// app/route-tracker.tsx
'use client';
import { useEffect } from 'react';
import { usePathname } from 'next/navigation';
import { useMetricTrail } from '@metrictrail/react';
export function RouteTracker() {
const pathname = usePathname();
const { page } = useMetricTrail();
useEffect(() => {
page(pathname);
}, [pathname, page]);
return null;
}4. Catch React errors
autoErrors already reports unhandled errors. To also catch component render errors with a graceful fallback UI, wrap the tree with MetricTrailErrorBoundary:
import { MetricTrailErrorBoundary } from '@metrictrail/react';
<MetricTrailErrorBoundary
fallback={({ error, resetError }) => (
<div role="alert">
<p>Something went wrong: {error.message}</p>
<button onClick={resetError}>Try again</button>
</div>
)}
>
<Dashboard />
</MetricTrailErrorBoundary>Track a custom event
Use the useMetricTrail hook from any Client Component:
'use client';
import { useMetricTrail } from '@metrictrail/react';
export function CheckoutButton() {
const { track } = useMetricTrail();
return (
<button onClick={() => track('checkout_started', { cart_size: 3 })}>
Checkout
</button>
);
}Prefer the lower-level API? @metrictrail/tracker works the same way without React bindings — see the full SDK reference for every method, or run the free SEO checker on your site while you're here.
No credit card required · 5-minute setup · Cancel anytime