Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query Parameters on the registration URL #587

Open
develohpanda opened this issue Oct 30, 2023 · 6 comments · May be fixed by #769
Open

Query Parameters on the registration URL #587

develohpanda opened this issue Oct 30, 2023 · 6 comments · May be fixed by #769

Comments

@develohpanda
Copy link

develohpanda commented Oct 30, 2023

Hi! Thank you for this wonderful plugin.

I'm working on something that would greatly benefit from being able to pass query parameters to the service worker registration URL. Something like, /sw.js?version=1.0.3. This way, within an incoming service worker I am able to do new URL(self.location).searchParams.get('version'), and pass information to an incoming service worker during updates. (See SO answer)

Example

One example of a use case would be that by sending a query parameter, I am able to convey to an incoming service worker information about the currently running application/service worker. Then, I can check whether the incoming service worker should force-install (via self.skipWaiting() and claim and refresh all clients in the activate event). I will be able to compare the version of the incoming service worker (let's say 2.0.0) with the current application (1.0.3 from the query parameter).

This is useful because it allows the incoming service worker to determine independently it's installation behavior, and we don't need to rely on currently running code (from the assets served by the existing service worker) to do the force update. This is fairly critical to my use case and I'm exploring what options are available.

// sw.js

const version = `2.0.1`;

const url = new URL(self.location);
const currentVersion = url.searchParams.get('version');
	
const shouldAutoActivate = // check whether currentVersion -> version is a minor or major upgrade

self.addEventListener('install', () => {
	if (shouldAutoActivate) {
		self.skipWaiting();
	}
});

self.addEventListener('activate', () => {
	if (shouldAutoActivate) {
		return self.clients.matchAll()
		    .then(function(clients) {
				clients.forEach(client => client.navigate(client.url))
		    });
	}
});

Alternative

Is there a way to send query parameters currently, that I am missing? I am using React, and there is not a way to use the useRegisterSW() utility hook to send query parameters, nor a way to set additional query parameters in the VitePWAOptions.

@develohpanda
Copy link
Author

Hi @userquin! I've experimented with this locally and it appears to work as intended.

I'd like to make a contribution for vite-plugin-pwa for query parameter support, and I'm wondering whether you (or another maintainer) have input towards what the API might/should look like?

I envision an additional optional property in RegisterSWOptions, used like useRegisterSW({ searchParams: '?foo=bar' }), but with that we'll need to do some funky-logic to combine these params with the dev-sw param.

Please let me know your thoughts!

@develohpanda
Copy link
Author

Hi @userquin (or @antfu), sorry to tag you numerous times! I would really appreciate your input before I embark on writing code to raise a PR. 😄

@userquin
Copy link
Member

userquin commented Dec 1, 2023

I guess we should add it to custom injectManifest configuration option, this way we can inject the query params in the client and use it also on src/plugins/dev.ts plugin, check src/client/build/register.ts module and dev.ts plugin.

Client injections can be found in src/modules.ts module.

export type CustomInjectManifestOptions = InjectManifestOptions & {

@develohpanda
Copy link
Author

develohpanda commented Dec 1, 2023

If we add query params as a property to CustomInjectManifestOptions, then the query param used in the workbox registration would need to be defined at build time, is that right? I think that works for my use case, but is there value in allowing the query params to be set at runtime via RegisterSWOptions since the params are actually used at runtime?

@userquin
Copy link
Member

userquin commented Dec 1, 2023

There should be only one source, if we add the option to the client side, dev will not work.

If we add query params as a property to CustomInjectManifestOptions, then the query param used in the workbox registration would need to be defined at build time, is that right?

No, will work also in dev (when enabled), modules.ts or html.ts modules should update __SW__ properly (I need to check dev.ts plugin, IIRC will need some update to include query params).

Anyway, I have no idea if the browser/workbox will interpret the url with params as a new sw, we need to ensure the sw is the same.

EDIT: in any case, you can register the sw yourself without using workbox-window or adding the logic in src/client/build/register.ts module (injectRegister: null and not using any virtual, IIRC there is an entry in the docs).

@Iran-110 Iran-110 linked a pull request Oct 15, 2024 that will close this issue
@Iran-110
Copy link

@develohpanda
For some advanced cache management like you said, this feature is unavoidable. I wrote it in PR #769.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants