Прослушайте изменение маршрута с помощью next.js для использования с matomo/piwik
Я пытаюсь прослушать изменения маршрута в приложении next.js, чтобы регистрировать навигацию в matomo (он же piwik). Согласно документации next.js, я должен сделать что-то вроде этого:
Router.events.on('routeChangeStart', url => {
// Do something
});
Где я должен использовать этот код в своем приложении, чтобы регистрировать все события изменения маршрута?
("где" означает, в каком файле / классе / методе)
4 ответа
Вы должны добавить его в pages/_app.js
, в componentDidMount
метод:
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"]);
}
});
}
Не забудьте инициализировать его на своей базовой странице (т.е. в макете или что-то в этом роде):
<!-- 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 -->
у меня так работает
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} />
}
Чтобы добавить поверх других ответов: вы должны использовать событие routeChangeComplete поверх routeChangeStart, чтобы получить правильные данные - с помощью routeChangeStart вы получите заголовок/URL страницы предыдущей страницы.
Полное решение:
_app.js как функциональный компонент:
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
</>
)
}
В качестве альтернативы вы можете использовать скрипт из next/script и вместо этого вложить js.
@rap-2-h ответ отлично сработал. Для включения сценария на вашу базовую страницу вы можете включить сценарий matomo какdangerouslySetInnerHTML
внутри next.js <Head>
компонент вроде этого:
//import next had
import Head from 'next/head'
export default class Meta extends Component {
render() {
return (
<Head>
<script type="text/javascript" dangerouslySetInnerHTML={{
__html: ` var _paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function () {
var u = "https://your_matomo_link";
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', '1']);
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 + 'matomo.js'; s.parentNode.insertBefore(g, s);
})();
`}} />
</Head>
)
}
}
Затем добавьте его вверху макета или где угодно