Vite react pwa allows a nice and simple way to show a PWA prompt to reload the app and run with latest service worker and assets.
Table of contents
Open Table of contents
PWA Update UI
you might have seen pwa update feature in some apps.
A screenshot from hoppscotch
Create a simple react pwa with vite
Firstly create a simple react vite app with vite-plugin-pwa.
Create a new component which will be responsible for showing the prompt.
Use this component anywhere in the App
tree.
import { Button, Group, Modal, Text } from "@mantine/core";
import { showNotification } from "@mantine/notifications";
import { useEffect } from "react";
import { useRegisterSW } from "virtual:pwa-register/react";
const AppUpdateModal = () => {
const {
offlineReady: [offlineReady, setOfflineReady],
needRefresh: [needRefresh, setNeedRefresh],
updateServiceWorker,
} = useRegisterSW({
onRegistered(r) {
// eslint-disable-next-line prefer-template
console.log("SW Registered: " + r);
},
onRegisterError(error) {
console.log("SW registration error", error);
},
});
const close = () => {
setOfflineReady(false);
setNeedRefresh(false);
};
useEffect(() => {
offlineReady &&
showNotification({
title: "Ready",
message: "App is ready to work offline",
color: "blue",
});
}, [offlineReady]);
return (
<>
<Modal
opened={needRefresh}
title="Install update"
centered
onClose={close}
>
<Text>A new app update is available.</Text>
<Text c={"dimmed"} fz="xs" mt="sm">
<strong>Reload</strong> will refresh the app. You may lose the
progress, if any.
</Text>
<Text c={"dimmed"} fz="xs">
<strong>Cancel</strong> will install the update next time you visit
the app.
</Text>
<Group position="right" mt="lg">
<Button variant="subtle" onClick={close}>
Cancel
</Button>
<Button onClick={() => updateServiceWorker(true)}>Reload</Button>
</Group>
</Modal>
</>
);
};
export default AppUpdateModal;
Here we get the state (offlineReady
, needRefresh
) via useRegisterSW
hook from virtual module and based on that we show the modal.
Here I used mantine react UI kit, which is really cool. You may swap with your favourite UI kit.
You will also need to set register type as prompt
in vite.config.ts
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import { VitePWA } from "vite-plugin-pwa";
export default defineConfig({
plugins: [
react(),
VitePWA({
registerType: "prompt",
// other config here ...
}),
],
});
vite-plugin-pwa offers more stategies. You may further explore at https://vite-pwa-org.netlify.app/examples/react.html