v146 · Web APIs · File Handling
Populate targetURL during file handling
Chrome 146 ensures that LaunchParams.targetURL is populated when a Progressive Web App is launched via the File Handling API — for example, when a user opens a file with the PWA from the OS file picker or double-clicks a registered file type. Previously targetURL was null in this scenario.
concepts
-
TargetURL Demo
Shows the full
LaunchParamsobject available throughlaunchQueue.setConsumer(), includingtargetURLandfiles. Simulates what you'd see when a PWA is launched for file handling in Chrome 146. -
File Handling Flow
Step-by-step walkthrough of the file handling flow: manifest registration → OS association → user opens file → PWA launch →
launchQueueconsumer receivesLaunchParamswithtargetURLpopulated. -
Target URL router
Pick a file from a fake OS shell and watch the file-handler matching algorithm pick an action, build the
targetURL, and surface it in a fake browser chrome. Toggle single-client vs multi-client manifests. -
File Handler Tester
A file picker and four presets (txt, json, csv, md) trigger a simulated launch flow. The page shows
launchParams.targetURLwith URL components breakdown (scheme, hostname, path, filename). ALaunchParamsfields table marks thetargetURLproperty with a "new v146" badge, with a before/after code comparison and a Web App Manifestfile_handlerssnippet.
why it shipped
The File Handling API lets PWAs register as handlers for specific file types via the web app manifest. When the OS launches the PWA to handle a file, the app receives a LaunchParams object with a files array of FileSystemFileHandle. The targetURL property on LaunchParams was also intended to carry the URL the app was launched with — but in file handling launches it was incorrectly null. Chrome 146 fixes this so apps can inspect both the URL and the files in one place.
the API
// Register in web app manifest:
// "file_handlers": [{
// "action": "/open",
// "accept": { "text/plain": [".txt"] }
// }]
// In the PWA, consume launches via launchQueue
if ('launchQueue' in window) {
launchQueue.setConsumer(async launchParams => {
// Chrome 146: targetURL is now populated for file handling launches
console.log('targetURL:', launchParams.targetURL); // e.g. "https://app.example/open"
console.log('files:', launchParams.files); // FileSystemFileHandle[]
for (const fileHandle of launchParams.files) {
const file = await fileHandle.getFile();
const text = await file.text();
console.log(file.name, text);
}
});
}