<script> tag not working on page change, only on initial load and reload #17919
-
Hello, I have 2 3rd party script tags in _document.js. The script interacts with divs on the page based on classNames. The script works perfectly on the initial load but stops working if I navigate to other pages. If I refresh the page, the script starts working again. This is an ongoing issue: #4477 Anyway to get the script tag to work on page change? |
Beta Was this translation helpful? Give feedback.
Replies: 17 comments 48 replies
-
Hi @junaid33. Do you happen to have an example of what you are seeing? This sounds similar to another issue where |
Beta Was this translation helpful? Give feedback.
-
I found a solution to UET. It seams to work, but please test yourself. This principle may apply to other scripts as well. The solution in nextjs was adding this to <script id="uetq">{`(function(w,d,t,r,u){....);`}</script> and fire a page load event, when the page changes. export default function MyApp({ Component, pageProps }) {
useEffect(() => {
// uet
if (typeof window !== "undefined" && window.uetq.push) {
window.uetq = window.uetq || [];
window.uetq.push("event", "page_view", {
page_path: pageProps.page.path,
});
}
}, [pageProps.page])
...
} |
Beta Was this translation helpful? Give feedback.
-
You can use useEffect to listen for the routeChangeComplete event and and reload (or load the portion you want loaded again) the script. Solved my issue 100% Edit the _app.js file adding the following:
Source of inspiration for this fix: https://stackoverflow.com/questions/68389552/how-to-access-the-url-or-page-that-is-currently-loading-on-navigation-with-next/68415175#68415175 NextJs developers should modify the <Script> loading library to add a strategy that will allow a new option something like onRouteChange that'll allow you to easily load a script when router path change event occur - this is a huge oversight and forcing lots of devs to give up using lib (which sucks because it actually is a nice thing that speeds up page loads). |
Beta Was this translation helpful? Give feedback.
-
I found a solution that I can wrap your component in a HOC called withScript(Component, dir, ...srcs), which makes use of
Now you just have to import
Maybe its not an elegant solution, but it seems to serve the need for now. Maybe I can improve it so that it wont call |
Beta Was this translation helpful? Give feedback.
-
This is the workaround to get
|
Beta Was this translation helpful? Give feedback.
-
Some proposed solutions work when refreshing a page in a browser, but not when navigating between the pages. That is still an issue and has been a problem for nearly 2 years. |
Beta Was this translation helpful? Give feedback.
-
I solved it this way.
|
Beta Was this translation helpful? Give feedback.
-
You can give unique url for every render.
You can use this hook also.
|
Beta Was this translation helpful? Give feedback.
-
I've tried all the options and so far no results. Even mount and unmount Head with scripts. I don't want to remove Link component from the site because we are losing our speed advantage. Maybe someone will help. My case is displaying embedded posts from facebook and twitter. The principle is the same, connect next/script and subscribe to router event. The thing is, most of the scripts have a reload function in the documentation, so we call them when the route changes.
|
Beta Was this translation helpful? Give feedback.
-
Unfortunately it seems like it's still an issue. I built a custom to hook for it and wrote a blog post about it for further explanation. Hopefully it helps someone. The hook looks like this:
|
Beta Was this translation helpful? Give feedback.
-
External <script> runs only on page load, not on page update. async and defer just for performance. To run the script on soft SPA you need to have some global bootstrap functions like window.init() in the script. You need to run bootstrap functions on script load. Full script cannot be run in soft SPA. |
Beta Was this translation helpful? Give feedback.
-
Necro'ing this thread to confirm it's still an issue in |
Beta Was this translation helpful? Give feedback.
-
Has anyone found a solution? |
Beta Was this translation helpful? Give feedback.
-
Found a solution Create a scripts loaded component `import React, { useEffect, useRef } from 'react'; const ScriptLoaded = () => { useEffect(() => {
}, []); return ;
}; export default ScriptLoaded; import the component in _app.js `// pages/_app.js import 'public/static/vendors/liquid-icon/liquid-icon.min.css'; function MyApp({ Component, pageProps }: AppProps) { export default MyApp; |
Beta Was this translation helpful? Give feedback.
-
I have been running into this issue when loading iframes from external scripts such as a ticket buyer at DICE events and a SweepStakes iframe script from SweepWidget. This makes the <Script /> tag almost unusable on production because it gives such a terrible UX... none of the fixes above seem straight forward and I am worried it would just cause more issues. Currently my solution is to just present a button to reload the page if the user doesn't see anything. Would love to get the Script feature working properly with Next.js 13! |
Beta Was this translation helpful? Give feedback.
-
I faced the same issue while I was implementing the AfterShip tracking widget. Here's the solution that worked for me:
|
Beta Was this translation helpful? Give feedback.
-
When using Next app router and server rendered components, I found this approached fixed the issue:
Mini example which fetches data server side: // Page.tsx
async function getData(): Promise<any> {
const data = await fetch(...)
return data
}
export default async function MyPage() {
const data = await getData();
return (
<div>
<div>
<MyScriptComponent />
</div>
</div>
);
}
// MyScriptComponent.tsx
'use client';
import Script from 'next/script';
export const MyScriptEmbed = () => {
return (
<div>
<div id="myEmbedDiv"></div>
<Script src={'path/or/url/to/script.js?v=' + Math.random() * 999} />
</div>
);
}; |
Beta Was this translation helpful? Give feedback.
Hi @junaid33. Do you happen to have an example of what you are seeing?
This sounds similar to another issue where
dangerouslySetInnerHTML
was not working properly when doing client side navigation due to the manner in whichdangerouslySetInnerHTML
works: #17346 (reply in thread)