Skip to content

SocialGouv/matomo-next

Repository files navigation

Matomo Next

Matomo analytics for Next.js applications

Github Master CI Build Status License: Apache-2.0 GitHub release (latest SemVer) Npm version codecov


A lightweight, TypeScript-ready Matomo analytics integration for Next.js applications with support for both Pages Router and App Router.

Features

  • Pages Router & App Router Support - Works with both Next.js routing systems
  • Automatic Page Tracking - Tracks route changes and page views automatically
  • Search Tracking - Built-in search query tracking
  • GDPR Compliant - Cookie-less tracking option
  • Custom Events - Type-safe event tracking API
  • Heatmap & Session Recording - Optional user behavior visualization
  • TypeScript Support - Full type safety and auto-completion

Installation

npm install @socialgouv/matomo-next

Quick Start

Pages Router

Add the trackPagesRouter() call in your _app.js:

import { useEffect } from "react";
import { trackPagesRouter } from "@socialgouv/matomo-next";

const MATOMO_URL = process.env.NEXT_PUBLIC_MATOMO_URL;
const MATOMO_SITE_ID = process.env.NEXT_PUBLIC_MATOMO_SITE_ID;

function MyApp({ Component, pageProps }) {
  useEffect(() => {
    trackPagesRouter({ url: MATOMO_URL, siteId: MATOMO_SITE_ID });
  }, []);

  return <Component {...pageProps} />;
}

export default MyApp;

App Router

Create a client component for tracking with trackAppRouter():

"use client";

import { trackAppRouter } from "@socialgouv/matomo-next";
import { usePathname, useSearchParams } from "next/navigation";
import { useEffect } from "react";

const MATOMO_URL = process.env.NEXT_PUBLIC_MATOMO_URL;
const MATOMO_SITE_ID = process.env.NEXT_PUBLIC_MATOMO_SITE_ID;

export function MatomoAnalytics() {
  const pathname = usePathname();
  const searchParams = useSearchParams();

  useEffect(() => {
    trackAppRouter({
      url: MATOMO_URL,
      siteId: MATOMO_SITE_ID,
      pathname,
      searchParams,
    });
  }, [pathname, searchParams]);

  return null;
}

Add it to your root layout wrapped in a Suspense boundary:

import { Suspense } from "react";
import { MatomoAnalytics } from "./matomo";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Suspense fallback={null}>
          <MatomoAnalytics />
        </Suspense>
      </body>
    </html>
  );
}

Documentation

Common Use Cases

Track Custom Events

Use the sendEvent() helper for type-safe event tracking:

import { sendEvent } from "@socialgouv/matomo-next";

// Track a button click
sendEvent({ category: "contact", action: "click phone" });

// Track with additional context
sendEvent({
  category: "video",
  action: "play",
  name: "intro-video",
  value: "120",
});

Configuration Options

Option Type Description Default Docs
url string Matomo instance URL - Required
siteId string Matomo site ID - Required
pathname string Current pathname (App Router only) - Required for App Router
searchParams URLSearchParams URL search params (App Router only) - Required for App Router
jsTrackerFile string Custom JS tracker filename "matomo.js" Advanced
phpTrackerFile string Custom PHP tracker filename "matomo.php" Advanced
excludeUrlsPatterns RegExp[] URLs to exclude from tracking [] Advanced
disableCookies boolean Cookie-less tracking false Advanced
cleanUrl boolean Remove query params from URLs false Advanced
searchKeyword string Search query parameter name "q" Advanced
searchRoutes string[] Custom search route paths ["/recherche", "/search"] Advanced
enableHeartBeatTimer boolean Track time on page false Advanced
heartBeatTimerInterval number HeartBeat timer interval (seconds) 15 (Matomo default) Advanced
enableHeatmapSessionRecording boolean Enable session recording false Heatmap
heatmapConfig HeatmapConfig Heatmap configuration object {} Heatmap
debug boolean Enable debug logs false Advanced
nonce string CSP nonce value - Security
trustedPolicyName string Trusted Types policy name "matomo-next" Security
onInitialization () => void Callback on init - Advanced
onRouteChangeStart (path) => void Callback on route change start - Advanced
onRouteChangeComplete (path) => void Callback on route change complete - Advanced
onScriptLoadingError () => void Callback on script loading error - Advanced

See complete configuration options for full details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Links