Next.js Native Open-Source Analytics
100% server-side. No client JavaScript. No cookies. No GDPR banners.
Just accurate analytics that respect your users.
Website · Integrations · Demo
Nextlytics is a server-side analytics library for Next.js. It tracks page views automatically via middleware and lets you send custom events from server components, server actions, and API routes.
There's no client-side JavaScript involved. Events go directly from your server to your analytics backend. This means no ad blockers, no cookies, and accurate data.
It works with multiple backends — Segment, PostHog, Google Analytics, or you can write directly to a database like ClickHouse or Postgres.
npm install @nextlytics/core1. Configure your backend (src/nextlytics.ts)
import { Nextlytics } from "@nextlytics/core/server";
import { segmentBackend } from "@nextlytics/core/backends/segment";
// Optional: import your auth library to track authenticated users
import { auth } from "./lib/auth"; // next-auth
export const { middleware, handlers, analytics } = Nextlytics({
backends: [
segmentBackend({
writeKey: process.env.SEGMENT_WRITE_KEY!,
}),
],
// Optional but recommended: identify authenticated users
callbacks: {
async getUser() {
const session = await auth();
if (!session?.user) return null;
return {
userId: session.user.id,
traits: { email: session.user.email, name: session.user.name },
};
},
},
});2. Add to layout (src/app/layout.tsx)
import { NextlyticsServer } from "@nextlytics/core/server";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<NextlyticsServer>{children}</NextlyticsServer>
</body>
</html>
);
}3. Export middleware (src/middleware.ts)
import { middleware } from "./nextlytics";
export { middleware };That's it. Every page view is now tracked server-side.
Nextlytics also supports the Pages Router. The middleware works the same way, but instead of
NextlyticsServer, use getNextlyticsProps in your _app.tsx:
1. Configure your backend (same as App Router - see above)
2. Add to _app.tsx (pages/_app.tsx)
import type { AppContext, AppProps } from "next/app";
import { NextlyticsClient, getNextlyticsProps, type NextlyticsContext } from "@nextlytics/core";
type MyAppProps = AppProps & { nextlyticsCtx: NextlyticsContext };
function MyApp({ Component, pageProps, nextlyticsCtx }: MyAppProps) {
return (
<NextlyticsClient ctx={nextlyticsCtx}>
<Component {...pageProps} />
</NextlyticsClient>
);
}
MyApp.getInitialProps = async (appContext: AppContext) => {
return {
pageProps: appContext.Component.getInitialProps
? await appContext.Component.getInitialProps(appContext.ctx)
: {},
nextlyticsCtx: getNextlyticsProps(appContext.ctx),
};
};
export default MyApp;3. Export middleware (same as App Router)
| Backend | Type |
|---|---|
| Segment or Jitsu | CDP |
| PostHog | Product Analytics |
| Google Analytics | Web Analytics |
| ClickHouse | Database |
| Neon / Supabase | Database |
MIT