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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@cesnow/matomo-next

v1.0.5

Published

Matomo integration for next.js projects

Downloads

455

Readme

Matomo React

Standalone library for using Matomo tracking in Next.js projects. Originally forked from @datapunt/matomo-react and maxfahl/matomo-react.

Since my nextjs project requires matomo to be initialized after startup (standalone build), I forked the part of it that contains React specific logic. Most of the credit for this code belongs to the two projects mentioned above.

Installation

yarn add @cesnow/matomo-next

Usage

To use this you need to create a Matomo instance with your project specific details, and wrap your application with the MatomoProvider that this package exposes.

// ./src/app/layout.tsx

"use client";
import { Providers } from "./providers";
import { AppProvider } from "@/components/Providers/AppProvider";
import { MatomoProvider } from "@cesnow/matomo-next";

export default function RootLayout({children}: { children: React.ReactNode}) {
  return (
    <html suppressHydrationWarning lang="en">
    {/*
        <head /> will contain the components returned by the nearest parent
        head.js. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
      */}
    <head />

    <body>
      <MatomoProvider>
        <AppProvider>
          {children} 
        </AppProvider>
      </MatomoProvider>
    </body>
    </html>
  );
}

After the application is started, you can obtain the required environment variables (server, etc.) through other methods and set them inside MatomoProvider

// @/components/Providers/AppProvider.tsx
"use client";

import React, { useEffect } from "react";
import { createInstance, useMatomo } from "@cesnow/matomo-next";

export function AppProvider({ children }: { children: React.ReactNode }) {
  const { setInstance } = useMatomo();

  useEffect(() => {
    const instance = createInstance({
      urlBase: "https://LINK.TO.DOMAIN",
      siteId: 3,
      userId: "UID76903202", // optional, default value: `undefined`.
      trackerUrl: "https://LINK.TO.DOMAIN/tracking.php", // optional, default value: `${urlBase}matomo.php`
      srcUrl: "https://LINK.TO.DOMAIN/tracking.js", // optional, default value: `${urlBase}matomo.js`
      permanentTitle: "My Awesome App", // optional, always use this title for tracking, ignores document.title. Useful for SPAs.
      permanentHref: "/", // optional, always use this href for tracking, ignores window.location.href. Useful for SPAs.
      disabled: false, // optional, false by default. Makes all tracking calls no-ops if set to true.
      heartBeat: {
        // optional, enabled by default
        active: true, // optional, default value: true
        seconds: 10, // optional, default value: 15
      },
      linkTracking: false, // optional, default value: true
      configurations: {
        // optional, default value: {}
        // any valid matomo configuration, all below are optional
        disableCookies: true,
        setSecureCookie: true,
        setRequestMethod: "POST",
      },
    });
    setInstance(instance);
  }, []);

  return <></>;
}

After wrapping your application with the MatomoProvider you can use the useMatomo hook to track your application from anywhere within the MatomoProvider component tree:

import React from 'react'
import { useMatomo } from '@cesnow/matomo-next'

const MyPage = () => {
  const { trackPageView, trackEvent } = useMatomo()

  // Track page view
  React.useEffect(() => {
    trackPageView()
  }, [])

  const handleOnClick = () => {
    // Track click on button
    trackEvent({ category: 'sample-page', action: 'click-event' })
  }

  return (
    <button type="button" onClick={handleOnClick}>
      Click me
    </button>
  )
}

You can use isReady to confirm that the MatomoProvider is ready

import React from 'react'
import { useMatomo } from '@cesnow/matomo-next'

const MyPage = () => {
  const { isReady, trackPageView, trackEvent } = useMatomo()

  // Track page view
  React.useEffect(() => {
    if (!isReady) return;
    trackPageView();
  }, [isReady])

  const handleOnClick = () => {
    if (!isReady) return;
    // Track click on button
    trackEvent({ category: 'sample-page', action: 'click-event' })
  }

  return (
    <></>
  )
}

Advanced usage

By default we send the window's document title and location, or send your own values. Also, custom dimensions can be used:

import React from 'react'
import { useMatomo } from '@cesnow/matomo-next'

const MyPage = () => {
  const { trackPageView, trackEvent } = useMatomo()

  // Track page view
  React.useEffect(() => {
    trackPageView({
      documentTitle: 'Page title', // optional
      href: 'https://LINK.TO.PAGE', // optional
      customDimensions: [
        {
          id: 1,
          value: 'loggedIn',
        },
      ], // optional
    })
  }, [])

  const handleOnClick = () => {
    // Track click on button
    trackEvent({ category: 'sample-page', action: 'click-event' })
  }

  return (
    <button type="button" onClick={handleOnClick}>
      Click me
    </button>
  )
}

And you can do the same for the trackEvent method:

import React from 'react'
import { useMatomo } from '@cesnow/matomo-next'

const MyPage = () => {
  const { trackEvent } = useMatomo()

  const handleOnClick = () => {
    // Track click on button
    trackEvent({
      category: 'sample-page',
      action: 'click-event',
      name: 'test', // optional
      value: 123, // optional, numerical value
      documentTitle: 'Page title', // optional
      href: 'https://LINK.TO.PAGE', // optional
      customDimensions: [
        {
          id: 1,
          value: 'loggedIn',
        },
      ], // optional
    })
  }

  return (
    <button type="button" onClick={handleOnClick}>
      Click me
    </button>
  )
}

The useMatomo hook also exposes the following methods:

  • trackEvents()
  • trackSiteSearch()
  • trackLink()
  • pushInstruction()

For example, the pushInstruction() function can be used to push instructions to Matomo for execution. This is equivalent to pushing entries into the _paq array.

const { pushInstruction } = useMatomo()
pushInstruction('setUserId', 'USER_ID_HERE')

SPA Link Tracking

Matomo provides the option to track outbound link, however, this implementation is flaky for a SPA (Single Page Application) without SSR (Server Side Rendering) across different versions of Matomo. Therefore you can use the enableLinkTracking method to listen to outbound clicks on anchor elements. This method should be placed on a component directly below your MatomoProvider on a component that's rendered on every page view. Also, make sure to disable the linkTracking option on the instance passed to the provider to prevent Matomo from catching some link clicks:

import { MatomoProvider, createInstance, useMatomo } from '@cesnow/matomo-next'

const instance = createInstance({
  urlBase: "https://LINK.TO.DOMAIN",
});

ReactDOM.render(
  <MatomoProvider>
    <MyApp />
  </MatomoProvider>
)

const MyApp = () => {
  const { enableLinkTracking } = useMatomo()

  enableLinkTracking()

  return (
    // Render components
  )
}

References