vite-pwa / vite-plugin-pwa

Zero-config PWA for Vite
https://vite-pwa-org.netlify.app/
MIT License
3.23k stars 211 forks source link

registerSW.js do not gets added in generated index.html file #85

Closed chavda-bhavik closed 3 years ago

chavda-bhavik commented 3 years ago

Thanks for this plugin. I'm using this plugin with react. When I build the app the generated index.html file is missing registerSW.js as a script.

vite.config.js

import { defineConfig } from 'vite';
import reactRefresh from '@vitejs/plugin-react-refresh';
import tsconfigPaths from 'vite-tsconfig-paths';
import { VitePWA } from 'vite-plugin-pwa';

// https://vitejs.dev/config/
export default defineConfig({
    build: {
        brotliSize: false,
    },
    plugins: [
        tsconfigPaths(),
        reactRefresh(),
        VitePWA({
            registerType: 'prompt',
            workbox: {
                cleanupOutdatedCaches: true,
                clientsClaim: true,
                skipWaiting: true,
                navigateFallback: undefined,
            },
            manifest: {
                name: 'App',
                short_name: 'App',
                display: 'fullscreen',
                theme_color: '#EDEDE5',
                icons: [
                    {
                        src: '/icon_512x512.png',
                        sizes: '512x512',
                        type: 'image/png',
                    },
                ],
            },
        }),
    ],
});

Here is the index.html that is being generated in dist folder

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Vite App</title>
        <script type="module" crossorigin src="/assets/index.bce22a61.js"></script>
        <link rel="modulepreload" href="/assets/vendor.95506056.js" />
        <link rel="stylesheet" href="/assets/index.940d6da2.css" />
        <link rel="manifest" href="/manifest.webmanifest" />
    </head>
    <body>
        <div id="root"></div>
    </body>
</html>

But index.html file should be like,

<!DOCTYPE html>
<html lang="en">
    <head>
        ....
        <link rel="manifest" href="/manifest.webmanifest" />
        <script src="/registerSW.js"></script> <== missing
    </head>
   ...
</html>

Am I missing something?

userquin commented 3 years ago

@chavda-bhavik read the docs: here you can find what's your're asking for, see warning there.

kutsan commented 3 years ago

@userquin Care to explain again since that link is broken now. I'm having the same problem. Do I need to call registerSW in my code or is it going to be injected automatically?

userquin commented 3 years ago

@kutsan read de docs on netlify app, you have a link on readme file

kutsan commented 3 years ago

@userquin I've asked that question after reading the docs actually. It's not actually clear how am I going to register generated service worker. Generate Service Worker section isn't speaking of about this and Prompt for new content refreshing section is saying This is the default option when strategies and registerType are not configured. (and it's not set in my config) with a registerSW code snippet. So, maybe I missed something.

userquin commented 3 years ago

@kutsan You need to import virtual module and then call registerSW or useRegiterSW , see the code for prompt for update on vue

https://vite-plugin-pwa.netlify.app/frameworks/vue.html

userquin commented 3 years ago

Or on react

userquin commented 3 years ago

You can also see on examples directory on this repo 3 examples for react

kutsan commented 3 years ago

What I'm actually having trouble with is I don't actually want to handle onRegistered and onRegisterError such events and I do not want to use offlineReady etc. states. It's okay to just inject registerSW.js script to register service worker for me. Do I need to call useRegisterSW hook with no arguments or is there anything should I using for this behaviour? Adding <script defer src="/registerSW.js"></script> in index.html solves the problem but I'm not sure whether or not I should be using it like this. Thanks.

userquin commented 3 years ago

@kutsan all sutff are optional, if you don't want such functionality just don't add it. If you are using prompt for update you should interact with the ui, the only way to do that is using the react virtual module (or vanilla js) on your built-in component with proper callbacks as described on docs.

If you inject manually the registerSW.js (this is not the virtual, is just the logic to register the sw on browser manually), then there will not be interaction with the ui, and so when the new sw will be available the new sw will keep on skip waiting state, and will keep in this state since nobody can emit the event to install the new version (the event to trigger the update will be on reload button prompt, and since you are not showing it...)

userquin commented 3 years ago

@kutsan take a look at this example: https://github.com/antfu/vite-plugin-pwa/tree/main/examples/react-basic

userquin commented 3 years ago

@kutsan just use this on your buit-in component:

// eslint-disable-next-line no-use-before-define
import React from 'react'
import './ReloadPrompt.css'

import { useRegisterSW } from 'virtual:pwa-register/react'

function ReloadPrompt() {

  const {
    offlineReady: [offlineReady, setOfflineReady],
    needRefresh: [needRefresh, setNeedRefresh],
    updateServiceWorker,
  } = useRegisterSW()

  const close = () => {
    setOfflineReady(false)
    setNeedRefresh(false)
  }

  return (
    <div className="ReloadPrompt-container">
      { (offlineReady || needRefresh)
          && <div className="ReloadPrompt-toast">
            <div className="ReloadPrompt-message">
              { offlineReady
                ? <span>App ready to work offline</span>
                : <span>New content available, click on reload button to update.</span>
              }
            </div>
            { needRefresh && <button className="ReloadPrompt-toast-button" onClick={() => updateServiceWorker(true)}>Reload</button> }
            <button className="ReloadPrompt-toast-button" onClick={() => close()}>Close</button>
          </div>
      }
    </div>
  )
}
export default ReloadPrompt
userquin commented 3 years ago

and don't forget to add on you main.tsx or App.tsx (add also the ReloadPrompt.css), you can see it on basic example linked on previous entry.

userquin commented 3 years ago

the old read link can be found here: https://github.com/antfu/vite-plugin-pwa/blob/8c7ec04f1d112a0d92d7dfa25082ff64af1041cd/README.md#prompt-for-new-content

kutsan commented 3 years ago

Thank you so much @userquin and sorry for the late response, I hadn't had time to check this out but now I did and it's working as you described.