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.pushStatewill 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.