When I use the <Link>
tag in NextJs to navigate between pages it doesn’t rerun my scripts after changing pages. It only runs the scripts after the first page load or when I press reload. When using plain <a>
tags instead, it works fine because the page reloads after each navigation. As far as I can tell this happens because the <Link>
tag makes it a Single-Page Application and doesn’t refresh the page when navigating between pages.
I would greatly appreciate anyway to have it rerun the scripts when navigating between pages or to have it refresh the page without using just plain <a>
tags and losing the Single-Page Application functionality.
This code doesn’t refresh the page
<Link href="/page1"> <a>Page 1</a> </Link> <Link href="/page2"> <a>Page 2 </a> </Link>
This code does refresh the page
<a href="/page1">Page 1</a> <a href="/page2">Page 2 </a>
I load in all my scripts using a scripts component
export default const MyScripts = () => { return ( <Script strategy="afterInteractive" type="module" src="/scripts/myScript.js" onReady={() => { console.log("Ready") }} /> ) }
One thing I’ve noticed is that the above onReady
function fires each time I change pages. Maybe someone knows how to run the myScript.js
from the onReady
.
Advertisement
Answer
Caution: The hack of using
history.pushState
will not work reliably, especially when DOM elements need to be fetched usingdocument.querySelector*
. Anyway, it’s also better to avoid hacks if you can.
I think the correct and clean way to do this is to use the useEffect
React hook (or componentDidMount
in class-based components).
This idea was proposed here: samplep182’s comment in: Normal scripts “” not working after page navigation · Issue #4477 · vercel/next.js
Simply move the Javascript code from your script
tag into a useEffect
block. Remove the script
tag and any script file as you no longer need them.
import { useEffect } from 'react'; export default const MyScripts = () => { useEffect(() => { // Paste the contents of /scripts/myScript.js here (and remove that file) }, []); }
Note that it’s recommended to have an empty array []
as the dependency list, to execute this on page load only.