DEV Community

Cover image for Integrating PostHog with NextJS
Tejas Bhovad
Tejas Bhovad

Posted on

2 1

Integrating PostHog with NextJS

PostHog is the best free (also open source) analytics platform out there, and NextJS is the most used web framework used according to State of JS survey 2024. Though Posthog has great docs, it might be difficult for any beginner to integrate posthog in their NextJS projects.

This blog encompasses how to add posthog analytics to NextJS 15 app router. Assuming you have setup a NextJS app, you’ll need to install the posthog-js package

npm install posthog-js
# OR
yarn add posthog-js
# OR
pnpm add posthog-js
Enter fullscreen mode Exit fullscreen mode

Create a .env.local file and paste the given environment variables in it

NEXT_PUBLIC_POSTHOG_KEY=phc_XXX
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
Enter fullscreen mode Exit fullscreen mode

add a posthog provider in src/providers directory

"use client";

import posthog from "posthog-js";
import { PostHogProvider } from "posthog-js/react";

if (typeof window !== "undefined") {
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
    api_host: "/ingest",
    ui_host: "https://us.posthog.com",
    person_profiles: "always",
    capture_pageview: false,
    capture_pageleave: true,
  });
}
export function NextHogProvider({ children }) {
  return <PostHogProvider client={posthog}>{children}</PostHogProvider>;
}

Enter fullscreen mode Exit fullscreen mode

Add a Page view component in src/components directory


"use client";

import { usePathname, useSearchParams } from "next/navigation";
import { useEffect } from "react";
import { usePostHog } from "posthog-js/react";

export default function PostHogPageView() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const posthog = usePostHog();
  useEffect(() => {
    // Track pageviews
    if (pathname && posthog) {
      let url = window.origin + pathname;
      if (searchParams.toString()) {
        url = url + `?${searchParams.toString()}`;
      }
      posthog.capture("$pageview", {
        $current_url: url,
      });
    }
  }, [pathname, searchParams, posthog]);

  return null;
}

Enter fullscreen mode Exit fullscreen mode

In the layout.js wrap auth provider around the body and add the PageView inside too.

    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <NextHogProvider>
          <Suspense fallback={null}>
            <PostHogPageView />
          </Suspense>
          {children}
        </NextHogProvider>
      </body>
    </html>
Enter fullscreen mode Exit fullscreen mode

in the next.config.mjs

/** @type {import('next').NextConfig} */
// next.config.js

const nextConfig = {
  async rewrites() {
    return [
      {
        source: "/ingest/:path*",
        destination: "https://app.posthog.com/:path*", // Proxy to PostHog cloud service
      },
    ];
  },
};

export default nextConfig;

Enter fullscreen mode Exit fullscreen mode

This is done to prevent the request being blocked by client

Image of Wix Studio

2025: Your year to build apps that sell

Dive into hands-on resources and actionable strategies designed to help you build and sell apps on the Wix App Market.

Get started

Top comments (0)