diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.ts
similarity index 87%
rename from docs/.vitepress/config.js
rename to docs/.vitepress/config.ts
index b6ba157e..d486a4ed 100644
--- a/docs/.vitepress/config.js
+++ b/docs/.vitepress/config.ts
@@ -1,4 +1,4 @@
-require('esbuild-register')
+import type { UserConfig } from 'vitepress'
const Guide = [
{
@@ -83,6 +83,10 @@ const Frameworks = [
text: 'Svelte',
link: '/frameworks/svelte',
},
+ {
+ text: 'SvelteKit',
+ link: '/frameworks/sveltekit',
+ },
{
text: 'SolidJS',
link: '/frameworks/solidjs',
@@ -114,6 +118,10 @@ const Examples = [
text: 'Svelte',
link: '/examples/svelte',
},
+ {
+ text: 'SvelteKit',
+ link: '/examples/sveltekit',
+ },
{
text: 'SolidJS',
link: '/examples/solidjs',
@@ -147,45 +155,41 @@ const slidebars = [
{
text: 'Guide',
children: Guide.map((e) => {
- e.useLinkText = `${e.text} | Guide`
+ (e as any).useLinkText = `${e.text} | Guide`
return e
}),
},
{
text: 'Frameworks',
children: Frameworks.map((e) => {
- e.useLinkText = `${e.text} | Frameworks`
+ (e as any).useLinkText = `${e.text} | Frameworks`
return e
}),
},
{
text: 'Examples',
children: Examples.map((e) => {
- e.useLinkText = `${e.text} | Examples`
+ (e as any).useLinkText = `${e.text} | Examples`
return e
}),
},
{
text: 'Deployment',
children: Deployment.map((e) => {
- e.useLinkText = `${e.text} | Deployment`
+ (e as any).useLinkText = `${e.text} | Deployment`
return e
}),
},
{
text: 'Workbox',
children: Workbox.map((e) => {
- e.useLinkText = `${e.text} | Workbox`
+ (e as any).useLinkText = `${e.text} | Workbox`
return e
}),
},
]
-
-/**
- * @type {import('vitepress').UserConfig}
- */
-const config = {
+const config: UserConfig = {
title: 'Vite Plugin PWA',
description: 'Zero-config PWA Framework-agnostic Plugin for Vite',
lang: 'en-US',
@@ -195,7 +199,7 @@ const config = {
['link', { rel: 'alternate icon', href: '/favicon.ico', type: 'image/png', sizes: '16x16' }],
['link', { rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#ffffff' }],
['meta', { name: 'author', content: 'Anthony Fu' }],
- ['meta', { name: 'keywords', content: 'react, pwa, vue, preact, svelte, workbox, solidjs, vite, vite-plugin' }],
+ ['meta', { name: 'keywords', content: 'react, pwa, vue, vitepress, preact, svelte, sveltekit, workbox, solidjs, vite, vite-plugin' }],
['meta', { property: 'og:title', content: 'Vite Plugin PWA' }],
['meta', { property: 'og:description', content: 'Zero-config PWA Framework-agnostic Plugin for Vite' }],
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
@@ -252,4 +256,4 @@ const config = {
},
}
-module.exports = config
+export default config
diff --git a/docs/.vitepress/theme/components/ExamplesBehaviors.md b/docs/.vitepress/theme/components/ExamplesBehaviors.md
new file mode 100644
index 00000000..ad847517
--- /dev/null
+++ b/docs/.vitepress/theme/components/ExamplesBehaviors.md
@@ -0,0 +1,17 @@
+- `Prompt for update`:
+ - Show `Ready to work offline` on first visit and once the `service worker` ready.
+ - Show `Prompt for update` when new `service worker` available.
+
+- `Auto update`:
+ - Show `Ready to work offline` on first visit and once the `service worker` ready.
+ - When new content available, the service worker will be updated automatically.
+
+- `Prompt for update` with `Periodic service worker updates`:
+ - Show `Ready to work offline` on first visit and once the `service worker` ready.
+ - Show `Prompt for update` when new `service worker` available.
+ - The example project will register a `Periodic service worker updates`
+
+- `Auto update` with `Periodic service worker updates`:
+ - Show `Ready to work offline` on first visit and once the `service worker` ready.
+ - The example project will register a `Periodic service worker updates`
+ - When new content available, the service worker will be updated automatically.
diff --git a/docs/.vitepress/theme/components/ExamplesGenerateSW.md b/docs/.vitepress/theme/components/ExamplesGenerateSW.md
new file mode 100644
index 00000000..1e5a3432
--- /dev/null
+++ b/docs/.vitepress/theme/components/ExamplesGenerateSW.md
@@ -0,0 +1,3 @@
+`generateSW` has the following behaviors:
+
+
diff --git a/docs/.vitepress/theme/components/ExamplesInjectManifest.md b/docs/.vitepress/theme/components/ExamplesInjectManifest.md
new file mode 100644
index 00000000..06becabc
--- /dev/null
+++ b/docs/.vitepress/theme/components/ExamplesInjectManifest.md
@@ -0,0 +1,3 @@
+`injectManifest` has the following behavior:
+
+
diff --git a/docs/.vitepress/theme/composables/navLink.ts b/docs/.vitepress/theme/composables/navLink.ts
index 527c69d4..485c0c06 100644
--- a/docs/.vitepress/theme/composables/navLink.ts
+++ b/docs/.vitepress/theme/composables/navLink.ts
@@ -2,11 +2,9 @@ import { computed, Ref } from 'vue'
import { useRoute, withBase } from 'vitepress'
import type { DefaultTheme } from '../config'
import { isExternal as isExternalCheck } from '../utils'
-// import { useUrl } from './url'
export function useNavLink(item: Ref) {
const route = useRoute()
- // const { withBase } = useUrl()
const isExternal = isExternalCheck(item.value.link)
@@ -24,6 +22,12 @@ export function useNavLink(item: Ref) {
= itemPath === '/'
? itemPath === routePath
: routePath.startsWith(itemPath)
+ // fix /frameworks/sveltekit and /frameworks/svelte
+ if (routePath === '/frameworks/sveltekit' && itemPath === '/frameworks/svelte' && active)
+ active = false
+ // fix /examples/sveltekit and /examples/svelte
+ if (routePath === '/examples/sveltekit' && itemPath === '/examples/svelte' && active)
+ active = false
}
return {
diff --git a/docs/examples/index.md b/docs/examples/index.md
index bc2fdfc9..15561f27 100644
--- a/docs/examples/index.md
+++ b/docs/examples/index.md
@@ -102,7 +102,7 @@ We provide the following example projects:
Vue 3 injectManifest Example
- : Ready to work offline and Prompt for update.
+ : set of examples with disparate behaviors.
@@ -117,7 +117,7 @@ We provide the following example projects:
React injectManifest Example
- : Ready to work offline and Prompt for update.
+ : set of examples with disparate behaviors.
@@ -132,7 +132,22 @@ We provide the following example projects:
Svelte injectManifest Example
- : Ready to work offline and Prompt for update.
+ : set of examples with disparate behaviors.
+
+
+
+
+
+ SvelteKit
+
+
+
+ SvelteKit generatesSw Example
+ : set of examples with disparate behaviors.
+
+
+ SvelteKit injectManifest Example
+ : set of examples with disparate behaviors.
@@ -147,7 +162,7 @@ We provide the following example projects:
SolidJS injectManifest Router Example
- : Ready to work offline and Prompt for update.
+ : set of examples with disparate behaviors.
@@ -162,7 +177,7 @@ We provide the following example projects:
Preact injectManifest Router Example
- : Ready to work offline and Prompt for update.
+ : set of examples with disparate behaviors.
diff --git a/docs/examples/preact.md b/docs/examples/preact.md
index 2015d6cb..63da6c54 100644
--- a/docs/examples/preact.md
+++ b/docs/examples/preact.md
@@ -8,7 +8,11 @@ The `Preact` example project can be found on `examples/preact-router` package/di
The router used on this example project is [preact-router](https://github.com/preactjs/preact-router) .
-The `Preact` example has been created using `create-vite` template with `PNPM`:
+The `Preact` example has been created using `create-vite` template with `pnpx`:
+
+
+ pnpx create-vite
+
```shell
pnpx create-vite
+ create-vite 2.6.6
@@ -24,7 +28,7 @@ Done. Now run:
npm install
npm run dev
```
-
+
To test `new content available`, you should rerun the corresponding script, and then refresh the page.
@@ -37,31 +41,8 @@ If you are running an example with `Periodic SW updates`, you will need to wait
## generateSW
-`generateSW` has the following behaviors:
-- `Prompt for update`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - Show `Prompt for update` when new `service worker` available.
-
-- `Auto update`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - When new content available, the service worker will be updated automatically.
-
-- `Prompt for update` with `Periodic service worker updates`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - Show `Prompt for update` when new `service worker` available.
- - The example project will register a `Periodic service worker updates`
-
-- `Auto update` with `Periodic service worker updates`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - The example project will register a `Periodic service worker updates`
- - When new content available, the service worker will be updated automatically.
+
## injectManifest
-`injectManifest` has the following behavior:
-- Custom `TypeScript Service Worker` with offline support.
-- Show `Ready to work offlline` on first visit and once the `service worker` ready.
-- Show `Prompt for update` when new `service worker` available.
-
-
-
+
diff --git a/docs/examples/react.md b/docs/examples/react.md
index 089048f3..c13c22d1 100644
--- a/docs/examples/react.md
+++ b/docs/examples/react.md
@@ -8,7 +8,11 @@ The `React` example project can be found on `examples/react-router` package/dire
The router used on this example project is [react-router](https://reactrouter.com/) .
-The `React` example has been created using `create-vite` template with `PNPM`:
+The `React` example has been created using `create-vite` template with `pnpx`:
+
+
+ pnpx create-vite
+
```shell
pnpx create-vite
+ create-vite 2.5.4
@@ -24,6 +28,7 @@ Done. Now run:
npm install
npm run dev
```
+
To test `new content available`, you should rerun the corresponding script, and then refresh the page.
@@ -36,28 +41,8 @@ If you are running an example with `Periodic SW updates`, you will need to wait
## generateSW
-`generateSW` has the following behaviors:
-- `Prompt for update`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - Show `Prompt for update` when new `service worker` available.
-
-- `Auto update`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - When new content available, the service worker will be updated automatically.
-
-- `Prompt for update` with `Periodic service worker updates`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - Show `Prompt for update` when new `service worker` available.
- - The example project will register a `Periodic service worker updates`
-
-- `Auto update` with `Periodic service worker updates`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - The example project will register a `Periodic service worker updates`
- - When new content available, the service worker will be updated automatically.
+
## injectManifest
-`injectManifest` has the following behavior:
-- Custom `TypeScript Service Worker` with offline support.
-- Show `Ready to work offlline` on first visit and once the `service worker` ready.
-- Show `Prompt for update` when new `service worker` available.
+
diff --git a/docs/examples/solidjs.md b/docs/examples/solidjs.md
index 34e3aaa1..30d989e7 100644
--- a/docs/examples/solidjs.md
+++ b/docs/examples/solidjs.md
@@ -8,11 +8,16 @@ The `SolidJS` example project can be found on `examples/solid-router` package/di
The router used on this example project is [solid-app-router](https://github.com/solidjs/solid-app-router) .
-The `SolidJS` example has been created using `https://github.com/solidjs/templates` template with `NPX`:
+The `SolidJS` example has been created using `https://github.com/solidjs/templates` template with `npx`:
+
+
+ npx degit solidjs/templates/ts-router solid-router
+
```shell
npx degit solidjs/templates/ts-router solid-router
> cloned solidjs/templates#HEAD to solid-router
```
+
To test `new content available`, you should rerun the corresponding script, and then refresh the page.
@@ -25,28 +30,9 @@ If you are running an example with `Periodic SW updates`, you will need to wait
## generateSW
-`generateSW` has the following behaviors:
-- `Prompt for update`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - Show `Prompt for update` when new `service worker` available.
-
-- `Auto update`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - When new content available, the service worker will be updated automatically.
-
-- `Prompt for update` with `Periodic service worker updates`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - Show `Prompt for update` when new `service worker` available.
- - The example project will register a `Periodic service worker updates`
-
-- `Auto update` with `Periodic service worker updates`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - The example project will register a `Periodic service worker updates`
- - When new content available, the service worker will be updated automatically.
+
## injectManifest
-`injectManifest` has the following behavior:
-- Custom `TypeScript Service Worker` with offline support.
-- Show `Ready to work offlline` on first visit and once the `service worker` ready.
-- Show `Prompt for update` when new `service worker` available.
+
+
diff --git a/docs/examples/svelte.md b/docs/examples/svelte.md
index 2600d9cd..d63b1a32 100644
--- a/docs/examples/svelte.md
+++ b/docs/examples/svelte.md
@@ -8,7 +8,11 @@ The `Svelte` example project can be found on `examples/react-routify` package/di
The router used on this example project is [@roxi/routify](https://routify.dev/) .
-The `Svelte` example has been created using `create-vite` template with `PNPM`:
+The `Svelte` example has been created using `create-vite` template with `pnpx`:
+
+
+ pnpx create-vite
+
```shell
pnpx create-vite
+ create-vite 2.5.4
@@ -24,6 +28,7 @@ Done. Now run:
npm install
npm run dev
```
+
To test `new content available`, you should rerun the corresponding script, and then refresh the page.
@@ -36,28 +41,9 @@ If you are running an example with `Periodic SW updates`, you will need to wait
## generateSW
-`generateSW` has the following behaviors:
-- `Prompt for update`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - Show `Prompt for update` when new `service worker` available.
-
-- `Auto update`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - When new content available, the service worker will be updated automatically.
-
-- `Prompt for update` with `Periodic service worker updates`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - Show `Prompt for update` when new `service worker` available.
- - The example project will register a `Periodic service worker updates`
-
-- `Auto update` with `Periodic service worker updates`:
- - Show `Ready to work offlline` on first visit and once the `service worker` ready.
- - The example project will register a `Periodic service worker updates`
- - When new content available, the service worker will be updated automatically.
+
## injectManifest
-`injectManifest` has the following behavior:
-- Custom `TypeScript Service Worker` with offline support.
-- Show `Ready to work offlline` on first visit and once the `service worker` ready.
-- Show `Prompt for update` when new `service worker` available.
+
+
diff --git a/docs/examples/sveltekit.md b/docs/examples/sveltekit.md
new file mode 100644
index 00000000..688b8c2e
--- /dev/null
+++ b/docs/examples/sveltekit.md
@@ -0,0 +1,67 @@
+---
+title: SvelteKit | Examples
+---
+
+# SvelteKit
+
+The `SvelteKit` example project can be found on `examples/sveltekit-pwa` package/directory and it is configured with `@sveltejs/adapter-static` adapter.
+
+The `SvelteKit` example has been created using `svelte@next` template with `pnpm`:
+
+
+ pnpm create svelte@next sveltekit-pwa
+
+```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
+
+
+ {#if (!dev && browser)}
+
+ {/if}
+
+
+
+
+
+
+{#if ReloadPrompt}
+
+{/if}
+```
+
+
+## SvelteKit Adapters
+
+The main problem with the current implementation of the service worker module of `SvelteKit` is that you don't have access to the result applied by any adapter you have configured on your application. The service worker module of `SvelteKit` will be called before the adapter logic is applied, and so, inside the service worker module, you don't have access to those resources. Your application will not work when the user is offline, since the pages will not be included on the service worker precache manifest.
+
+When using `Vite PWA Plugin` with any `SvelteKit Adapter` you need to provide an additional script to rebuild your `pwa` once `SvelteKit` finish building your application, that is, when the adapter configured finish its job.
+
+The biggest difference between this plugin and the SvelteKit service worker module is that this plugin does not require integration into the application logic - just configuration. You can take a look at [SvelteKit example](https://github.com/antfu/vite-plugin-pwa/tree/main/examples/sveltekit-pwa) to configure the additional scripts on your application, it is quite complex since we use it for multiple behaviors with the same codebase.
+
+### Workbox manifestTransforms
+
+We must provide a list of URLs for the service worker to load and precache. We provide these to workbox using the [the `manifestTransforms` option](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.ManifestTransform) under `workbox` or [`injectManifest`](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.injectManifest). The [manifest entries](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.ManifestEntry) provided via this option will contain all the assets specified in the `srcDir` option.
+
+Since `SvelteKit` outputs an `.html` page for each pre-rendered page, you can use `manifestTransforms` to generate the URL from the prerendered HTML file path. For an example, see the `pwa-configuration.js` module in the next example using `@sveltejs/adapter-static`.
+
+Pages which are not prerendered or are generated with a unique adapter will need to be handled separately and the `manifestTransforms` logic will need to be modified accordingly.
+
+### Static Adapter example
+
+As an example, when using [@sveltejs/adapter-static](https://github.com/sveltejs/kit/tree/master/packages/adapter-static) with `generateSW` strategy and `Prompt for update` behavior, you will need:
+
+
+1) add pwa.js script
+
+```js
+import { resolveConfig } from 'vite'
+import { VitePWA } from 'vite-plugin-pwa';
+import { pwaConfiguration } from './pwa-configuration.js';
+import { copyFileSync } from 'fs';
+
+const webmanifestDestinations = [
+ './.svelte-kit/output/client/',
+ './build/',
+]
+
+const swDestinations = [
+ './build/',
+]
+
+const buildPwa = async() => {
+ 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()
+```
+
+
+
+
+2) add pwa-configuration.js script
+
+```js
+const pwaConfiguration = {
+ srcDir: './build',
+ outDir: './.svelte-kit/output/client',
+ includeManifestIcons: false,
+ base: '/',
+ scope: '/',
+ manifest: {
+ short_name: "",
+ name: "",
+ scope: "/",
+ start_url: "/",
+ display: "standalone",
+ theme_color: "#ffffff",
+ background_color: "#ffffff",
+ icons: [
+ {
+ src: "/pwa-192x192.png",
+ sizes: "192x192",
+ type: "image/png"
+ },
+ {
+ src: "/pwa-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ },
+ {
+ src: "/pwa-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ purpose: 'any maskable'
+ }
+ ]
+ },
+ workbox: {
+ // mode: 'development',
+ navigateFallback: '/',
+ // vite and SvelteKit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work
+ dontCacheBustURLsMatching: /-[a-f0-9]{8}\./,
+ globDirectory: './build/',
+ globPatterns: ['robots.txt', '**/*.{js,css,html,ico,png,svg,webmanifest}'],
+ globIgnores: ['**/sw*', '**/workbox-*'],
+ manifestTransforms: [async(entries) => {
+ // manifest.webmanifest is added always by pwa plugin, so we remove it.
+ // EXCLUDE from the sw precache sw and workbox-*
+ const manifest = entries.filter(({ url }) =>
+ url !== 'manifest.webmanifest' && url !== 'sw.js' && !url.startsWith('workbox-')
+ ).map((e) => {
+ let url = e.url;
+ if (url && url.endsWith('.html')) {
+ if (url.startsWith('/')) {
+ url = url.slice(1)
+ }
+ if (url === 'index.html') {
+ e.url = url === 'index.html' ? '/'
+ } else if (url.endsWith('index.html')) {
+ e.url = `/${url.substring(0, url.lastIndexOf('/'))}`
+ } else if (url.endsWith('.html')) {
+ e.url = `/${url.substring(0, url.length - '.html'.length)}`
+ }
+ }
+
+ return e
+ });
+
+ return { manifest };
+ }]
+ }
+};
+
+export { pwaConfiguration };
+```
+
+
+
+3) modify your build script
+
+```json
+"scripts": {
+ "build": "svelte-kit build && node ./pwa.js"
+}
+```
+
+
+
+
+4) add Vite Plugin PWA to svelte.config.js
+
+```js
+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)]
+ }
+ }
+};
+
+export default config;
+```
+
diff --git a/examples/preact-router/package.json b/examples/preact-router/package.json
index 66c56a87..9a2bdf31 100644
--- a/examples/preact-router/package.json
+++ b/examples/preact-router/package.json
@@ -8,6 +8,9 @@
"start-claims": "npm run run-build-claims && npm run serve",
"start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run serve",
"start-sw": "npm run run-build-sw && npm run serve",
+ "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run serve",
+ "start-sw-claims": "npm run run-build-sw-claims && npm run serve",
+ "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run serve",
"dev": "cross-env DEBUG=vite-plugin-pwa:* vite",
"build": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build",
"run-build": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build",
@@ -15,6 +18,9 @@
"run-build-claims": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite build",
"run-build-reloadsw-claims": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true vite build",
"run-build-sw": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true vite build",
+ "run-build-sw-reloadsw": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true SW=true vite build",
+ "run-build-sw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true SW=true vite build",
+ "run-build-sw-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true vite build",
"serve": "serve dist"
},
"dependencies": {
@@ -30,6 +36,7 @@
"typescript": "^4.4.4",
"vite": "^2.6.14",
"vite-plugin-pwa": "workspace:*",
+ "workbox-core": "^6.4.0",
"workbox-precaching": "^6.4.0",
"workbox-routing": "^6.4.0",
"workbox-window": "^6.4.0"
diff --git a/examples/preact-router/src/claims-sw.ts b/examples/preact-router/src/claims-sw.ts
new file mode 100644
index 00000000..02152cad
--- /dev/null
+++ b/examples/preact-router/src/claims-sw.ts
@@ -0,0 +1,17 @@
+import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching'
+import { clientsClaim } from 'workbox-core'
+import { registerRoute, NavigationRoute } from 'workbox-routing'
+
+declare let self: ServiceWorkerGlobalScope
+
+// self.__WB_MANIFEST is default injection point
+precacheAndRoute(self.__WB_MANIFEST)
+
+// clean old assets
+cleanupOutdatedCaches()
+
+// to allow work offline
+registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html')))
+
+self.skipWaiting()
+clientsClaim()
diff --git a/examples/preact-router/src/sw.ts b/examples/preact-router/src/prompt-sw.ts
similarity index 100%
rename from examples/preact-router/src/sw.ts
rename to examples/preact-router/src/prompt-sw.ts
diff --git a/examples/preact-router/vite.config.ts b/examples/preact-router/vite.config.ts
index 47475b19..8b3dcbb6 100644
--- a/examples/preact-router/vite.config.ts
+++ b/examples/preact-router/vite.config.ts
@@ -33,22 +33,23 @@ const pwaOptions: Partial = {
}
const replaceOptions = { __DATE__: new Date().toISOString() }
+const claims = process.env.CLAIMS === 'true'
+const reload = process.env.RELOAD_SW === 'true'
if (process.env.SW === 'true') {
pwaOptions.srcDir = 'src'
- pwaOptions.filename = 'sw.ts'
+ pwaOptions.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts'
pwaOptions.strategies = 'injectManifest'
;(pwaOptions.manifest as Partial).name = 'PWA Inject Manifest'
;(pwaOptions.manifest as Partial).short_name = 'PWA Inject'
}
-else {
- if (process.env.CLAIMS === 'true')
- pwaOptions.registerType = 'autoUpdate'
- if (process.env.RELOAD_SW === 'true') {
- // @ts-ignore
- replaceOptions.__RELOAD_SW__ = 'true'
- }
+if (claims)
+ pwaOptions.registerType = 'autoUpdate'
+
+if (reload) {
+ // @ts-ignore
+ replaceOptions.__RELOAD_SW__ = 'true'
}
// https://vitejs.dev/config/
diff --git a/examples/react-router/package.json b/examples/react-router/package.json
index 79a574d4..a4f19821 100644
--- a/examples/react-router/package.json
+++ b/examples/react-router/package.json
@@ -8,6 +8,9 @@
"start-claims": "npm run run-build-claims && npm run serve",
"start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run serve",
"start-sw": "npm run run-build-sw && npm run serve",
+ "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run serve",
+ "start-sw-claims": "npm run run-build-sw-claims && npm run serve",
+ "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run serve",
"dev": "cross-env DEBUG=vite-plugin-pwa:* vite",
"build": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build",
"run-build": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build",
@@ -15,6 +18,9 @@
"run-build-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite build",
"run-build-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true vite build",
"run-build-sw": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true vite build",
+ "run-build-sw-reloadsw": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true SW=true vite build",
+ "run-build-sw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true SW=true vite build",
+ "run-build-sw-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true vite build",
"serve": "serve dist"
},
"dependencies": {
@@ -37,6 +43,7 @@
"typescript": "^4.4.4",
"vite": "^2.6.14",
"vite-plugin-pwa": "workspace:*",
+ "workbox-core": "^6.4.0",
"workbox-precaching": "^6.4.0",
"workbox-routing": "^6.4.0",
"workbox-window": "^6.4.0"
diff --git a/examples/react-router/src/claims-sw.ts b/examples/react-router/src/claims-sw.ts
new file mode 100644
index 00000000..02152cad
--- /dev/null
+++ b/examples/react-router/src/claims-sw.ts
@@ -0,0 +1,17 @@
+import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching'
+import { clientsClaim } from 'workbox-core'
+import { registerRoute, NavigationRoute } from 'workbox-routing'
+
+declare let self: ServiceWorkerGlobalScope
+
+// self.__WB_MANIFEST is default injection point
+precacheAndRoute(self.__WB_MANIFEST)
+
+// clean old assets
+cleanupOutdatedCaches()
+
+// to allow work offline
+registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html')))
+
+self.skipWaiting()
+clientsClaim()
diff --git a/examples/react-router/src/sw.ts b/examples/react-router/src/prompt-sw.ts
similarity index 100%
rename from examples/react-router/src/sw.ts
rename to examples/react-router/src/prompt-sw.ts
diff --git a/examples/react-router/vite.config.ts b/examples/react-router/vite.config.ts
index fbd77f92..30a8bf94 100644
--- a/examples/react-router/vite.config.ts
+++ b/examples/react-router/vite.config.ts
@@ -33,22 +33,23 @@ const pwaOptions: Partial = {
}
const replaceOptions = { __DATE__: new Date().toISOString() }
+const claims = process.env.CLAIMS === 'true'
+const reload = process.env.RELOAD_SW === 'true'
if (process.env.SW === 'true') {
pwaOptions.srcDir = 'src'
- pwaOptions.filename = 'sw.ts'
+ pwaOptions.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts'
pwaOptions.strategies = 'injectManifest'
;(pwaOptions.manifest as Partial).name = 'PWA Inject Manifest'
;(pwaOptions.manifest as Partial).short_name = 'PWA Inject'
}
-else {
- if (process.env.CLAIMS === 'true')
- pwaOptions.registerType = 'autoUpdate'
- if (process.env.RELOAD_SW === 'true') {
- // @ts-ignore
- replaceOptions.__RELOAD_SW__ = 'true'
- }
+if (claims)
+ pwaOptions.registerType = 'autoUpdate'
+
+if (reload) {
+ // @ts-ignore
+ replaceOptions.__RELOAD_SW__ = 'true'
}
export default defineConfig({
diff --git a/examples/solid-router/package.json b/examples/solid-router/package.json
index af46b0eb..b3c622c5 100644
--- a/examples/solid-router/package.json
+++ b/examples/solid-router/package.json
@@ -8,6 +8,9 @@
"start-claims": "npm run run-build-claims && npm run serve",
"start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run serve",
"start-sw": "npm run run-build-sw && npm run serve",
+ "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run serve",
+ "start-sw-claims": "npm run run-build-sw-claims && npm run serve",
+ "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run serve",
"dev": "cross-env DEBUG=vite-plugin-pwa:* vite",
"build": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build",
"run-build": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build",
@@ -15,6 +18,9 @@
"run-build-claims": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite build",
"run-build-reloadsw-claims": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true vite build",
"run-build-sw": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true vite build",
+ "run-build-sw-reloadsw": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true SW=true vite build",
+ "run-build-sw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite SW=true build",
+ "run-build-sw-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true vite build",
"serve": "serve dist"
},
"devDependencies": {
@@ -26,6 +32,7 @@
"vite": "^2.6.14",
"vite-plugin-pwa": "workspace:*",
"vite-plugin-solid": "^2.1.2",
+ "workbox-core": "^6.4.0",
"workbox-precaching": "^6.4.0",
"workbox-routing": "^6.4.0",
"workbox-window": "^6.4.0"
diff --git a/examples/solid-router/src/ReloadPrompt.tsx b/examples/solid-router/src/ReloadPrompt.tsx
index 4dfbfc01..957ccd81 100644
--- a/examples/solid-router/src/ReloadPrompt.tsx
+++ b/examples/solid-router/src/ReloadPrompt.tsx
@@ -40,18 +40,18 @@ const ReloadPrompt: Component = () => {
-
- New content available, click on reload button to update.}
- when={offlineReady()}
- >
- App ready to work offline
-
-
-
-
-
-
+
+ New content available, click on reload button to update.}
+ when={offlineReady()}
+ >
+ App ready to work offline
+
+
+
+
+
+
diff --git a/examples/solid-router/src/claims-sw.ts b/examples/solid-router/src/claims-sw.ts
new file mode 100644
index 00000000..02152cad
--- /dev/null
+++ b/examples/solid-router/src/claims-sw.ts
@@ -0,0 +1,17 @@
+import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching'
+import { clientsClaim } from 'workbox-core'
+import { registerRoute, NavigationRoute } from 'workbox-routing'
+
+declare let self: ServiceWorkerGlobalScope
+
+// self.__WB_MANIFEST is default injection point
+precacheAndRoute(self.__WB_MANIFEST)
+
+// clean old assets
+cleanupOutdatedCaches()
+
+// to allow work offline
+registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html')))
+
+self.skipWaiting()
+clientsClaim()
diff --git a/examples/solid-router/src/sw.ts b/examples/solid-router/src/prompt-sw.ts
similarity index 100%
rename from examples/solid-router/src/sw.ts
rename to examples/solid-router/src/prompt-sw.ts
diff --git a/examples/solid-router/vite.config.ts b/examples/solid-router/vite.config.ts
index 22055b3c..728d1cee 100644
--- a/examples/solid-router/vite.config.ts
+++ b/examples/solid-router/vite.config.ts
@@ -33,22 +33,23 @@ const pwaOptions: Partial = {
}
const replaceOptions = { __DATE__: new Date().toISOString() }
+const claims = process.env.CLAIMS === 'true'
+const reload = process.env.RELOAD_SW === 'true'
if (process.env.SW === 'true') {
pwaOptions.srcDir = 'src'
- pwaOptions.filename = 'sw.ts'
+ pwaOptions.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts'
pwaOptions.strategies = 'injectManifest'
;(pwaOptions.manifest as Partial).name = 'PWA Inject Manifest'
;(pwaOptions.manifest as Partial).short_name = 'PWA Inject'
}
-else {
- if (process.env.CLAIMS === 'true')
- pwaOptions.registerType = 'autoUpdate'
- if (process.env.RELOAD_SW === 'true') {
- // @ts-ignore
- replaceOptions.__RELOAD_SW__ = 'true'
- }
+if (claims)
+ pwaOptions.registerType = 'autoUpdate'
+
+if (reload) {
+ // @ts-ignore
+ replaceOptions.__RELOAD_SW__ = 'true'
}
export default defineConfig({
diff --git a/examples/svelte-routify/package.json b/examples/svelte-routify/package.json
index a685f066..cb7e5b98 100644
--- a/examples/svelte-routify/package.json
+++ b/examples/svelte-routify/package.json
@@ -9,6 +9,9 @@
"start-claims": "npm run run-build-claims && npm run serve",
"start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run serve",
"start-sw": "npm run run-build-sw && npm run serve",
+ "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run serve",
+ "start-sw-claims": "npm run run-build-sw-claims && npm run serve",
+ "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run serve",
"dev": "cross-env DEBUG=vite-plugin-pwa:* vite",
"build": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build",
"run-build": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build",
@@ -16,6 +19,9 @@
"run-build-claims": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite build",
"run-build-reloadsw-claims": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true vite build",
"run-build-sw": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true vite build",
+ "run-build-sw-reloadsw": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true vite build",
+ "run-build-sw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true SW=true vite build",
+ "run-build-sw-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true vite build",
"serve": "serve dist"
},
"devDependencies": {
@@ -33,6 +39,7 @@
"svelte-preprocess": "^4.9.8",
"typescript": "^4.4.4",
"vite": "^2.6.14",
+ "workbox-core": "^6.4.0",
"workbox-precaching": "^6.4.0",
"workbox-routing": "^6.4.0",
"vite-plugin-pwa": "workspace:*"
diff --git a/examples/svelte-routify/src/claims-sw.ts b/examples/svelte-routify/src/claims-sw.ts
new file mode 100644
index 00000000..02152cad
--- /dev/null
+++ b/examples/svelte-routify/src/claims-sw.ts
@@ -0,0 +1,17 @@
+import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching'
+import { clientsClaim } from 'workbox-core'
+import { registerRoute, NavigationRoute } from 'workbox-routing'
+
+declare let self: ServiceWorkerGlobalScope
+
+// self.__WB_MANIFEST is default injection point
+precacheAndRoute(self.__WB_MANIFEST)
+
+// clean old assets
+cleanupOutdatedCaches()
+
+// to allow work offline
+registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html')))
+
+self.skipWaiting()
+clientsClaim()
diff --git a/examples/svelte-routify/src/lib/ReloadPrompt.svelte b/examples/svelte-routify/src/lib/ReloadPrompt.svelte
index efdb408b..55777b35 100644
--- a/examples/svelte-routify/src/lib/ReloadPrompt.svelte
+++ b/examples/svelte-routify/src/lib/ReloadPrompt.svelte
@@ -65,30 +65,30 @@
{buildDate}
diff --git a/examples/svelte-routify/src/sw.ts b/examples/svelte-routify/src/prompt-sw.ts
similarity index 100%
rename from examples/svelte-routify/src/sw.ts
rename to examples/svelte-routify/src/prompt-sw.ts
diff --git a/examples/svelte-routify/vite.config.js b/examples/svelte-routify/vite.config.js
index 5c5477bd..0be8cc68 100644
--- a/examples/svelte-routify/vite.config.js
+++ b/examples/svelte-routify/vite.config.js
@@ -33,22 +33,23 @@ const pwaOptions = {
}
const replaceOptions = { __DATE__: new Date().toISOString() }
+const claims = process.env.CLAIMS === 'true'
+const reload = process.env.RELOAD_SW === 'true'
if (process.env.SW === 'true') {
pwaOptions.srcDir = 'src'
- pwaOptions.filename = 'sw.ts'
+ pwaOptions.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts'
pwaOptions.strategies = 'injectManifest'
pwaOptions.manifest.name = 'PWA Inject Manifest'
pwaOptions.manifest.short_name = 'PWA Inject'
}
-else {
- if (process.env.CLAIMS === 'true')
- pwaOptions.registerType = 'autoUpdate'
- if (process.env.RELOAD_SW === 'true') {
- // @ts-ignore
- replaceOptions.__RELOAD_SW__ = 'true'
- }
+if (claims)
+ pwaOptions.registerType = 'autoUpdate'
+
+if (reload) {
+ // @ts-ignore
+ replaceOptions.__RELOAD_SW__ = 'true'
}
export default defineConfig({
diff --git a/examples/sveltekit-pwa/.eslintrc.cjs b/examples/sveltekit-pwa/.eslintrc.cjs
new file mode 100644
index 00000000..6ad4bdd7
--- /dev/null
+++ b/examples/sveltekit-pwa/.eslintrc.cjs
@@ -0,0 +1,20 @@
+module.exports = {
+ root: true,
+ parser: '@typescript-eslint/parser',
+ extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
+ plugins: ['svelte3', '@typescript-eslint'],
+ ignorePatterns: ['*.cjs'],
+ overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
+ settings: {
+ 'svelte3/typescript': () => require('typescript')
+ },
+ parserOptions: {
+ sourceType: 'module',
+ ecmaVersion: 2019
+ },
+ env: {
+ browser: true,
+ es2017: true,
+ node: true
+ }
+};
diff --git a/examples/sveltekit-pwa/.gitignore b/examples/sveltekit-pwa/.gitignore
new file mode 100644
index 00000000..bbde1f50
--- /dev/null
+++ b/examples/sveltekit-pwa/.gitignore
@@ -0,0 +1,7 @@
+.DS_Store
+node_modules
+/build
+/.svelte-kit
+/package
+.env
+.env.*
diff --git a/examples/sveltekit-pwa/README.md b/examples/sveltekit-pwa/README.md
new file mode 100644
index 00000000..82510ca0
--- /dev/null
+++ b/examples/sveltekit-pwa/README.md
@@ -0,0 +1,38 @@
+# create-svelte
+
+Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte);
+
+## Creating a project
+
+If you're seeing this, you've probably already done this step. Congrats!
+
+```bash
+# create a new project in the current directory
+npm init svelte@next
+
+# create a new project in my-app
+npm init svelte@next my-app
+```
+
+> Note: the `@next` is temporary
+
+## Developing
+
+Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
+
+```bash
+npm run dev
+
+# or start the server and open the app in a new browser tab
+npm run dev -- --open
+```
+
+## Building
+
+Before creating a production version of your app, install an [adapter](https://kit.svelte.dev/docs#adapters) for your target environment. Then:
+
+```bash
+npm run build
+```
+
+> You can preview the built app with `npm run preview`, regardless of whether you installed an adapter. This should _not_ be used to serve your app in production.
diff --git a/examples/sveltekit-pwa/package.json b/examples/sveltekit-pwa/package.json
new file mode 100644
index 00000000..ace54907
--- /dev/null
+++ b/examples/sveltekit-pwa/package.json
@@ -0,0 +1,53 @@
+{
+ "name": "example-sveltekit-pwa",
+ "version": "0.0.0",
+ "private": true,
+ "scripts": {
+ "dev": "svelte-kit dev",
+ "build": "svelte-kit build",
+ "package": "svelte-kit package",
+ "preview": "svelte-kit preview",
+ "check": "svelte-check --tsconfig ./tsconfig.json",
+ "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
+ "lint": "eslint --ignore-path .gitignore .",
+ "start": "npm run run-build && npm run preview",
+ "start-reloadsw": "npm run run-build-reloadsw && npm run preview",
+ "start-claims": "npm run run-build-claims && npm run preview",
+ "start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run preview",
+ "start-sw": "npm run run-build-sw && npm run preview",
+ "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run preview",
+ "start-sw-claims": "npm run run-build-sw-claims && npm run preview",
+ "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run preview",
+ "run-build": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true",
+ "run-build-reloadsw": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --RELOAD_SW=true",
+ "run-build-claims": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --CLAIMS=true",
+ "run-build-reloadsw-claims": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --CLAIMS=true --RELOAD_SW=true",
+ "run-build-sw": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --SW=true",
+ "run-build-sw-reloadsw": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --RELOAD_SW=true --SW=true",
+ "run-build-sw-claims": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --CLAIMS=true --SW=true",
+ "run-build-sw-reloadsw-claims": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --CLAIMS=true --RELOAD_SW=true --SW=true"
+ },
+ "devDependencies": {
+ "@rollup/plugin-replace": "^3.0.0",
+ "@sveltejs/adapter-static": "next",
+ "@sveltejs/kit": "next",
+ "@typescript-eslint/eslint-plugin": "^4.31.1",
+ "@typescript-eslint/parser": "^4.31.1",
+ "cross-env": "^7.0.3",
+ "eslint": "^7.32.0",
+ "eslint-plugin-svelte3": "^3.2.1",
+ "https-localhost": "^4.7.0",
+ "minimist": "^1.2.5",
+ "rimraf": "^3.0.2",
+ "svelte": "^3.44.1",
+ "svelte-check": "^2.2.8",
+ "svelte-preprocess": "^4.9.8",
+ "tslib": "^2.3.1",
+ "typescript": "^4.4.4",
+ "workbox-core": "^6.4.0",
+ "workbox-precaching": "^6.4.0",
+ "workbox-routing": "^6.4.0",
+ "vite-plugin-pwa": "workspace:*"
+ },
+ "type": "module"
+}
diff --git a/examples/sveltekit-pwa/pwa-configuration.js b/examples/sveltekit-pwa/pwa-configuration.js
new file mode 100644
index 00000000..f150c260
--- /dev/null
+++ b/examples/sveltekit-pwa/pwa-configuration.js
@@ -0,0 +1,89 @@
+const pwaConfiguration = {
+ srcDir: './build',
+ outDir: './.svelte-kit/output/client',
+ mode: 'development',
+ includeManifestIcons: false,
+ scope: '/',
+ base: '/',
+ manifest: {
+ short_name: "PWA Router",
+ name: "PWA Router",
+ start_url: "/",
+ scope: "/",
+ display: "standalone",
+ theme_color: "#ffffff",
+ background_color: "#ffffff",
+ icons: [
+ {
+ src: '/pwa-192x192.png',
+ sizes: '192x192',
+ type: 'image/png',
+ },
+ {
+ src: '/pwa-512x512.png',
+ sizes: '512x512',
+ type: 'image/png',
+ },
+ {
+ src: '/pwa-512x512.png',
+ sizes: '512x512',
+ type: 'image/png',
+ purpose: 'any maskable',
+ },
+ ]
+ },
+}
+
+const claims = process.env.CLAIMS === 'true'
+const reload = process.env.RELOAD_SW === 'true'
+const sw = process.env.SW === 'true'
+const replaceOptions = {
+ __DATE__: new Date().toISOString(),
+ __RELOAD_SW__: reload ? 'true' : 'false',
+}
+
+const workboxOrInjectManifestEntry = {
+ // vite and SvelteKit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work
+ dontCacheBustURLsMatching: /-[a-f0-9]{8}\./,
+ globDirectory: './build/',
+ globPatterns: ['**/*.{js,css,html,ico,png,svg,webmanifest}'],
+ globIgnores: sw ? (claims ? ['**/claims-sw*'] : ['**/prompt-sw*']) : ['**/sw*', '**/workbox-*'],
+ // Before generating the service worker, manifestTransforms entry will allow us to transform the resulting precache manifest. See the manifestTransforms docs for mode details.
+ manifestTransforms: [async(entries) => {
+ // manifest.webmanifest is added always by pwa plugin, so we remove it.
+ // EXCLUDE from the sw precache sw and workbox-*
+ const manifest = entries.filter(({ url }) =>
+ url !== 'manifest.webmanifest' && !url.endsWith('sw.js') && !url.startsWith('workbox-')
+ ).map((e) => {
+ let url = e.url
+ if (url && url.endsWith('.html')) {
+ if (url.startsWith('/'))
+ url = url.slice(1)
+
+ e.url = url === 'index.html' ? '/' : `/${url.substring(0, url.lastIndexOf('/'))}`
+ console.log(`${url} => ${e.url}`)
+ }
+
+ return e
+ })
+ return { manifest }
+ }]
+}
+
+if (sw) {
+ pwaConfiguration.srcDir = 'src'
+ pwaConfiguration.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts'
+ pwaConfiguration.strategies = 'injectManifest'
+ pwaConfiguration.manifest.name = 'PWA Inject Manifest'
+ pwaConfiguration.manifest.short_name = 'PWA Inject'
+ pwaConfiguration.injectManifest = workboxOrInjectManifestEntry
+} else {
+ workboxOrInjectManifestEntry.mode = 'development'
+ workboxOrInjectManifestEntry.navigateFallback = '/'
+ pwaConfiguration.workbox = workboxOrInjectManifestEntry
+}
+
+if (claims)
+ pwaConfiguration.registerType = 'autoUpdate'
+
+export { pwaConfiguration, replaceOptions }
diff --git a/examples/sveltekit-pwa/pwa.js b/examples/sveltekit-pwa/pwa.js
new file mode 100644
index 00000000..ff4b347c
--- /dev/null
+++ b/examples/sveltekit-pwa/pwa.js
@@ -0,0 +1,57 @@
+import { resolveConfig } from 'vite'
+import replace from '@rollup/plugin-replace'
+import { VitePWA } from 'vite-plugin-pwa'
+import { copyFileSync } from 'fs'
+import minimist from 'minimist'
+
+const args = minimist(process.argv.slice(2))
+
+process.env.CLAIMS = `${args['CLAIMS'] === 'true'}`
+process.env.RELOAD_SW = `${args['RELOAD_SW'] === 'true'}`
+process.env.SW = `${args['SW'] === 'true'}`
+
+const webmanifestDestinations = [
+ './.svelte-kit/output/client/',
+ './build/',
+]
+
+const swDestinations = [
+ './build/',
+]
+
+const buildPwa = async() => {
+ const { pwaConfiguration, replaceOptions } = await import('./pwa-configuration.js')
+ const config = await resolveConfig({
+ plugins: [
+ VitePWA(pwaConfiguration),
+ replace(replaceOptions),
+ ]
+ },
+ 'build',
+ 'production'
+ )
+ // when `vite-plugin-pwa` is presented, 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, svelte kit will copy it
+ if (pwaConfiguration.strategies === 'injectManifest') {
+ const destName = pwaConfiguration.registerType === 'autoUpdate' ? 'claims-sw.js' : 'prompt-sw.js'
+ const name = `./.svelte-kit/output/client/${destName}`
+ swDestinations.forEach(d => {
+ copyFileSync(name, `${d}/${destName}`)
+ })
+ } else {
+ swDestinations.forEach(d => {
+ copyFileSync('./.svelte-kit/output/client/sw.js', `${d}/sw.js`)
+ })
+ }
+ console.log('Generation of PWA complete')
+ }
+}
+
+buildPwa()
diff --git a/examples/sveltekit-pwa/src/app.html b/examples/sveltekit-pwa/src/app.html
new file mode 100644
index 00000000..2238847d
--- /dev/null
+++ b/examples/sveltekit-pwa/src/app.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+ %svelte.head%
+
+
+
%svelte.body%
+
+
diff --git a/examples/sveltekit-pwa/src/claims-sw.ts b/examples/sveltekit-pwa/src/claims-sw.ts
new file mode 100644
index 00000000..65d55450
--- /dev/null
+++ b/examples/sveltekit-pwa/src/claims-sw.ts
@@ -0,0 +1,17 @@
+import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching'
+import { clientsClaim } from 'workbox-core'
+import { registerRoute, NavigationRoute } from 'workbox-routing'
+
+declare let self: ServiceWorkerGlobalScope
+
+// self.__WB_MANIFEST is default injection point
+precacheAndRoute(self.__WB_MANIFEST)
+
+// clean old assets
+cleanupOutdatedCaches()
+
+// to allow work offline
+registerRoute(new NavigationRoute(createHandlerBoundToURL('/')))
+
+self.skipWaiting()
+clientsClaim()
diff --git a/examples/sveltekit-pwa/src/global.d.ts b/examples/sveltekit-pwa/src/global.d.ts
new file mode 100644
index 00000000..815c61ad
--- /dev/null
+++ b/examples/sveltekit-pwa/src/global.d.ts
@@ -0,0 +1,4 @@
+///
+///
+///
+///
diff --git a/examples/sveltekit-pwa/src/lib/components/Counter.svelte b/examples/sveltekit-pwa/src/lib/components/Counter.svelte
new file mode 100644
index 00000000..e3cefc5f
--- /dev/null
+++ b/examples/sveltekit-pwa/src/lib/components/Counter.svelte
@@ -0,0 +1,34 @@
+
+
+
+
+
diff --git a/examples/sveltekit-pwa/src/lib/components/Go.svelte b/examples/sveltekit-pwa/src/lib/components/Go.svelte
new file mode 100644
index 00000000..ce98478b
--- /dev/null
+++ b/examples/sveltekit-pwa/src/lib/components/Go.svelte
@@ -0,0 +1,52 @@
+
+
+
+
+
diff --git a/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte b/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte
new file mode 100644
index 00000000..6c907074
--- /dev/null
+++ b/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte
@@ -0,0 +1,87 @@
+
+
+{#if toast}
+
+
+ {#if $offlineReady}
+
+ App ready to work offline
+
+ {:else}
+
+ New content available, click on reload button to update.
+
+ {/if}
+
+ {#if $needRefresh}
+
+ {/if}
+
+
+{/if}
+
+
{buildDate}
+
+
diff --git a/examples/sveltekit-pwa/src/prompt-sw.ts b/examples/sveltekit-pwa/src/prompt-sw.ts
new file mode 100644
index 00000000..39a74fcf
--- /dev/null
+++ b/examples/sveltekit-pwa/src/prompt-sw.ts
@@ -0,0 +1,18 @@
+import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching'
+import { registerRoute, NavigationRoute } from 'workbox-routing'
+
+declare let self: ServiceWorkerGlobalScope
+
+self.addEventListener('message', (event) => {
+ if (event.data && event.data.type === 'SKIP_WAITING')
+ self.skipWaiting()
+})
+
+// self.__WB_MANIFEST is default injection point
+precacheAndRoute(self.__WB_MANIFEST)
+
+// clean old assets
+cleanupOutdatedCaches()
+
+// to allow work offline
+registerRoute(new NavigationRoute(createHandlerBoundToURL('/')))
diff --git a/examples/sveltekit-pwa/src/routes/__layout.svelte b/examples/sveltekit-pwa/src/routes/__layout.svelte
new file mode 100644
index 00000000..f5391c6d
--- /dev/null
+++ b/examples/sveltekit-pwa/src/routes/__layout.svelte
@@ -0,0 +1,58 @@
+
+
+
+ {#if (!dev && browser)}
+
+ {/if}
+
+
+
+
+