plugin-web-update-notification icon indicating copy to clipboard operation
plugin-web-update-notification copied to clipboard

Detect webpage updates and notify user to reload. support Vite, Umijs, and Webpack.

English | 简体中文

plugin-web-update-notification

Gzip Size NPM Version License discussions-image

Detect webpage updates and notify user to reload. support vite, umijs and webpack.

Take the git commit hash( if not a git repository, use packaging time) as the version number, and write version into json file. The client polls the version of the server (visibilitychange event assistant), compares it with the local one, and if it is not the same, notifies the user to refresh the page.

When to check for updates (fetch version.json) ?

  1. first load page.
  2. poll (default: 10 * 60 * 1000 ms).
  3. script resource loading failure detected (404 ?).
  4. when the browser is refocus or revisible.

Why

Some users do not have the habit of closing web pages. If the front-end page is updated, the user page may report an error (file 404) or a white screen.

Install

# vite
pnpm add @plugin-web-update-notification/vite -D

# umijs
pnpm add @plugin-web-update-notification/umijs -D

# webpack plugin
pnpm add @plugin-web-update-notification/webpack -D

Usage

vite | umi | webpack

Vite

// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { webUpdateNotice } from '@plugin-web-update-notification/vite'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    webUpdateNotice({
      logVersion: true,
    }),
  ]
})
// vite.config.ts
export default defineConfig({
  plugins: [
    vue(),
    webUpdateNotice({
      // custom notification text
      notificationProps: {
        title: 'system update',
        description: 'System update, please refresh the page',
        buttonText: 'refresh',
      },
    }),
  ]
})
// vite.config.ts
export default defineConfig({
  plugins: [
    vue(),
    webUpdateNotice({
      // custom notification UI
      customNotificationHTML: `
        <div style="background-color: #fff;padding: 24px;border-radius: 4px;position: fixed;top: 24px;right: 24px;border: 1px solid;">
          System update, please refresh the page
        </div>
      `,
    }),
  ]
})
// hidden default notification, listener to update event custom behavior.
// vite.config.ts
export default defineConfig({
  plugins: [
    vue(),
    webUpdateNotice({
      hiddenDefaultNotification: true
    }),
  ]
})

// other file to listener custom update event
document.body.addEventListener('system_update_plugin_web_update_notification', (options) => {
  console.log(options)
  alert('System update!')
})

Umijs

// .umirc.ts
import { defineConfig } from 'umi'
import type { Options as WebUpdateNotificationOptions } from '@plugin-web-update-notification/umijs'

export default {
  plugins: ['@plugin-web-update-notification/umijs'],
  webUpdateNotification: {
    logVersion: true,
    checkInterval: 0.5 * 60 * 1000,
    notificationProps: {
      title: 'system update',
      description: 'System update, please refresh the page',
      buttonText: 'refresh',
    },
  } as WebUpdateNotificationOptions
}

webpack

// vue.config.js(vue-cli project)
const { WebUpdateNotificationPlugin } = require('@plugin-web-update-notification/webpack')
const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({
  // ...other config
  configureWebpack: {
    plugins: [
      new WebUpdateNotificationPlugin({
        logVersion: true,
      }),
    ],
  },
})

Options

function webUpdateNotice(options?: Options): Plugin

interface Options {
  /** polling interval(ms), default 10*60*1000 */
  checkInterval?: number
  /** whether to output commit-hash in console */
  logVersion?: boolean
  customNotificationHTML?: string
  notificationProps?: NotificationProps
  hiddenDefaultNotification?: boolean
  /** index.html file path, by default, we will look up path.resolve(webpackOutputPath, './index.html') */
  indexHtmlFilePath?: string // only webpack plugin support

  /**
   * Base public path for inject file, Valid values include:
   * * Absolute URL pathname, e.g. /foo/
   * * Full URL, e.g. https://foo.com/
   * * Empty string(default) or ./
   */
  injectFileBase?: string
}

interface NotificationProps {
  title?: string
  description?: string
  buttonText?: string
}

License

MIT