npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@socialgouv/matomo-next

v1.13.1

Published

Matomo analytics integration for Next.js applications

Readme

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
  • A/B Testing - Built-in support for Matomo's A/B Testing plugin with React hooks
  • Server-Side Proxy - Bypass ad-blockers by routing tracking through your own domain
  • 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,
});

A/B Testing

Run experiments using Matomo's A/B Testing plugin. Pass your test definitions to the tracker and use the useABTestVariant() hook in your components:

// Pass abTests to the tracker
trackAppRouter({
  url: MATOMO_URL,
  siteId: MATOMO_SITE_ID,
  pathname,
  searchParams,
  abTests: [
    {
      name: "homepage-hero",
      percentage: 100,
      variations: [{ name: "original" }, { name: "new-hero" }],
    },
  ],
});
// In your component
import { useABTestVariant } from "@socialgouv/matomo-next";

export function HeroSection() {
  const variant = useABTestVariant("homepage-hero");

  if (variant === "new-hero") {
    return <NewHeroSection />;
  }
  return <OriginalHeroSection />;
}

See the A/B Testing documentation for scheduling, custom triggers, and advanced usage.

Server-Side Proxy

Bypass ad-blockers by routing Matomo requests through your own domain using withMatomoProxy():

By default, the public proxy endpoint is generated under your own API namespace: /api/{random}.

// next.config.mjs
import { withMatomoProxy } from "@socialgouv/matomo-next";

export default withMatomoProxy({
  matomoUrl: "https://analytics.example.com",
})(nextConfig);

matomoUrl is required here because it’s the server-side target the proxy forwards to (stored in MATOMO_PROXY_TARGET, not exposed to the browser).

// In your tracker component
import { trackAppRouter } from "@socialgouv/matomo-next";

// When the proxy is configured, calls are automatically routed through your own domain.
// This also hides the usual `matomo.js` / `matomo.php` filenames behind opaque build-time
// random names (some blockers match on those filenames).
trackAppRouter({ siteId: "1", pathname, searchParams });

See the Server-Side Proxy documentation for custom paths, chaining with other plugins, and security considerations.

Configuration Options

| Option | Type | Description | Default | Docs | | ------------------------------- | -------------------- | ----------------------------------------------------- | ---------------------------------------------- | --------------------------------------------------------- | | url | string | Matomo instance URL | - | Required unless using the server-side proxy | | siteId | string | Matomo site ID | - | Required | | useProxy | boolean | Prefer proxy (path + opaque filenames) when available | true | Server-side proxy | | 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" (or proxy-provided opaque name) | Advanced | | phpTrackerFile | string | Custom PHP tracker filename | "matomo.php" (or proxy-provided opaque name) | 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 | | abTests | ABTestDefinition[] | A/B test experiments to register | - | A/B Testing |

See complete configuration options for full details.

Contributing

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

Links