0

Although not recommended (in this web.dev article) I have the situation of two nested PWAs:

  1. app "A" - the outer/global one, scope: "example.com"
  2. app "B" - the inner one with scope: "example.com/m/subproduct"

In both of these PWAs I can visit the page example.com/m/subproduct/test. In the JavaScript environment I'd now like to detect if the user is using app A or B for this pageview - so far without success.

I basically need a way to query the manifest info that was used during installation, but I don't think there is any JS Api to e.g. get the start-url.

I also thought about using some kind of localStorage/sessionStorage mechanism to remember the context during installation but since the domain is the same it also means that the storage scope is the same. In addition, this data could be wiped, so it's not reliable.

Using special start-urls to store something in the sessionStorage (when a certain get-parameter is detected) might be a way to differentiate sessions that are started via the app launcher, but it would also miss a lot of other ways to trigger the app-opening.

I also considered checking the currently installed/active service workers but they are the same as well.

I saw this article about a new AppID mechanism but again I don't see a way to query this ID in the JS context

Is there any way to access the currently installed manifest or any other way that I don't see to reliably detect which app is used?

The only idea I had so far was using different values for the "display" property because we can detect if it's standalone or not via this:

matchMedia('(display-mode: standalone)').matches

... but this is not really an option since I need "standalone" for both apps. I'd need something to e.g. query the theme color so I can differentiate as a workaround - any ideas?

Riesling
  • 6,343
  • 7
  • 29
  • 33

1 Answers1

0

I also considered checking the currently installed/active service workers but they are the same as well.

I think this is basically your answer, since the main differentiator will be that when you're on app "B", the relevant service worker registration will have a scope that corresponds to your narrower subsection of the site. That's what you should focus on, rather than a list of all the registered service workers for the origin.

(await navigator.serviceWorker.ready).scope should give you a value (asynchronously) that will be different depending on whether you're using "A" or "B".

Jeff Posnick
  • 53,580
  • 14
  • 141
  • 167
  • Thanks for your input, unfortunately, I don't see it working for me. I install app B on example.com/m/subproduct -> now service-worker "b" with narrow scope is installed. Next I install app A on _example.com/somewhereelse_ -> now service-worker "a" with global scope is installed. Running `(await navigator.serviceWorker.ready).scope` on _example.com/m/subproduct_ using **app A** gives me **service-worker b** as a result. – Riesling Jun 22 '22 at 06:06
  • Even if you think you're "using app A," your web client is being controlled by service worker B in that scenario, and that's what the result of that expression is telling you. I'm not sure what it means to be "using app A" given that service worker B is in control—wouldn't that be functionally equivalent to using app B? – Jeff Posnick Jun 22 '22 at 13:25
  • To a degree - yes, technically there might be no difference for the current page context but e.g. from a tracking point of view it does make a difference what is the "surrounding container", so if the user started app A or B (e.g. via the app drawer). Imagine I'd like to show some promo for app A to the users that use app B already - if I'm not sure which app they're using I might promote app A to users actually already using app A right now. That is my whole dilemma I guess, on all pages that can be consumed in both apps it will always look like it's the inner app e.g. according to the SW – Riesling Jun 22 '22 at 14:11
  • I don't think you're going to come up with a solution that meets your requirements purely client-side. The best bet might be to use a query parameter in your `start_url` to trigger setting a flag that's saved in session storage or IDB, and assume that users won't deliberate delete it. Alternatively, if you have control over the backend web server, you might be able to configure things so that when app A links to`example.com/m/subproduct`, it links to a different URL that renders the same content, like `example.com/alt/subproduct`. – Jeff Posnick Jun 22 '22 at 15:07
  • I was afraid of that, thanks a lot though - will consider that option – Riesling Jun 22 '22 at 15:47