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

  1. TargetURL Demo

    Shows the full LaunchParams object available through launchQueue.setConsumer(), including targetURL and files. Simulates what you'd see when a PWA is launched for file handling in Chrome 146.

  2. File Handling Flow

    Step-by-step walkthrough of the file handling flow: manifest registration → OS association → user opens file → PWA launch → launchQueue consumer receives LaunchParams with targetURL populated.

  3. 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.

  4. File Handler Tester

    A file picker and four presets (txt, json, csv, md) trigger a simulated launch flow. The page shows launchParams.targetURL with URL components breakdown (scheme, hostname, path, filename). A LaunchParams fields table marks the targetURL property with a "new v146" badge, with a before/after code comparison and a Web App Manifest file_handlers snippet.

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);
    }
  });
}

references