# Creating Installable Web Apps
The web has come a long way, and one of the significant advancements is the rise of Progressive Web Apps (PWAs). These apps have opened up new opportunities for developers worldwide, making web development even more powerful in an increasingly connected world. The acceptance of web-based applications for daily use is growing rapidly, and it's essential to have a framework that supports installing web apps on mobile devices and desktops.

# Is it possible to create PWAs with a traditional architecture?

YES, it is possible to create PWAs even with a traditional architecture that uses server-side rendered pages and ClojureScript (JavaScript). To make your web app installable, you need to provide the browser with the necessary information. PWAs typically consist of three main components:

* A `manifest.json` file
* A `service worker` (usually `sw.js`)
* A registration workflow in the browser using the `navigator` object

## The `manifest.json` File

The `manifest.json` file is a crucial component of a PWA. It provides the browser with essential information about your app, such as its name, short name, theme color, and background color. These colors determine the appearance of the status bar and navigation on mobile devices. You can find more information about the `manifest.json` file on the [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/Manifest).

Here's an example of a `manifest.json` file in Clojure:
```clojure
;; manifest.edn gets translated into manifest.json
{:name "borkweb"
 :short_name "borkweb"
 :theme_color "#2b3035"
 :background_color "#2b3035"
 :start_url "./"
 :scope "./"
 :display "standalone"
 :prefer_related_applications false
 :icons
  [{:src "https://raw.githubusercontent.com/m3tti/borkweb/refs/heads/master/logo/borkweb.png"
 :type "image/png"
 :sizes "512x512"}]}
```

## The Service Worker
The service worker is a more complex component of a PWA. It runs in the background, handling requests for your web page and caching content. Here's an example of a basic service worker in Squint (ClojureScript):

```clojure
(defn on-activate [ev]
  (js/console.log "Send claim")
  (.waitUntil ev (-> self .-clients .claim)))

(defn on-fetch [ev]
  (.respondWith ev (js/fetch (.-request ev)) ))

(defn on-install [ev]
  (js/console.log "Install"))

(.addEventListener self "activate" on-activate)
(.addEventListener self "fetch" on-fetch)
(.addEventListener self "install" on-install)
```
This code defines three main functions:
* `on-activate`: Called when the web page is loaded
* `on-fetch`: Called when a resource is requested from the web page
* `on-install`: Called when the PWA is installed

You can also listen for other events, such as `beforeinstallprompt`, to show a custom installation dialog.

## Registering the Service Worker

To register your ServiceWorker, you need to add the following code:
```clojure
(when (get js/navigator "serviceWorker")
  (.addEventListener
   js/self "load"
   (^:async fn []
     (let [container (.-serviceWorker js/navigator)]
       (if (nil? (.-controller container))
         (do
           (js/console.log "Try to register new sw")
           (js-await (.register container "sw.js"))
           (js/console.log "SW installed"))
         (js/console.log "SW already registered"))))))
```
This code checks if a service worker is available and registers it if none exists.

## Whats up next
So creating a PWA is easier than you think, even with a traditional architecture. By providing a `manifest.json` file, a service worker, and registering it in the browser, you can create a seamless and installable web app experience for your users. And all of this is now part of borkweb. You get if for free just by using borkweb. Join the web revolution! Enjoy the web like it was intended!