### Start Service Worker Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/examples/vanilla-ts-no-ip/README.md Run this command to start the service worker for the PWA example. Ensure https-localhost is configured. ```bash npm run start-sw ``` -------------------------------- ### Install and build project dependencies Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/CONTRIBUTING.md Install all project dependencies using pnpm and then build the project. ```shell pnpm i pnpm run build ``` -------------------------------- ### Run examples with default options Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/CONTRIBUTING.md Execute the examples to test your changes against different frameworks using default CLI options. This checks for major build breakages. ```shell pnpm run examples ``` -------------------------------- ### Start Svelte Development Server Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/examples/sveltekit-pwa/README.md Run npm run dev to start the development server. Use the -- --open flag to automatically open the app in a new browser tab. ```bash npm run dev # or start the server and open the app in a new browser tab npm run dev -- --open ``` -------------------------------- ### Run Development Server Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/examples/react-router/README.md Use this command to start the development server. Ensure you have https-localhost configured for local HTTPS serving. ```bash npm run start ``` -------------------------------- ### Install PNPM Globally Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/examples/index.md Install PNPM globally using npm if it's not already installed. This package manager is recommended for the project. ```shell npm install -g pnpm ``` -------------------------------- ### Install vite-plugin-pwa with NPM Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/index.md Install the vite-plugin-pwa plugin as a dev dependency using NPM. ```shell npm i vite-pwa -D ``` -------------------------------- ### Install vite-plugin-pwa with PNPM Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/index.md Install the vite-plugin-pwa plugin as a dev dependency using PNPM. ```shell pnpm i vite-pwa -D ``` -------------------------------- ### Install Dependencies and Build Vite Plugin PWA Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/examples/index.md Install project dependencies and build the vite-plugin-pwa plugin from the cloned repository root using PNPM. ```shell pnpm install pnpm run build ``` -------------------------------- ### Install Playwright Chromium browser Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/CONTRIBUTING.md Before running tests, install the Playwright Chromium browser. ```shell pnpm playwright install chromium ``` -------------------------------- ### Build Svelte Project for Production Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/examples/sveltekit-pwa/README.md Before building, install an adapter for your target environment. Then, run npm run build to create a production version of your app. ```bash npm run build ``` -------------------------------- ### Run tests Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/CONTRIBUTING.md Execute the test suite for the project. This can be run from the root folder or within individual example folders after building. ```shell pnpm run test ``` -------------------------------- ### Install Dependencies and Build Vite Plugin PWA with YARN Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/examples/index.md Alternative method to install project dependencies and build the vite-plugin-pwa plugin using YARN. ```shell yarn && yarn build ``` -------------------------------- ### Install vite-plugin-pwa with Yarn Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/index.md Install the vite-plugin-pwa plugin as a dev dependency using Yarn. ```shell yarn add vite-pwa -D ``` -------------------------------- ### Install vite-plugin-pwa Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/README.md Install the plugin using npm, yarn, or pnpm. This package is a development dependency. ```bash npm i vite-plugin-pwa -D # yarn yarn add vite-plugin-pwa -D # pnpm pnpm add vite-plugin-pwa -D ``` -------------------------------- ### Preview Built Svelte Project Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/examples/sveltekit-pwa/README.md You can preview the built app with npm run preview, regardless of whether you installed an adapter. This command should not be used to serve your app in production. ```bash npm run preview ``` -------------------------------- ### Basic Netlify Deployment Configuration Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/deployment/netlify.md This netlify.toml file configures build environment variables, the publish directory, build command, redirects, and headers for manifest and assets. It's a comprehensive example for deploying Vite PWA projects. ```toml [build.environment] NPM_FLAGS = "--prefix=/dev/null" NODE_VERSION = "14" [build] publish = "dist" command = "npx pnpm i --store=node_modules/.pnpm-store && npx pnpm run build" [[redirects]] from = "/*" to = "/index.html" status = 200 [[headers]] for = "/manifest.webmanifest" [headers.values] Content-Type = "application/manifest+json" [[headers]] for = "/assets/*" [headers.values] cache-control = ''' max-age=31536000, immutable ''' ``` -------------------------------- ### Add Vite Plugin PWA to Svelte Config Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/frameworks/sveltekit.md Configures SvelteKit to use the static adapter and integrates Vite PWA with the defined configuration. Ensure `adapter-static` is installed and configured. ```javascript import adapter from '@sveltejs/adapter-static' import preprocess from 'svelte-preprocess' import { VitePWA } from 'vite-plugin-pwa' import { pwaConfiguration } from './pwa-configuration.js' /** @type {import('@sveltejs/kit').Config} */ const config = { // Consult https://github.com/sveltejs/svelte-preprocess // for more information about preprocessors preprocess: preprocess(), kit: { adapter: adapter(), // hydrate the
element in src/app.html target: '#svelte', vite: { plugins: [VitePWA(pwaConfiguration)] } } } ``` -------------------------------- ### Basic Service Worker with Precaution Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/inject-manifest.md A minimal custom service worker using Workbox to precache assets. Ensure `workbox-precaching` is installed as a dev dependency. ```javascript import { precacheAndRoute } from 'workbox-precaching' precacheAndRoute(self.__WB_MANIFEST) ``` -------------------------------- ### Dynamically Import ReloadPrompt Component with Vue 3 Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/faq.md This example shows how to dynamically import the `ReloadPrompt` component in a Vue 3 application, ensuring it's only loaded on the client side. This is crucial for SSR/SSG compatibility when using the 'prompt' strategy. ```vue // src/App.vue ``` -------------------------------- ### Custom Service Worker for Network First Strategy Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/workbox/inject-manifest.md Implement a custom service worker using Workbox for the network-first strategy. Includes logic for cache-network-race, runtime cache management, and fallback for document requests. Ensure Workbox dependencies are installed as dev dependencies. ```typescript import { cacheNames, clientsClaim } from 'workbox-core' import { registerRoute, setCatchHandler, setDefaultHandler } from 'workbox-routing' import type { StrategyHandler } from 'workbox-strategies' import { NetworkFirst, NetworkOnly, Strategy } from 'workbox-strategies' import type { ManifestEntry } from 'workbox-build' // Give TypeScript the correct global. declare let self: ServiceWorkerGlobalScope declare type ExtendableEvent = any const data = { race: false, debug: false, credentials: 'same-origin', networkTimeoutSeconds: 0, fallback: 'index.html' } const cacheName = cacheNames.runtime function buildStrategy(): Strategy { if (race) { class CacheNetworkRace extends Strategy { _handle(request: Request, handler: StrategyHandler): Promise { const fetchAndCachePutDone: Promise = handler.fetchAndCachePut(request) const cacheMatchDone: Promise = handler.cacheMatch(request) return new Promise((resolve, reject) => { fetchAndCachePutDone.then(resolve).catch((e) => { if (debug) console.log(`Cannot fetch resource: ${request.url}`, e) }) cacheMatchDone.then(response => response && resolve(response)) // Reject if both network and cache error or find no response. Promise.allSettled([fetchAndCachePutDone, cacheMatchDone]).then((results) => { const [fetchAndCachePutResult, cacheMatchResult] = results if (fetchAndCachePutResult.status === 'rejected' && !cacheMatchResult.value) reject(fetchAndCachePutResult.reason) }) }) } } return new CacheNetworkRace() } else { if (networkTimeoutSeconds > 0) return new NetworkFirst({ cacheName, networkTimeoutSeconds }) else return new NetworkFirst({ cacheName }) } } const manifest = self.__WB_MANIFEST as Array const cacheEntries: RequestInfo[] = [] const manifestURLs = manifest.map( (entry) => { const url = new URL(entry.url, self.location) cacheEntries.push(new Request(url.href, { credentials: credentials as any })) return url.href } ) self.addEventListener('install', (event: ExtendableEvent) => { event.waitUntil( caches.open(cacheName).then((cache) => { return cache.addAll(cacheEntries) }) ) }) self.addEventListener('activate', (event: ExtendableEvent) => { // - clean up outdated runtime cache event.waitUntil( caches.open(cacheName).then((cache) => { // clean up those who are not listed in manifestURLs cache.keys().then((keys) => { keys.forEach((request) => { debug && console.log(`Checking cache entry to be removed: ${request.url}`) if (!manifestURLs.includes(request.url)) { cache.delete(request).then((deleted) => { if (debug) { if (deleted) console.log(`Precached data removed: ${request.url || request}`) else console.log(`No precache found: ${request.url || request}`) } }) } }) }) }) ) }) registerRoute( ({ url }) => manifestURLs.includes(url.href), buildStrategy() ) setDefaultHandler(new NetworkOnly()) // fallback to app-shell for document request setCatchHandler(({ event }): Promise => { switch (event.request.destination) { case 'document': return caches.match(fallback).then((r) => { return r ? Promise.resolve(r) : Promise.resolve(Response.error()) }) default: return Promise.resolve(Response.error()) } }) // this is necessary, since the new service worker will keep on skipWaiting state // and then, caches will not be cleared since it is not activated self.skipWaiting() clientsClaim() ``` -------------------------------- ### SolidJS Type Declarations for Vite PWA Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/frameworks/solidjs.md Provides type declarations for the `virtual:pwa-register/solid` module, enabling type safety for SolidJS applications using Vite PWA. Ensure `workbox-window` is installed as a dev dependency. ```typescript declare module 'virtual:pwa-register/solid' { // @ts-expect-error ignore when solid-js is not installed import type { Accessor, Setter } from 'solid-js' export interface RegisterSWOptions { immediate?: boolean onNeedReload?: () => void onNeedRefresh?: () => void onOfflineReady?: () => void /** * Called only if `onRegisteredSW` is not provided. * * @deprecated Use `onRegisteredSW` instead. * @param registration The service worker registration if available. */ onRegistered?: (registration: ServiceWorkerRegistration | undefined) => void /** * Called once the service worker is registered (requires version `0.12.8+`). * * @param swScriptUrl The service worker script url. * @param registration The service worker registration if available. */ onRegisteredSW?: (swScriptUrl: string, registration: ServiceWorkerRegistration | undefined) => void onRegisterError?: (error: any) => void } export function useRegisterSW(options?: RegisterSWOptions): { needRefresh: [Accessor, Setter] offlineReady: [Accessor, Setter] updateServiceWorker: (reloadPage?: boolean) => Promise } } ``` -------------------------------- ### Preact Type Declarations for PWA Registration Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/frameworks/preact.md Defines the types for the `virtual:pwa-register/preact` module, including options for `useRegisterSW` and its return values. Ensure `workbox-window` is installed as a dev dependency. ```typescript declare module 'virtual:pwa-register/preact' { // @ts-expect-error ignore when preact/hooks is not installed import type { StateUpdater } from 'preact/hooks' export interface RegisterSWOptions { immediate?: boolean onNeedReload?: () => void onNeedRefresh?: () => void onOfflineReady?: () => void /** * Called only if `onRegisteredSW` is not provided. * * @deprecated Use `onRegisteredSW` instead. * @param registration The service worker registration if available. */ onRegistered?: (registration: ServiceWorkerRegistration | undefined) => void /** * Called once the service worker is registered (requires version `0.12.8+`). * * @param swScriptUrl The service worker script url. * @param registration The service worker registration if available. */ onRegisteredSW?: (swScriptUrl: string, registration: ServiceWorkerRegistration | undefined) => void onRegisterError?: (error: any) => void } export function useRegisterSW(options?: RegisterSWOptions): { needRefresh: [boolean, StateUpdater] offlineReady: [boolean, StateUpdater] updateServiceWorker: (reloadPage?: boolean) => Promise } } ``` -------------------------------- ### Serve VitePress Documentation Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/examples/vitepress.md Run this command from the root folder to serve the VitePress documentation site locally. ```shell pnpm run docs:serve ``` -------------------------------- ### Create SvelteKit Project with pnpm Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/examples/sveltekit.md Use this command to create a new SvelteKit project with pnpm. Follow the prompts to configure TypeScript, ESLint, and Prettier. ```shell pnpm create svelte@next sveltekit-pwa + create-svelte 2.0.0-next.89 Progress: resolved 5, reused 5, downloaded 0, added 5, done create-svelte version 2.0.0-next.89 Welcome to SvelteKit! This is beta software; expect bugs and missing features. Problems? Open an issue on https://github.com/sveltejs/kit/issues if none exists already. √ Which Svelte app template? » Skeleton project √ Use TypeScript? ... No / Yes √ Add ESLint for code linting? ... No / Yes √ Add Prettier for code formatting? ... No / Yes Your project is ready! ✔ Typescript Inside Svelte components, use ``` -------------------------------- ### Enable Manifest Credentials Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/faq.md Set `useCredentials` to `true` in the plugin options to send web manifest requests with credentials, resolving 401 errors on authenticated sites. ```javascript useCredentials: true ``` -------------------------------- ### Import Libraries Safely in SSR/SSG Environments Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/faq.md When encountering `navigator` or `window` undefined errors in SSR/SSG environments, use dynamic imports guarded by `typeof window !== 'undefined'` or framework-specific lifecycle hooks like `onMount`. ```javascript if (typeof window !== 'undefined') import('./library-not-ssr-ssg-aware') ``` -------------------------------- ### Configure HTML for External Resources Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/workbox/generate-sw.md Configure your index.html file to include external resources like fonts and CSS from CDNs. Ensure crossorigin="anonymous" is set for these resources. ```html ``` -------------------------------- ### PWA Script for Static Adapter Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/frameworks/sveltekit.md This script handles the generation of PWA assets when using the static adapter. It resolves Vite configuration, generates the Service Worker, and copies necessary files like the manifest. ```javascript import { copyFileSync } from 'node:fs' import { resolveConfig } from 'vite' import { VitePWA } from 'vite-plugin-pwa' import { pwaConfiguration } from './pwa-configuration.js' const webmanifestDestinations = [ './.svelte-kit/output/client/', './build/', ] const swDestinations = [ './build/', ] async function buildPwa() { const config = await resolveConfig({ plugins: [VitePWA({ ...pwaConfiguration })] }, 'build', 'production') // when `vite-plugin-pwa` is present, use it to regenerate SW after rendering const pwaPlugin = config.plugins.find(i => i.name === 'vite-plugin-pwa')?.api if (pwaPlugin?.generateSW) { console.log('Generating PWA...') await pwaPlugin.generateSW() webmanifestDestinations.forEach((d) => { copyFileSync('./.svelte-kit/output/client/_app/manifest.webmanifest', `${d}/manifest.webmanifest`) }) // don't copy workbox, SvelteKit will copy it swDestinations.forEach((d) => { copyFileSync('./.svelte-kit/output/client/sw.js', `${d}/sw.js`) }) console.log('Generation of PWA complete') } } buildPwa() ``` -------------------------------- ### Create Svelte Vite Project Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/examples/svelte.md Use this command to scaffold a new Svelte project with Vite and TypeScript. Follow the prompts to name your project and select the Svelte framework with the TypeScript variant. ```shell pnpx create-vite + create-vite 2.5.4 √ Project name: ... svelte-routify √ Select a framework: » svelte √ Select a variant: » svelte-ts Scaffolding project in examples\svelte-routify... Done. Now run: cd svelte-routify npm install npm run dev ``` -------------------------------- ### Create Vue 3 Project with Vite Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/examples/vue.md Use this command to scaffold a new Vue 3 project with TypeScript support using create-vite. Follow the prompts to name your project and select the Vue framework and TypeScript variant. ```shell pnpx create-vite + create-vite 2.5.4 √ Project name: ... vue-router √ Select a framework: » vue √ Select a variant: » vue-ts Scaffolding project in examples\vue-router... Done. Now run: cd vue-router npm install npm run dev ``` -------------------------------- ### Robots.txt for Search Engine Crawling Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/pwa-minimal-requirements.md Create a robots.txt file in the public folder to allow search engines to crawl all pages of your application. ```text User-agent: * Allow: / ``` -------------------------------- ### Vite PWA Plugin Configuration for Manifest Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/pwa-minimal-requirements.md Configure the Vite PWA plugin with essential manifest properties like name, short name, description, theme color, and required icons. ```typescript import { defineConfig } from 'vite' import { VitePWA } from 'vite-plugin-pwa' export default defineConfig({ plugins: [ VitePWA({ includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'masked-icon.svg'], manifest: { name: 'My Awesome App', short_name: 'MyApp', description: 'My Awesome App description', theme_color: '#ffffff', icons: [ { src: 'pwa-192x192.png', sizes: '192x192', type: 'image/png' }, { src: 'pwa-512x512.png', sizes: '512x512', type: 'image/png' } ] } }) ] }) ``` -------------------------------- ### Configure manifest.webmanifest MIME Type for Netlify Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/deployment/netlify.md Add this headers table to your netlify.toml to register the correct MIME type for the web manifest. This ensures the browser interprets the manifest file correctly. ```toml [[headers]] for = "/manifest.webmanifest" [headers.values] Content-Type = "application/manifest+json" ``` -------------------------------- ### Basic Vite PWA Configuration Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/README.md Add the VitePWA plugin to your Vite configuration file. This enables default PWA configurations. ```typescript import { VitePWA } from 'vite-plugin-pwa' export default { plugins: [ VitePWA() ] } ``` -------------------------------- ### vite-plugin-pwa Configuration with Dev Options Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/index.md Enable PWA features in development mode by adding the `devOptions` to the plugin configuration. This ensures the manifest and service worker are generated during development. ```typescript import { VitePWA } from 'vite-plugin-pwa' export default defineConfig({ plugins: [ VitePWA({ registerType: 'autoUpdate', devOptions: { enabled: true } }) ] }) ``` -------------------------------- ### Register Service Worker with Reload Callback Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/auto-update.md Import `registerSW` from `virtual:pwa-register` and provide an `onNeedReload` callback to customize the reload behavior. The default action is `window.location.reload()`. ```javascript import { registerSW } from 'virtual:pwa-register' const updateSW = registerSW({ onOfflineReady() {}, onNeedReload() { // called when the updated service worker takes control. // default behavior (when omitted) is: window.location.reload() }, }) ``` -------------------------------- ### Modify Build Script for PWA Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/frameworks/sveltekit.md Integrates PWA generation into the SvelteKit build process by appending a node script execution after the standard SvelteKit build. ```json { "scripts": { "build": "svelte-kit build && node ./pwa.js" } } ``` -------------------------------- ### Enable injectManifest Strategy Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/inject-manifest.md Configure the `vite-plugin-pwa` plugin to use the `injectManifest` strategy for custom service workers. ```typescript VitePWA({ strategies: 'injectManifest', }) ``` -------------------------------- ### Dynamically Import ReloadPrompt Component with Svelte Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/faq.md This Svelte code snippet demonstrates how to dynamically import the `ReloadPrompt` component, ensuring it is loaded only on the client side. This is essential for SSR/SSG environments when using the 'prompt' strategy. ```html ... {#if ClientReloadPrompt} {/if} ``` -------------------------------- ### Clone SolidJS Router Template Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/examples/solidjs.md Use this command to clone the SolidJS TypeScript router template. This sets up the project structure for a SolidJS application with routing capabilities. ```shell npx degit solidjs/templates/ts-router solid-router > cloned solidjs/templates#HEAD to solid-router ``` -------------------------------- ### Dynamic Import ReloadPrompt in SvelteKit Layout Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/frameworks/sveltekit.md Include the `ReloadPrompt` component using dynamic import in your main SvelteKit layout (`__layout.svelte`). This ensures the service worker registration and prompt only occur in production builds and on the client-side. ```html {#if (!dev && browser)} {/if}
{#if ReloadPrompt} {/if} ``` -------------------------------- ### Configure globPatterns for generateSW Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/static-assets.md When using the `generateSW` strategy, configure `globPatterns` within the `workbox` plugin option to specify assets to precache. ```typescript VitePWA({ workbox: { globPatterns: [], } }) ``` -------------------------------- ### Configure Precache Glob Patterns Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/service-worker-precache.md Add custom file types like 'ico', 'png', and 'svg' to the precache manifest by specifying them in the `globPatterns` option within the `workbox` configuration. This is used when the default `generateSW` strategy is active. ```typescript import { defineConfig } from 'vite' import { VitePWA } from 'vite-plugin-pwa' export default defineConfig({ plugins: [ VitePWA({ registerType: 'autoUpdate', workbox: { globPatterns: ['**/*.{js,css,html,ico,png,svg}'] } }) ] }) ``` -------------------------------- ### Implement Background Sync for API Requests Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/workbox/generate-sw.md Configure Workbox's runtime caching to use background sync for specific API POST requests. This ensures that requests are retried if they fail due to network issues. ```typescript VitePWA({ workbox: { runtimeCaching: [{ handler: 'NetworkOnly', urlPattern: /\/api\/.*\/*.json/, method: 'POST', options: { backgroundSync: { name: 'myQueueName', options: { maxRetentionTime: 24 * 60 } } } }] } }) ``` -------------------------------- ### Configure globPatterns for injectManifest Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/static-assets.md When using the `injectManifest` strategy, configure `globPatterns` within the `injectManifest` plugin option to specify assets to precache. ```typescript VitePWA({ injectManifest: { globPatterns: [], } }) ``` -------------------------------- ### vite-plugin-pwa Configuration for Older Versions Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/index.md If you are using vite-plugin-pwa version prior to 0.12.2, use this configuration to fix a bug with `injectRegister` and `autoUpdate` behavior. ```typescript import { VitePWA } from 'vite-plugin-pwa' export default defineConfig({ plugins: [ VitePWA({ registerType: 'autoUpdate', workbox: { clientsClaim: true, skipWaiting: true } }) ] }) ``` -------------------------------- ### Configure Manifest MIME Type for Apache Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/deployment/apache.md Add this configuration to your Apache server to ensure the webmanifest file is served with the correct MIME type. ```apache # Manifest file AddType application/manifest+json webmanifest ``` -------------------------------- ### Enable Service Worker on Development Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/guide/development.md Configure vite-plugin-pwa to enable the service worker during development. Ensure the `devOptions.enabled` is set to `true`. ```typescript import { defineConfig } from 'vite' import { VitePWA } from 'vite-plugin-pwa' export default defineConfig({ plugins: [ VitePWA({ /* other options */ /* enable sw on development */ devOptions: { enabled: true /* other options */ } }) ] }) ``` -------------------------------- ### Preact CSS for Reload Prompt Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/frameworks/preact.md Basic CSS styles for the `ReloadPrompt` component to create a toast-like notification. This file should be placed alongside `ReloadPrompt.tsx`. ```css .ReloadPrompt-container { padding: 0; margin: 0; width: 0; height: 0; } .ReloadPrompt-toast { position: fixed; right: 0; bottom: 0; margin: 16px; padding: 12px; border: 1px solid #8885; border-radius: 4px; z-index: 1; text-align: left; box-shadow: 3px 4px 5px 0 #8885; background-color: white; } .ReloadPrompt-toast-message { margin-bottom: 8px; } .ReloadPrompt-toast-button { border: 1px solid #8885; outline: none; margin-right: 5px; border-radius: 2px; padding: 3px 10px; } ``` -------------------------------- ### VitePWA Options for Inject Manifest Source: https://github.com/vite-pwa/vite-plugin-pwa/blob/main/docs/workbox/inject-manifest.md Configure VitePWA to use the 'injectManifest' strategy, specifying the source directory and filename for the service worker. ```typescript VitePWA({ strategies: 'injectManifest', srcDir: 'src', filename: 'sw.ts' }) ```