# launch_handler in manifest of PWA

<div data-processed="true" data-subtree="aimfl,mfl" id="bkmrk-the" jscontroller="v48bt" jsuid="NUbAm_9" style="display: contents;">The</div>`launch_handler` member in a Progressive Web App (PWA) manifest is part of the **Launch Handler API**, which <mark class="HxTRcb" data-processed="true">allows you to control how the PWA is launched</mark>—specifically, whether it opens in a new window or reuses an existing one, and how it handles the target URL.<span class="uJ19be notranslate" data-processed="true" data-wiz-uids="NUbAm_d,NUbAm_e,NUbAm_f"><span class="vKEkVd" data-animation-atomic="" data-processed="true" data-wiz-attrbind="class=NUbAm_d/TKHnVd;"> </span></span>

<div class="Y3BBE" data-hveid="CAEQAA" data-processed="true" data-sfc-cp="" id="bkmrk-" jsaction="rcuQ6b:&NUbAm_8|npT2md" jscontroller="zcfIf" jsuid="NUbAm_8">  
</div><div class="Y3BBE" data-hveid="CAIQAA" data-processed="true" data-sfc-cp="" id="bkmrk-it-is-an-experimenta" jsaction="rcuQ6b:&NUbAm_i|npT2md" jscontroller="zcfIf" jsuid="NUbAm_i">It is an experimental feature and may not be supported in all browsers, so the `window.launchQueue` API must be used in conjunction for robust handling.<span class="uJ19be notranslate" data-processed="true" data-wiz-uids="NUbAm_k,NUbAm_l,NUbAm_m"><span class="vKEkVd" data-animation-atomic="" data-processed="true" data-wiz-attrbind="class=NUbAm_k/TKHnVd;"> </span></span></div><div class="Y3BBE" data-hveid="CAIQAA" data-processed="true" data-sfc-cp="" id="bkmrk--1" jsaction="rcuQ6b:&NUbAm_i|npT2md" jscontroller="zcfIf" jsuid="NUbAm_i">  
</div><div class="Fsg96" data-processed="true" data-sfc-cp="" id="bkmrk--2" jsaction="rcuQ6b:&NUbAm_p|npT2md" jscontroller="KHhJQ" jsuid="NUbAm_p">  
</div><div aria-level="3" class="otQkpb" data-animation-nesting="" data-processed="true" data-sfc-cp="" id="bkmrk-usage" jscontroller="a7qCn" jsuid="NUbAm_q" role="heading">Usage</div><div aria-level="3" class="otQkpb" data-animation-nesting="" data-processed="true" data-sfc-cp="" id="bkmrk--3" jscontroller="a7qCn" jsuid="NUbAm_q" role="heading">  
</div><div class="Y3BBE" data-hveid="CAQQAA" data-processed="true" data-sfc-cp="" id="bkmrk-add-the-launch_handl" jsaction="rcuQ6b:&NUbAm_u|npT2md" jscontroller="zcfIf" jsuid="NUbAm_u">Add the `launch_handler` member to your `manifest.json` file with a `client_mode` subfield:<span class="uJ19be notranslate" data-processed="true" data-wiz-uids="NUbAm_y,NUbAm_z,NUbAm_10"><span class="vKEkVd" data-animation-atomic="" data-processed="true" data-wiz-attrbind="class=NUbAm_y/TKHnVd;"> </span></span></div><div class="Y3BBE" data-hveid="CAQQAA" data-processed="true" data-sfc-cp="" id="bkmrk--4" jsaction="rcuQ6b:&NUbAm_u|npT2md" jscontroller="zcfIf" jsuid="NUbAm_u">  
</div><div class="Fsg96" data-processed="true" data-sfc-cp="" id="bkmrk--5" jsaction="rcuQ6b:&NUbAm_11|npT2md" jscontroller="KHhJQ" jsuid="NUbAm_11">  
</div><div class="r1PmQe" data-hveid="CAUQAA" data-processed="true" data-wiz-uids="NUbAm_13,NUbAm_14,NUbAm_15" id="bkmrk-json" jscontroller="HP6Sjf" jsuid="NUbAm_12"><div data-processed="true"><div class="pHpOfb" data-animation-atomic="" data-processed="true"><div class="vVRw1d" data-processed="true">json</div></div></div></div>```
{
  "name": "My PWA App",
  "start_url": "/",
  "display": "standalone",
  "launch_handler": {
    "client_mode": "focus-existing"
  }
}

```

<div class="Y3BBE" data-hveid="CAYQAA" data-processed="true" data-sfc-cp="" id="bkmrk-%C2%A0" jsaction="rcuQ6b:&NUbAm_18|npT2md" jscontroller="zcfIf" jsuid="NUbAm_18"><span class="uJ19be notranslate" data-processed="true" data-wiz-uids="NUbAm_19,NUbAm_1a,NUbAm_1b"><span class="vKEkVd" data-animation-atomic="" data-processed="true" data-wiz-attrbind="class=NUbAm_19/TKHnVd;"> </span></span></div><div class="Y3BBE" data-hveid="CAYQAA" data-processed="true" data-sfc-cp="" id="bkmrk--6" jsaction="rcuQ6b:&NUbAm_18|npT2md" jscontroller="zcfIf" jsuid="NUbAm_18">  
</div><div class="Fsg96" data-processed="true" data-sfc-cp="" id="bkmrk--7" jsaction="rcuQ6b:&NUbAm_1d|npT2md" jscontroller="KHhJQ" jsuid="NUbAm_1d">  
</div><div aria-level="3" class="otQkpb" data-animation-nesting="" data-processed="true" data-sfc-cp="" id="bkmrk-client_mode-values" jscontroller="a7qCn" jsuid="NUbAm_1e" role="heading">`client_mode` Values</div><div aria-level="3" class="otQkpb" data-animation-nesting="" data-processed="true" data-sfc-cp="" id="bkmrk--8" jscontroller="a7qCn" jsuid="NUbAm_1e" role="heading">  
</div><div class="Y3BBE" data-hveid="CAgQAA" data-processed="true" data-sfc-cp="" id="bkmrk-the-client_mode-fiel" jsaction="rcuQ6b:&NUbAm_1j|npT2md" jscontroller="zcfIf" jsuid="NUbAm_1j">The `client_mode` field determines the launch behavior. The available values are:<span class="uJ19be notranslate" data-processed="true" data-wiz-uids="NUbAm_1l,NUbAm_1m,NUbAm_1n"><span class="vKEkVd" data-animation-atomic="" data-processed="true" data-wiz-attrbind="class=NUbAm_1l/TKHnVd;"> </span></span></div><div class="Y3BBE" data-hveid="CAgQAA" data-processed="true" data-sfc-cp="" id="bkmrk--9" jsaction="rcuQ6b:&NUbAm_1j|npT2md" jscontroller="zcfIf" jsuid="NUbAm_1j">  
</div>- <span class="T286Pc" data-processed="true" data-sfc-cp="">**`auto`**: The default behavior. The user agent (browser) decides the best context for the platform (e.g., `navigate-existing` on mobile, `navigate-new` on desktop).</span>
- <span class="T286Pc" data-processed="true" data-sfc-cp="">**`focus-existing`**: If an app instance is already running, it is brought into focus. The target URL is made available to the app via `window.launchQueue` but the navigation does not happen automatically, allowing you to handle it with custom JavaScript.</span>
- <span class="T286Pc" data-processed="true" data-sfc-cp="">**`navigate-existing`**: If an app instance is running, it is brought into focus and navigated to the launch target URL. The URL is still available via `window.launchQueue` for additional handling.</span>
- <span class="T286Pc" data-processed="true" data-sfc-cp="">**`navigate-new`**: The PWA always opens in a new web app window (or a new browsing context within the app) to load the target URL.</span><span class="uJ19be notranslate" data-processed="true" data-wiz-uids="NUbAm_2b,NUbAm_2c,NUbAm_2d"><span class="vKEkVd" data-animation-atomic="" data-processed="true" data-wiz-attrbind="class=NUbAm_2b/TKHnVd;"> </span></span>

<div class="Fsg96" data-processed="true" data-sfc-cp="" id="bkmrk--10" jsaction="rcuQ6b:&NUbAm_2h|npT2md" jscontroller="KHhJQ" jsuid="NUbAm_2h">  
</div><div aria-level="3" class="otQkpb" data-animation-nesting="" data-processed="true" data-sfc-cp="" id="bkmrk-custom-handling-with" jscontroller="a7qCn" jsuid="NUbAm_2i" role="heading">Custom Handling with JavaScript</div><div aria-level="3" class="otQkpb" data-animation-nesting="" data-processed="true" data-sfc-cp="" id="bkmrk--11" jscontroller="a7qCn" jsuid="NUbAm_2i" role="heading">  
</div><div class="Y3BBE" data-hveid="CAsQAA" data-processed="true" data-sfc-cp="" id="bkmrk-to-handle-the-launch" jsaction="rcuQ6b:&NUbAm_2m|npT2md" jscontroller="zcfIf" jsuid="NUbAm_2m">To handle the launch parameters within your PWA, especially when using `focus-existing` or handling files via the `file_handlers` API, you use the `window.launchQueue.setConsumer()` method in your application's JavaScript code:<span class="uJ19be notranslate" data-processed="true" data-wiz-uids="NUbAm_2q,NUbAm_2r,NUbAm_2s"><span class="vKEkVd" data-animation-atomic="" data-processed="true" data-wiz-attrbind="class=NUbAm_2q/TKHnVd;"> </span></span></div><div class="Y3BBE" data-hveid="CAsQAA" data-processed="true" data-sfc-cp="" id="bkmrk--12" jsaction="rcuQ6b:&NUbAm_2m|npT2md" jscontroller="zcfIf" jsuid="NUbAm_2m">  
</div><div class="Fsg96" data-processed="true" data-sfc-cp="" id="bkmrk--13" jsaction="rcuQ6b:&NUbAm_2v|npT2md" jscontroller="KHhJQ" jsuid="NUbAm_2v">  
</div><div class="r1PmQe" data-hveid="CA4QAA" data-processed="true" data-wiz-uids="NUbAm_4r,NUbAm_4s,NUbAm_4t" id="bkmrk-javascript" jscontroller="HP6Sjf" jsuid="NUbAm_4q"><div data-processed="true"><div class="pHpOfb" data-animation-atomic="" data-processed="true"><div class="vVRw1d" data-processed="true">javascript</div></div></div></div>```
if ('launchQueue' in window) {
  window.launchQueue.setConsumer(launchParams => {
    // Check if there's a target URL or files to handle
    if (launchParams.targetURL) {
      const url = new URL(launchParams.targetURL);
      // Implement custom routing or logic based on the URL
      console.log('Launched with URL:', url.pathname);
    }
    if (launchParams.files) {
      // Handle file system handles
      for (const fileHandle of launchParams.files) {
        console.log('Handling file:', fileHandle.name);
      }
    }
  });
}

```

<div class="Y3BBE" data-hveid="CA8QAA" data-processed="true" data-sfc-cp="" id="bkmrk-%C2%A0-1" jsaction="rcuQ6b:&NUbAm_4w|npT2md" jscontroller="zcfIf" jsuid="NUbAm_4w"><span class="uJ19be notranslate" data-processed="true" data-wiz-uids="NUbAm_4x,NUbAm_4y,NUbAm_4z"><span class="vKEkVd" data-animation-atomic="" data-processed="true" data-wiz-attrbind="class=NUbAm_4x/TKHnVd;"> </span></span></div><div class="Y3BBE" data-hveid="CA8QAA" data-processed="true" data-sfc-cp="" id="bkmrk--14" jsaction="rcuQ6b:&NUbAm_4w|npT2md" jscontroller="zcfIf" jsuid="NUbAm_4w">  
</div><div class="Y3BBE" data-hveid="CBAQAA" data-processed="true" data-sfc-cp="" id="bkmrk-this-allows-develope" jsaction="rcuQ6b:&NUbAm_52|npT2md" jscontroller="zcfIf" jsuid="NUbAm_52">This allows developers to create a more integrated, native-app-like experience by managing windows and navigation behavior according to user expectations</div>