Before Chrome 146, reloading a PWA page re-queued launchParams — causing the consumer callback to fire again on every reload. Chrome 146 fixes this: launchParams only fires once, on the initial launch. Simulate the full flow below.
Reload Count
0
Consumer Fires (v146)
0
Consumer Fires (pre-v146)
0
1. Simulate Initial Launch
Press "Launch" to simulate the PWA being opened by the OS with a target URL and a file. The consumer callback fires once with the LaunchParams object.
Chrome 146: Consumer callback fired once on initial launch. Subsequent reloads will NOT re-fire the consumer. The launchParams count stays at 1.
2. Reload Behaviour
Reload does not re-queue launchParams. Consumer callback will NOT fire again. Page content persists from the initial launch.
pre-v146 behaviour: every reload re-queues launchParams and fires the consumer again — causing duplicate processing, duplicate file opens, and unexpected side effects.
LaunchParams Consumer Log
No events yet — click "Simulate initial launch".
Code — setConsumer Handler
if ('launchQueue' in window) {
window.launchQueue.setConsumer(async (launchParams) => {
// Chrome 146: this fires ONCE — on initial launch only.
// Reloading the page does NOT re-invoke this callback.
const targetURL = launchParams.targetURL;
// e.g. "https://myapp.example/app?source=file"
for (const handle of launchParams.files) {
const file = await handle.getFile();
console.log('Opening file:', file.name);
await processFile(file);
}
// Safe: no need to guard against duplicate invocations on reload
});
}
if ('launchQueue' in window) {
window.launchQueue.setConsumer(async (launchParams) => {
// pre-v146: this fires on EVERY reload — including F5, history back,
// and hard refreshes. Developers had to work around this:
if (sessionStorage.getItem('launchHandled')) {
return; // guard against re-queuing bug
}
sessionStorage.setItem('launchHandled', '1');
const targetURL = launchParams.targetURL; // was undefined in some cases
for (const handle of launchParams.files) {
const file = await handle.getFile();
await processFile(file); // could run twice without the guard above
}
});
}