Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listen to route change with next.js to use with matomo/piwik

I'm trying to listen to route changes on a next.js app, in order to log navigation to matomo (aka piwik). According to next.js' documentation, I have to do something like this:

Router.events.on('routeChangeStart', url => {
  // Do something
});

Where do I have to use this code in my app in order to log all the route change events?

("where" means in which file/class/method)

like image 402
rap-2-h Avatar asked Jan 30 '19 14:01

rap-2-h


People also ask

Can I use react router in next js?

Next. js ships with its own built-in page-based routing system, whereas the typical SPA relies on client-side routing, typically using a library like react-router.

Does NextJs use client-side routing?

The Next. js router allows you to do client-side route transitions between pages, similar to a single-page application. A React component called Link is provided to do this client-side route transition.


Video Answer


2 Answers

You have to add it in pages/_app.js, in the componentDidMount method:

componentDidMount() {
  Router.events.on("routeChangeStart", url => {
    if (window && window._paq) {
      window._paq.push(["setCustomUrl", url]);
      window._paq.push(["setDocumentTitle", document.title]);
      window._paq.push(["trackPageView"]);
    }
  });
}

Don't forget to initialize it in your base page (i.e. your Layout or something like that):

<!-- Matomo -->
<script type="text/javascript">
  var _paq = window._paq || [];
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="//{$PIWIK_URL}/";
    _paq.push(['setTrackerUrl', u+'piwik.php']);
    _paq.push(['setSiteId', {$IDSITE}]);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
  })();
</script>
<!-- End Matomo Code -->
like image 137
rap-2-h Avatar answered Oct 17 '22 09:10

rap-2-h


I got it to work like this

LayoutDefault.js

import NextHead from 'next/head'

export default function LayoutDefault() {
return (
    <div>
        <NextHead>
            …
            <script dangerouslySetInnerHTML={{ __html: `
                console.log('Matomo Component')

                var _paq = window._paq = window._paq || [];
                _paq.push(['trackPageView']);
                _paq.push(['enableLinkTracking']);
                (function() {
                    var u="{$MATOMO_URL}";
                    _paq.push(['setTrackerUrl', u+'matomo.php']);
                    _paq.push(['setSiteId', {$IDSITE}]);
                    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
                    g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
                })();
            ` }} />
        </NextHead>
    </div>
)
}

_app.js

import { useEffect } from 'react'
import { useRouter } from 'next/router'

export default function MyApp({ Component, pageProps }) {
const router = useRouter()

useEffect(() => {
    const handleRouteChange = (url) => {
        if (window && window._paq) {
            _paq.push(['setCustomUrl', url]);
            _paq.push(['setDocumentTitle', document.title]);
            _paq.push(['trackPageView']);
        }
    }

    router.events.on('routeChangeStart', handleRouteChange)
}, [])

return <Component {...pageProps} />
}
like image 32
larswittenberg Avatar answered Oct 17 '22 08:10

larswittenberg