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

Prompting user to reload when the site has been updated #20972

Open
3 of 4 tasks
edwh opened this issue May 20, 2023 · 10 comments
Open
3 of 4 tasks

Prompting user to reload when the site has been updated #20972

edwh opened this issue May 20, 2023 · 10 comments

Comments

@edwh
Copy link
Contributor

edwh commented May 20, 2023

Describe the feature

Apologies if I've missed a feature which does this.

Some users will load a site and then have it sit in an open tab for days. Meanwhile, the site may be changing under their feet, perhaps with important fixes which they won't pick up.

Sometimes it would be good if the user was prompted to "reload when convenient"; more rarely it would be good if the site did a hard refresh under their feet.

It would be possible to roll my own code for this - for example Netlify has an API end point which I could poll to see if the deploy_id has changed since the build which the code is currently running.

But this might be of wider interest, including in other deployment environments, so I'm opening this for discussion.

Additional information

  • Would you be willing to help implement this feature?
  • Could this feature be implemented as a module?

Final checks

@warflash
Copy link
Member

I recommend checking out #19086 and https://nuxt.com/docs/getting-started/error-handling#errors-downloading-js-chunks, perhaps those can accomplish what you're looking for already

@maou-shonen
Copy link

You might want to learn about PWA

@edwh
Copy link
Contributor Author

edwh commented May 20, 2023

@warflash I'm already commenting on #19086. I'm not talking here about the case where there are issues downloading chunks after new deploys. I'm talking about the opposite case where you have downloaded everything you need and just sit there using the site. So the default nuxt behaviour of reloading on chunk errors, or the kinds of variations discussed in #19806, will never kick in.

But meanwhile the site has moved on, and unless you refresh the page you won't notice. I'm suggesting that most if not all Nuxt apps would benefit from a built-in mechanism to spot that.

@maou-shonen I could be wrong, but I don't think PWAs affect this significantly. You can roll your own PWA updating mechanism (e.g. https://stackoverflow.com/questions/59708511/how-to-update-a-pwa-when-has-been-already-installed) but I don't think that you get one for free.

@killjoy1221
Copy link

Here's a primitive update mechanism that uses the build time to check for changes.

// nuxt.config.ts
export defaultNuxtConfig({
  appConfig: {
    buildTimestamp: Date.now()
  }
})
// server/api/updateCheck.ts
export default defineEventHandler(() => {
  buildTimestamp: useAppConfig().buildTimestamp
})
<!-- app.vue -->
<script setup lang="ts">
const updateExists = ref(false)

onMounted(() => {
  const config = useAppConfig()
  const updateTimer = setInterval(async () => {
    try {
      const { buildTimestamp } = await $fetch("/api/updateCheck", {
        signal: AbortSignal.timeout(5000)
      })
      if (config.buildTimestamp !== buildTimestamp) {
        updateExists.value = true
        clearInterval(updateTimer)
        // or forcibly reload via reloadNuxtApp()
      }
    } catch {
      // ignore
    }
  }, 1000 * 60 * 30) // 30 minutes
})

function refreshApp() {
  reloadNuxtApp()
}
</script>
<template>
  <div v-if="updateExists">
    There is an update. <a @click="refreshApp">Click Here</a> to reload.
  </div>
</template>

@manniL
Copy link
Member

manniL commented Jun 5, 2023

This is definitely on the list of desired features but is important to discuss how to implement the detection.
I linked #21370 as one possible way to go for it.

@lwpinion
Copy link
Contributor

Some users will load a site and then have it sit in an open tab for days. Meanwhile, the site may be changing under their feet, perhaps with important fixes which they won't pick up.

This is me, so I'm glad to see that others are trying to research the best way to tackle this. I am very guilty about leaving tabs open in general, but this habit of mine really bites me in the butt with the documentation for most (if not all) sites across the Vue ecosystem. I'll go to look something up in my open tab and realize the page is not working for some reason.

As a developer, I am obviously capable of realizing that I just need to refresh the page, but your average user may not necessarily know that (and honestly it's just not great UX regardless of the user's skill). As we are currently working through a re-write of our site with Nuxt, these sort of issues are at the forefront of my mind.

Again, thanks for addressing this!

@bogdanciuca
Copy link

Has anyone figured out a solution to properly update a PWA? It seems to need 2-3 calls to reloadNuxtApp().

@killjoy1221
Copy link

With the update to Nuxt 3.8.0, we can now use the app:manifest:update hook.

const nuxtApp = useNuxtApp()
const updateAvailable = ref(false)

nuxtApp.hook("app:manifest:update", () => {
  updateAvailable.value = true
})

Additionally, the update will be applied automatically seamlessly when you navigate to another page. Unfortunately, the update check interval is hard-coded for 1 hour.

@bogdanciuca
Copy link

@killjoy1221 thanks for sharing this! Too bad that interval is hard-coded...

I already have a realtime mechanism to prompt for updates (packageJSON.version against DB data). However, even after a reloadNuxtApp() the user still gets outdated content, probably cached by the SW. After 20-30 seconds, the app reloads again by itself, finally "updating" to latest version. This might be better related to https://github.com/vite-pwa/nuxt though.

@edwh
Copy link
Contributor Author

edwh commented Jan 18, 2024

With the update to Nuxt 3.8.0, we can now use the app:manifest:update hook.

Close but no cigar, for me.

I'm already using this approach to avoid missing chunks:

  // This makes Netlify serve assets from the perm link for the build, which avoids missing chunk problems when
  // a new deploy happens.  See https://github.com/nuxt/nuxt/issues/20950.
  $production: {
    app: {
      cdnURL: process.env.DEPLOY_URL
        ? '/netlify/' + process.env.DEPLOY_URL.replace('https://', '')
        : '',
    },
  },

Unfortunately (for me) I think the check of the build manifest then picks up that modified base:

const meta = await $fetch(buildAssetsURL("builds/latest.json"));

...which means that the poll of the manifest keeps polling the old build, and therefore thinks that the build hasn't been updated.

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

No branches or pull requests

8 participants