I want to load a script only on certain pages. Next.js recommends using next/script tag for it.
However, when I navigate to some different pages I can still see the script present at the end of body in HTML.
import Script from "next/script";
const Comments = () => {
return (
<div className="giscus mt-16">
<Script
src="https://giscus.app/client.js"
data-repo="GorvGoyl/Personal-Site-Gourav.io"
data-repo-id="MDEwOlJlcG9zaXRvcnkyOTAyNjQ4MTU="
data-category="Announcements"
data-category-id="DIC_kwDOEU0W784CAvcn"
data-mapping="pathname"
data-reactions-enabled="0"
data-emit-metadata="0"
data-theme="light"
data-lang="en"
crossOrigin="anonymous"
strategy="lazyOnload"
onError={(e) => {
console.error("giscus script failed to load", e);
}}
></Script>
</div>
);
};
I suspect Next.js is not cleaning up the script on route change action. How do I make sure that scripts get removed on page change?
I was facing the same problem. Only solution that works for me is to reload the page as the routeChangeStart. I also made it in a custom Hook so can be reused with ease.
import { useRouter } from "next/router";
import { useEffect } from "react";
export default function useScript(url) {
const router = useRouter();
useEffect(() => {
const script = document.createElement("script");
script.src = url;
script.async = true;
document.body.appendChild(script);
// Needed for cleaning residue left by the external script that can only be removed by reloading the page
const onRouterChange = () => {
router.reload();
};
router.events.on("routeChangeStart", onRouterChange);
return () => {
router.events.off("routeChangeStart", onRouterChange);
document.body.removeChild(script);
};
}, [router]);
}
import useScript from "../utils/useScript"
export default function index(){
useScript("<script-ulr>");
}