NextJS

How to Hook into NextJS Router Events

March 3, 2023 1:36 PM


Sometimes when using NextJS' built in router you want to run some code for every navigation between pages. Normally in pure HTML + JS, this could be done via a simple script tag, which would cause the javascript within the tag to be re-ran every time the page loads. NextJS' Router, on the other hand, allows for client-side routing between pages much like a stock React app using ReactRouter. This means that inline scripts defined in a route won't be re-evaluated on subsequent page loads, because the NextJS router isn't really reloading the page in the traditional sense.

There's a few ways around this issue:

Use a Route Change Hook (for running on every page)

NextJS exposes various hooks within its routing system. For example, I've used this codeblock in the past to run a function "mt" for tracking page views on every page navigation within NextJS:

function MyApp({ Component, pageProps, router }) {
  useEffect(() => {
    const handleRouteChange = url => {
      {/* Mautic tracking */}
      mt('send', 'pageview');
    };
    router.events.on('routeChangeComplete', handleRouteChange);
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, []);
  ...

This code hooks into the routeChangeComplete event, which fires any time the NextJS router moves to another page.

Use a React useEffect hook (running on certain pages only)

Another option is to just use the React useEffect() hook. Something like the following would run the desired code when the page component is loaded:

function Page() {
  useEffect(() => {
    // code here
  }, []);
  ...