Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto reload page when chunk assets are not found #14594

Closed
pi0 opened this issue Aug 15, 2022 · 28 comments · Fixed by #19038
Closed

Auto reload page when chunk assets are not found #14594

pi0 opened this issue Aug 15, 2022 · 28 comments · Fixed by #19038

Comments

@pi0
Copy link
Member

pi0 commented Aug 15, 2022

References: #14591

We had this feature in Nuxt 2. Basically what happens is with a new deployment, hashes of old js chunks will be changed. And if users already loaded the page with manifest and chunks of the last deployment, they fail when navigating on client-side that tries to load dynamic chunks.

There are several ways to resolve this issue but probably the safest and easiest, is that same as Nuxt 2 we make use of a global error handler that identifies such errors and reload pages. (Note for implementation: We should set a LocalStorage key to avoid infinity page reloads)

Bonus: We could new offer a new nuxtApp hook such as app:chunkError that allows graceful HMR alike handling by end-user.

@KahrLu
Copy link

KahrLu commented Aug 15, 2022

Hi @pi0 , it's great!
btw, this brings me to another issue that is being discussed. https://github.com/nuxt/framework/discussions/6553

There are several ways to resolve this issue but probably the safest and easiest, is that same as Nuxt 2 we make use of a global error handler that identifies such errors and reload pages. (Note for implementation: We should set a LocalStorage key to avoid infinity page reloads)

I see your train of thought is somewhat similar to mine in 6553. However, the effect of that code is not good, because the user will first see the outdated interface, and then refresh for 1 second to show the latest interface.
Do you have some good idea?

@KahrLu
Copy link

KahrLu commented Aug 17, 2022

I hope to raise the priority of this function, For any enterprise adopting nuxt in the production environment, they does not want to see a page with all styles lost when the user opens the browser for the first time after each new deployment.
Thanks @pi0

@warflash
Copy link
Member

Hey, any news on this or perhaps a temporary workaround? Vercel in particular is annoying as they seemingly don't store old chunks at all which results in them being interpreted as function calls...

@tylerforesthauser
Copy link

I'm so glad this has come up again! I didn't realize it had been mentioned before because I've actually just discovered this issue and it has caused a huge pain for me and my users. Getting some eyes on this issue would be hugely appreciated 🙏

@tylerforesthauser
Copy link

Hey guys, I just wanted to check in on this. Is there any way to expedite a solution (or even a workaround)? Thank you very much 🙏

@shiva-prasad-reddy
Copy link

Hey guys, for my use case the following solution is working, hoping for a better and offical way to do this sooner.

const router = useRouter();
router.onError((error) => {
  const messages = [
    "Importing a module script failed", // safari
    "Failed to fetch dynamically imported module", // edge & chrome
  ];
  if (messages.some((message) => error?.message.includes(message))) {
    (async () => {
      // show some notification to the user if you want too.
      // add some delay so that user can read the message in notification.
      router.go(0);
    })();
  }
});

@jmverges
Copy link

@shiva-prasad-reddy where do you put that? I'm trying with your code but no luck yet

@shiva-prasad-reddy
Copy link

shiva-prasad-reddy commented Nov 17, 2022

@jmverges In app.vue

@jmverges
Copy link

thanks @shiva-prasad-reddy it is halfworking now for me.
Somehow action links are cached by onError but links like href="/contacts"
image
are silently failing. Any clue?

@shiva-prasad-reddy
Copy link

thanks @shiva-prasad-reddy it is halfworking now for me. Somehow action links are cached by onError but links like href="/contacts" image are silently failing. Any clue?

Which rendering mode are you using ?

@toooni
Copy link
Sponsor

toooni commented Nov 22, 2022

Thank you @shiva-prasad-reddy !
I made a plugin out of it, which works even if it's not a lazy page but a lazy component like a modal or whatever:

export default defineNuxtPlugin((nuxtApp) => {
  const checkError = (error) => {
    const messages = [
      "Importing a module script failed", // safari
      "Failed to fetch dynamically imported module", // edge & chrome
    ];
    if (messages.some((message) => error?.message.includes(message))) {
      (async () => {
        await alert("TODO: warning text here that the page will be refreshed");
        nuxtApp.$router.go(0);
      })();
    }
  };

  const errorHandler = nuxtApp.vueApp.config.errorHandler;

  nuxtApp.vueApp.config.errorHandler = (err, instance, info) => {
    if (typeof errorHandler === "function") {
      errorHandler.call(err, instance, info);
    }

    checkError(err);
  };

  nuxtApp.$router.onError((error) => {
    checkError(error);
  });
});

EDIT: I've added calling of already existing error handlers

@jmverges
Copy link

@shiva-prasad-reddy Client Side Rendering Only

@toooni I put your plugin in place but I don't get it triggered

I'm doing npm run build && nuxi preview then I access to the page and I can navigate then I do npm run build && nuxi preview again and I can navigate to the pages that I already visited but when I click a link that I didn't visit I don't get any error or anything just silently fails.

Any clue here?

@toooni
Copy link
Sponsor

toooni commented Nov 22, 2022

@jmverges Also nothing in your browser console? Are you using an errorHandler somewhere else? I've realized that setting the errorHandler without calling the already set errorHandler might not be a good idea. I've added this in my code-

But you might have someplace else which overwrites vue.config.errorHandler?

@jmverges
Copy link

@toooni I can't find what is overwritting it but probably some 3rd party it is

@mcrapts
Copy link

mcrapts commented Jan 14, 2023

I used the solution by @shiva-prasad-reddy and it works. Thanks a lot! I hope Nuxt 3 will soon handle this out of the box, because now the default behavior is that Nuxt apps can easily end up in an unrecoverable crashed state without any feedback to the user.

@koronowicz
Copy link

It will be good to have information on which NuxtLink was clicked and then redirect to this URL when error occurs.

@jastaffen
Copy link

@danielroe thanks for pointing me to this issue! :) I mean this with all due respect, but how is this issue just a "p2-nice-to-have"? If I can't employ a CI/CD flow on a heavy traffic site with nuxt3 without worrying about this sort of issue that is a fairly large discrepancy between something baked into nuxt2 that's not present in nuxt3 and was not mentioned anywhere clearly in the documentation then why is this not a larger/greater priority issue? Perhaps I'm missing something very obvious here, but I'm just curious.

Copy link
Member

The label is a triaging system for bugs, so all enhancements are marked as p2. That doesn't reflect where an issue falls on our roadmap.

@jastaffen
Copy link

The label is a triaging system for bugs, so all enhancements are marked as p2. That doesn't reflect where an issue falls on our roadmap.

Ok thank you for the clarification. :) On a side note, I've really loved working with nuxt3 and despite this major issue I'm running into, I've found it a joy to develop with.

@danielroe danielroe self-assigned this Feb 14, 2023
@MDileg
Copy link

MDileg commented May 9, 2023

Hello Developers, I have a question, how are u using loading, during fetch data,

methods:{
async fetchHome() {
loading.setLoading(true);
// some fetching data ...
loading.setLoading(false);
} }

I am using like this but loading was false during fetching data, in nuxt3

@IlyaSemenov
Copy link

I keep old hashes on the CDN living for some time, but use a custom Nuxt module that detects app update and shows a notification suggesting to reload the page.

I have been using this approach for years (even since pre-bridge Nuxt 2) privately. Today I published the module as a reusable npm package: nuxt-update. Hope someone finds it useful, too. ✌️

@edwh
Copy link
Contributor

edwh commented Jun 8, 2023

Posting for anyone who finds this via Google. I've not opened a new issue because the on going work to add hooks like app:chunkError is probably the Nuxt solution.

I find that if I hammer at the refresh and cancel icons in my browser, I can reproduce similar errors, e.g. Failed to fetch dynamically imported module even in local dev. I think what may be happening is related to the cancellation of network requests that happens when a page is reloaded.

In that case Nuxt bombs out and ends up on my custom error page. It doesn't reload,. However you can spot the error in script setup of a custom error page, and trigger a reload there.

@TouchSek
Copy link

I keep old hashes on the CDN living for some time, but use a custom Nuxt module that detects app update and shows a notification suggesting to reload the page.

I have been using this approach for years (even since pre-bridge Nuxt 2) privately. Today I published the module as a reusable npm package: nuxt-update. Hope someone finds it useful, too. ✌️

Does it work with nuxt 2?

@nandi95
Copy link
Contributor

nandi95 commented Oct 2, 2023

So if I hook into the 'app:chunkError' then my plugin will be called after plugin 'nuxt:chunk-reload'? Meaning by the time I hook in, page errors have been handled by the automatic reload?

router.onError((error, to) => {
if (chunkErrors.has(error)) {
reloadAppAtPath(to)
}
})

If this isn't the case, what's the recommended way to handle chunk errors from lazy loaded components?

@danielroe

@nandi95
Copy link
Contributor

nandi95 commented Oct 11, 2023

It seems that this hook will be called on page chunk error too. How would I differentiate between lazy loaded components and pages?

Copy link
Member

@nandi95 Would you open a new issue with some suggestions or a reproduction if you're encountering a bug or something you can't achieve with the current approach?

@gurgenhakobyan
Copy link

I'm getting this error as well. And happens randomly, the error is not gone after hard reload. And it's the same in different browsers. It gets fixed after I make a different commit and deploy again. Any ideas?

@manniL
Copy link
Member

manniL commented Mar 28, 2024

@gurgenhakobyan please refer to the comment above yours

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.