> For the complete documentation index, see [llms.txt](https://docs.klai.studio/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.klai.studio/engineering-reference-docs/creating-a-pwa/getting-started/making-it-installable.md).

# Making it installable

This will be the first feature added to your PWA. We will start by creating a manifest object and passing it as a parameter to a new BF function <mark style="color:red;">`pwaSetManifest`</mark>. In this example we added this code to a function in our <mark style="color:red;">`onAppLoad`</mark> named action.

```javascript
let manifest = {
  name: "My Awesome PWA",
  short_name: "My App",
  icons: [{
      src: "LINK_TO_YOUR_ICON",
      sizes: "196x196",
      type: "image/png",
      purpose: "any"
    },{
      src: "LINK_TO_YOUR_ICON",
      sizes: "196x196",
      type: "image/png",
      purpose: "maskable"
    }],
  start_url: "https://your.domain.com/index.html",
  display: "standalone",
  background_color: "#000000",
  theme_color: "#4DBA87"
};
//background_color and theme_color can be customized

BF.pwaSetManifest(manifest);
```

Next, as part of the <mark style="color:red;">`onAppLoad`</mark> as well, we add a new action <mark style="color:red;">`pwaCustomInstall`</mark>

```json
{
    "action": "pwaCustomInstall",
    "options": {
        "beforeinstallprompt_actions": [{
            "action": "function",
            "function": "model.isInstalled = false;"
        }]
    }
}
```

This new action has the options <mark style="color:red;">`beforeinstallprompt`</mark>, which are actions that will run before the trapped prompt to install event triggered by the browser when it identifies the web app as installable. The example above shows one way of setting a state variable that we will use to show or hide a button to install the app.

So in this case, we need a key <mark style="color:red;">`isInstalled`</mark> in our model.

In our example, once the install button is clicked on, a modal will prompt asking whether the user wants to install it.

```json
{
    "actions": [{
        "action": "showModal",
        "options": {
            "body": "Do you want to get the most out of this app?",
            "buttons": [],
            "slots": [{
                "actions": [{
                    "action": "namedAction",
                    "name": "installApp"
                }, {
                    "action": "hideModal"
                }],
                "component": "button",
                "slot": "button",
                "styleClasses": "btn btn-danger",
                "text": "Install"
            }, {
                "actions": [{
                    "action": "hideModal"
                }],
                "component": "button",
                "slot": "button",
                "styleClasses": "btn btn-info",
                "text": "Not now"
            }]
        }
    }],
    "buttonClasses": "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded",
    "styleClasses": "col-md-2",
    "text": "Install App!",
    "type": "button",
    "visible_calc": "!model.isInstalled"
}
```

The named action <mark style="color:red;">`instalApp`</mark> above has the following code.

```json
{
    "action": "pwaPromptInstall",
    "options": {
        "onAccepted_actions": [{
            "action": "showAlert",
            "options": {
                "text": "Thanks for installing the app!",
                "title": "Welcome!",
                "type": "information"
            }
        }],
        "onDismissed_actions": [{
            "action": "showAlert",
            "options": {
                "text": "If I were you, I'd install the app!",
                "title": "Too bad!",
                "type": "information"
            }
        }]
    }
}
```

The action <mark style="color:red;">`pwaPromptInstall`</mark> is the action that triggers the browser to prompt the user with the actual window that will install the app. This gives the flexibility to trigger this event from anywhere in your app, and customize it according to your needs.

The options <mark style="color:red;">`onAccepted_actions`</mark> and <mark style="color:red;">`onDismissed_actions`</mark> will run after the user click on <mark style="color:red;">`Cancel`</mark>, <mark style="color:red;">`Install`</mark> or close the browser’s prompt window.

Our modal looks like the image below.

<figure><img src="/files/SC9mgwD6YlaGWWvI94wk" alt=""><figcaption></figcaption></figure>

By clicking on <mark style="color:red;">`Install`</mark>, it will trigger the browser event that asks if the user wants to install the app, as shown on the image below.

<figure><img src="/files/PnfLGd6f2BbReIrNVoH0" alt=""><figcaption></figcaption></figure>

After installing it, the user will be able to access your web app as a regular native app.
