To add on top of other answers: You should use the routeChangeComplete event over routeChangeStart in order to get the correct data - with routeChangeStart you will get the page title/url of the previous page.
Complete solution:
_app.js as a functional component:
import { useRouter } from 'next/router'
import { useEffect } from 'react'
export default function App({ 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('routeChangeComplete', handleRouteChange)
}, [])
return (
//your code
)
}
layout.js:
import Head from 'next/head'
export default function Layout({ children }) {
return (
<>
<Head>
<script type="text/javascript" dangerouslySetInnerHTML={{__html: `
var _paq = window._paq = window._paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//<YOUR_MATOMO_URL>";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '1']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
`}} />
</Head>
//your code
</>
)
}
Alternatively you can use Script from next/script and enclose the js within instead.