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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.klai.studio/engineering-reference-docs/creating-a-pwa/getting-started/making-it-installable.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
