Git Product home page Git Product logo

Comments (51)

kyllerss avatar kyllerss commented on August 17, 2024 2

I ran into the same problem. In my case, I am using the adapter-netlify. I will admit much of this is over my head. I tried some of the initial suggestions, but I feel the conversation moved beyond my understanding of the internals of the frameworks involved.

Should I assume the pwa plugin will remain as is and I should work through the information in this issue, or would that work be nullified by an upcoming release that will address this issue?

Thank you all again for the great work you are doing!

from sveltekit.

userquin avatar userquin commented on August 17, 2024 2

@kyllerss pwa plugin is just a wrapper for workbox-build, that is file based, that's, to generate the sw precache manifest (injection point/self.__WB_MANIFEST) it will traverse a folder, and so kit integration will configure pwa plugin to run after prerender but before adapter processes in kit/vite lifecycle: we need the assets but also the prerendered pages.

Once prerender finish, pwa plugin will call workbox-build to generate the sw precache manifest: we need to configure pwa plugin properly via globDirectory on workbox or injectManifest : workbox-build will use globDirectory to traverse it and generate the sw with the sw precache manifest. We also need to configure properly the output folder, that's, the sw.js should be generated in the kit output build folder, that adapter will copy to the final build folder.

Once we have configured the pwa plugin, we can add some hooks to workbox-build before sw.js is written to disk: kit integration adds a ManifestTransform (will receive file paths in globDirectory and their revision/hash, a list of ManifestEntry objects) to apply some custom transformations (pretty url and fallback url for adapter). You can check it here, the config module has a few comments about kit output folder: https://github.com/vite-pwa/sveltekit/blob/main/src/config.ts#L60

With latest vite-plugin-pwa version released 0.14.0 (kit integration not updated nor released yet) we can use custom sw without injection point (I also need to update the docs to add this new option).

from sveltekit.

kyllerss avatar kyllerss commented on August 17, 2024 2

Hi, checking in. Is the fix for this one on the roadmap or is there some workaround I should be applying in the meantime (wasn't clear from the comments). Thanks!

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024 1

@userquin I am using the standard service worker.

import {
	cleanupOutdatedCaches,
	createHandlerBoundToURL,
	precacheAndRoute
} from 'workbox-precaching';
import { NavigationRoute, registerRoute } 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();

let allowlist: undefined | RegExp[];
if (import.meta.env.DEV) allowlist = [/^\/$/];

// to allow work offline
registerRoute(new NavigationRoute(createHandlerBoundToURL('/'), { allowlist }));

After removing the offline part, the service worker is working fine. But what If I want to use the offline mode?

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024 1

@Cluster2a can you create a minimal repro?

https://github.com/Cluster2a/pwa_examle - same stuff with the wrong URLs.

from sveltekit.

userquin avatar userquin commented on August 17, 2024 1

@Cluster2a I'll check it tmr, thx

from sveltekit.

ktecho avatar ktecho commented on August 17, 2024 1

This is also failing for me. I'll try the SvelteKit suplied service worker, but it would be cool to have a big notice saying vite-pwa doesn't work in SvelteKit if you're using adapter-node` so we don't lose so much time trying to guess what happens.

from sveltekit.

smart avatar smart commented on August 17, 2024 1

I'm still having this issue with the latest with adapter-auto deployed on vercel. Simultaneously I'm also struggling where my default route in development seems to be caching a redirect (but rendering the content from the redirect at the / route). I'm going to keep diving in, but wanted to give a heads up. vite config below.

SvelteKitPWA({ srcDir: './src', mode: process.env.NODE_ENV, // will default to process.env.NODE_ENV scope: '/', base: '/', selfDestroying: process.env.SELF_DESTROYING_SW === 'true', manifest: { short_name: 'XXXX', name: 'XXXX', start_url: '/', scope: '/', display: 'standalone', theme_color: "#ffffff", background_color: "#ffffff", icons: [ { "src": "/icon-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/icon-256x256.png", "sizes": "256x256", "type": "image/png" }, { "src": "/icon-384x384.png", "sizes": "384x384", "type": "image/png" }, { "src": "/icon-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": 'any maskable', } ], }, workbox: { globPatterns: ['client/**/*.{js,css,ico,png,svg,webp,woff,woff2}'] }, devOptions: { enabled: true, type: 'module' }, // if you have shared info in svelte config file put in a separate module and use it also here kit: {} })

`

from sveltekit.

userquin avatar userquin commented on August 17, 2024 1

@phil-w You need to prerender that route, workbox requires the html file, check if the index.html is present in your kit output folder, inside prerender folder

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a can you shared your pwa plugin options?

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

Hey - sure! Her you go.

SvelteKitPWA({
	srcDir: './src',
	mode: process.env.NODE_ENV as 'development' | 'production',
	strategies: 'injectManifest',
	filename: 'sw.ts',
	scope: '/',
	base: '/',
	injectRegister: 'script',
	includeAssets: ['favicon.ico', 'apple-touch-icon.png', '/img/mask-icon.svg'],
	manifest: {
		short_name: 'freispace',
		name: 'freispace',
		description: 'Your supercharged resource and project management.',
		start_url: '/dashboard?source=pwa',
		scope: '/',
		display: 'standalone',
		theme_color: '#006aa3',
		background_color: '#f3f4f6',
		icons: [
			{
				src: '/img/pwa-192x192.png',
				sizes: '192x192',
				type: 'image/png',
				purpose: 'any'
			},
			{
				src: '/img/pwa-512x512.png',
				sizes: '512x512',
				type: 'image/png',
				purpose: 'any'
			},
			{
				src: '/img/favicon.svg',
				sizes: 'any',
				type: 'image/svg+xml',
				purpose: 'any'
			}
		],
		shortcuts: [
			{
				name: 'freispace Dashboard',
				short_name: 'Dashboard',
				url: '/dashboard?source=pwa',
				icons: [
					{
						src: '/img/pwa-dashboard.png',
						type: 'image/png',
						sizes: '96x96'
					},
					{
						src: '/img/pwa-dashboard.svg',
						type: 'image/svg+xml',
						sizes: 'any'
					}
				]
			},
			{
				name: 'freispace Planner',
				short_name: 'Planner',
				url: '/planning/overview?source=pwa',
				icons: [
					{
						src: '/img/pwa-planner.png',
						type: 'image/png',
						sizes: '96x96'
					},
					{
						src: '/img/pwa-planner.svg',
						type: 'image/svg+xml',
						sizes: 'any'
					}
				]
			}
		]
	},
	injectManifest: {
		globPatterns: ['client/**/*.{js,css,ico,png,svg,webp,woff,woff2}']
	},
	devOptions: {
		enabled: true,
		type: 'module',
		navigateFallback: '/'
	}
})

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a can you share your sw.ts?

EDIT: you can try removing offline route:

// to allow work offline
registerRoute(new NavigationRoute(
  createHandlerBoundToURL('/'),
  { allowlist },
))

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

@userquin, what if I want to use the offline mode?
Removing this is just like a workaround but not a real fix, or am I mistaken here?

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a try configuring /404 adding +error.svelte with prerender enabled in +error.ts: export const prerender = true;.

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

image

image

@userquin do you mean like this? It doesn't work either:
image

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

@userquin, ah I see - you asked for an +error.ts. This does not seem to be allowed in svelteKit:
image

To make it a little bit more clear, my app is calling an API in the hooks.server.ts. Because of this, I am disabling the prerendering in the svelte.config.js.

I could enable this again and only pre-render the 404, but according to the svelteKit documentation, there is no way to set pretender = true for the error-page.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a try adding it at least to the entry point (/: +page.ts), if there is no prerender we cannot fallback to any url...

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a have you tried to just request some missing page without the offline entry?

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a the docs allows you to create an error.html under src folder, check where it is copied then use it as fallback:

https://kit.svelte.dev/docs/routing#error

imagen

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

@userquin I created a /sw/+page.svelte & /sw/+page.ts (prerender = true).

registerRoute(new NavigationRoute(createHandlerBoundToURL('/sw'), { allowlist }));

I also excluded this route from my hook.
This seems to work now.

Is this a valid way to handle this?

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

I also checked the fallback error:
image
But I wasn't able to access it via URL.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a what adapter are you using? try adding the fallback to kit adapter config file and also to kit entry in pwa options:

https://vite-pwa-org.netlify.app/frameworks/sveltekit.html#sveltekit-and-adapters

The fallback is always generated, the adapter should copy it to the build folder... if you don't add the fallback to the adapter, the page will not be copied

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

@userquin, i am using @sveltejs/adapter-node.
I am not aware of the fallback option. I need to check that out.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a you can check this repo (using static adapter):

EDIT: what's the build folder for adapter node? can you check if the fallback is there? Your previous screenshot is the kit output.

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

@userquin, I can not use the static adapter since I am using server-side endpoints which are not supported by this adapter.

The node-adapter does not seem to accept a fallback option.

My build folder looks like this:
image

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a it is using also build folder, and it is copying all client and prerendered folders, so we need to add a custom manifestTransform to the pwa plugin: just check the code in the config.ts module in this repo.

The layout is different, static-adapter will copy the client and prerendered folders contents in the build folder, adapter node will copy also the client and the prerendered to the build.

EDIT: Im think we don't need to change it, it is a problem serving assets: what is the url for /sw? it should be /sw and not /prerendered/sw so you need a hack to serve any generated html page.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

The node-adapter does not seem to accept a fallback option.

Then, how the adapter serves the client assets? Maybe you only need to add a node/express middleware, when requesting /sw just serve the content from prerendered/sw.html.

EDIT: the client and the prerender folders are part of the request? if so, you will need to change the manifestTransform. Can you share the repo? I can review the vite pwa kit integration to add custom manifestTransform for each adapter.

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

EDIT: Im think we don't need to change it, it is a problem serving assets: what is the url for /sw? it should be /sw and not /prerendered/sw so you need a hack to serve any generated html page.

@userquin I think you got me wrong... When requesting /sw the prerendered/sw.html is served correctly and the service worker is working.
But somehow this feels kind of hacky to create a custom pre-rendered page and exclude it in my hook just for the service worker to work correctly.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a configure /sw in the offline route: try requesting some non existing route/page

EDIT: I was checking the adapter hander, it has 3 serve entries forwarding content from static, client and prerendered folder: https://github.com/sveltejs/kit/blob/master/packages/adapter-node/src/handler.js#L139

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

@userquin requesting an invalid route will bring up my error-page (404). So this seems to work.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@userquin requesting an invalid route will bring up my error-page (404). So this seems to work.

try it also setting offline the browser

from sveltekit.

Cluster2a avatar Cluster2a commented on August 17, 2024

@userquin, the cache seems to be messed up:
image
All the JS files are served directly from the /_app -Folder.
When accessing the files form cache, it somehow messes up the path:
image

It is adding the folder of the route, which is wrong.

The cache seems good though:
image

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a can you create a minimal repro?

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a check this commit on my fork: userquin/vite-pwa-kit-issue-16@29fb7bc

The main problem with this approach is the navigation pages is not being cached, so you need to refresh/visit the page twice, check it, the offline support should work (since you have a login page I cannot test it).

Check also the changes in the pwa options, added useCredentials and removed includeAssets adding also the exclusion of the icons in the manifest (on kit there is no need, only when using Vite).

You can check the sw and adjust the logic, the sw logic is being called:

imagen

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@Cluster2a pushed another commit on my fork, app working but kit not showing the content (hydration problem?)

from sveltekit.

iva2k avatar iva2k commented on August 17, 2024

I'm adding @vite-pwa/sveltekit to my SvelteKit template project, and I have the same issue, though I'm using adapter-static for debugging. So I stepped through the sw.js with debugger in the browser and figured out that there is a disconnect between how the urls are actually handled and how example code shows them.

If I replace:

- registerRoute(new NavigationRoute(createHandlerBoundToURL('/sw'), { allowlist: [/^\/$/] }));
+ registerRoute(new NavigationRoute(createHandlerBoundToURL('prerendered/pages/sw.html'), { allowlist: [/^\/$/] }));
  • it gets to pass this route ok.

However, it fails further down with the 404 error trying to cache the very first item from the manifest, and the code is complaining about url:
/client/_app/immutable/assets/_layout-ba887965.css

I find the same item in the precache manifest, but without the leading slash '/':

client/_app/immutable/assets/_layout-ba887965.css

However, the request works only for:
/_app/immutable/assets/_layout-ba887965.css

@userquin - is that what your clone repo tries to do - sanitize the urls and clip the prefix?

from sveltekit.

iva2k avatar iva2k commented on August 17, 2024

I investigated further, and concluded that SW on client is wrong place to sort out the problem. Precache manifest should be handled at build time, with manifestTransforms parameter to SvelteKitPWA plugin.

Here's version that works with adapter-static, adapter-netlify and adapter-vercel (sorry, I don't have a setup to try adapter-node):

const scope = '/';

// For @sveltejs/adapter-static, @sveltejs/adapter-netlify, @sveltejs/adapter-vercel
/** @type {import('workbox-build').ManifestTransform} */
const manifestTransformStatic = async (manifestEntries) => {
  console.info('Precache Manifest Entries:');
  const manifest = manifestEntries
    .filter(
      ({ url }) =>
        // Remove paths that should not be cached:
        url !== 'client/vite-manifest.json' && url !== 'prerendered/fallback.html'
      // && url !== 'client/manifest.webmanifest' && !url.endsWith('sw.js') && !url.startsWith('workbox-')
    )
    .map((e) => {
      // Adjust paths to match what the adapter server understands:
      const url1 = e.url;
      let url = e.url;
      if (url.startsWith('/')) url = url.slice(1);
      if (url.startsWith('client/')) url = url.slice(7);
      if (url.startsWith('prerendered/pages/')) url = url.slice(18);

      // router paths
      if (url && url.endsWith('.html')) {
        url = url === 'index.html' ? '' : `${url.substring(0, url.lastIndexOf('.'))}`;
      }
      e.url = scope + url; // Canonical URL starts with base
      console.info(`  ${url1.padEnd(100)} => ${JSON.stringify(e)}`);
      return e;
    });
  return { manifest };
};
const manifestTransforms = [manifestTransformStatic];

Pass manifestTransforms to SvelteKitPWA.

from sveltekit.

iva2k avatar iva2k commented on August 17, 2024

I also checked source of @vite-pwa/sveltekit, and found it sets default manifestTransforms by createManifestTransform() which does pretty much the same as what I posted above in manifestTransformStatic(), with createManifestTransform() handling settings more thoroughly.

The reason it was not working in my case, is I had manifestTransforms set to a non-transform, just to log the precache manifest.

So for the adapter-node - it server static, client and prerender. Note that adapter-static serves prerender/pages, which means adapter-node will have /page/index.html, not /index.html. Default createManifestTransform() does not handle that case. The quick fix could be to use my manifestTransformStatic() and adjust the paths until they match what adapter-node serves.

BTW, createManifestTransform() might emit precache manifest with a duplicate entry, if fallback is set to index.html. Just note that it is a special case and handle it accordingly - precache manifest is created from list of paths found in ./.svelte-kit/output/client, and transformManifest should emit the list of paths matching what is served by the adapter.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@iva2k thx for investigating this, I have it pending, maybe we can add some presets, pr welcome

from sveltekit.

iva2k avatar iva2k commented on August 17, 2024

@userquin

thx for investigating this, I have it pending, maybe we can add some presets, pr welcome

I'd like to submit a PR, but the scope is unclear...

I'm thinking that best design would be to have createManifestTransform() coordinate with the adapter, maybe just get a map (source file -> URL destination) from the adapter and use that map, or adapter should provide the transform function, since it only knows how things will be on the server.

Another improvement is to expose / export createManifestTransform(), and allow caller to compose their array of transforms and invoke the standard one which came from the adapter in their chain. That way adapter will have a say, and custom transform added before or after can act on URLs (post) or on file paths (pre), and won't need to know how things are mapped.

Right now custom transform should know what the adapter does, but it has no context to get which adapter is used. In case of adapter-auto, there are few possible actual adapters that custom transform has to figure out. And users could make their own custom adapters. Extending adapter scope will go into sveltejs/kit repo. If that PR is rejected, there's no way to make an informed transform.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@iva2k if you provide a custom TransformManifest the plugin will no register the default one. We can add some preset folder adding there the required stuff, maybe also adding some custom configuration options, not only the TransformManifest:

https://github.com/vite-pwa/sveltekit/blob/main/src/config.ts#L56

from sveltekit.

iva2k avatar iva2k commented on August 17, 2024

@userquin

if you provide a custom TransformManifest the plugin will no register the default one

Yes. What I'm saying is if I can call createManifestTransform() and get the default transform, I could use it in my chain and do this:

  import {createManifestTransform} from '@vite-pwa/sveltekit';
  const myPreTransform = (manifest) => {... my file transforms; return manifest; }
  const myPostTransform = (manifest) => {... my URL transforms; return manifest; }
  const defaultTransform = createManifestTransform();
  const transforms = [
    myPreTransform,
    defaultTransform,
    myPostTransform 
  ];

Then just pass transforms to the plugin.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

@iva2k oh yeah, maybe we can add preManifestTransform and postManifestTransform options to the kit entry with the following logic:

  • if manifestTransform not empty, then unshift preManifestTransform and add postManifestTransform (this no makes sense, since you are adding the callbacks on the pwa workbox/injectManifest option, so can be ignored, add all in the corresponding option)
  • if manifestTransform not configured or empty then add preManifestTransform, then add default one and finally add postManifestTransform

We can also export createManifestTransform: I guess we can also add default presets for adapters (if needed).

If we need the presets for the adapters, we'll also need to add an option for the preset: in previous logic we'll use the preset instead the default one (that shhould be the default preset, similar to adapter-auto)

from sveltekit.

stellanhaglund avatar stellanhaglund commented on August 17, 2024

I'm also getting this issue with the default config provided in the docs and using adapter-auto, seems like it's preventing the service-worker to install in safari

from sveltekit.

userquin avatar userquin commented on August 17, 2024

check #30 we've detected a bug in custom manifest transform, should be fixed once new version released, in the meantime try adding the manifest transform in the PR to your workbox: { manifestTransform: [] } or injectManifest: { manifestTransform: [] } array depending on the strategy used.

from sveltekit.

ESchouten avatar ESchouten commented on August 17, 2024

So has this issue been resolved? And if so, is there a guide or demo project I can follow? The above discussion does not seem to solve this issue for me. I can't seem to get the offline caching of the pages working, receiving the same error Uncaught non-precached-url: non-precached-url :: [{"url":"/"}] when deployed to Vercel.

I want to purely store the application in cache and nothing else, the webapp can just make http requests which will be handled by the service workers.

from sveltekit.

nadanke avatar nadanke commented on August 17, 2024

@ESchouten have you tried the service worker from the SvelteKit docs? It pretty much does caching and nothing else, and it's pretty straight forward to modify.

from sveltekit.

ESchouten avatar ESchouten commented on August 17, 2024

@nadanke @ktecho Yes, that's what I am doing now, I am using the Workbox libraries and use these functions directly in Sveltekits service-worker.ts.
But since VitePWA advertises with being zero-config, I was hoping the caching & offline working part of PWAs would be automatically solved for my application.

from sveltekit.

userquin avatar userquin commented on August 17, 2024

closed via #32

from sveltekit.

phil-w avatar phil-w commented on August 17, 2024

Yeah I'm getting this too, not sure what it's about as I have a path / and it works fine, so I can't see why it'd whine about it.

from sveltekit.

phil-w avatar phil-w commented on August 17, 2024

Ah, thanks, copy that.

from sveltekit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.