---
title: Offline and PWA
description: The opt-in progressive web app — what it stores for offline reading, how publishing interacts with it, and how to turn it off cleanly.
order: 6
---

# Offline and PWA

Docs get read in places with no signal: a plant floor, a survey site, a basement, a plane. Docsary can install as a progressive web app so that pages a reader has already opened stay available with the network gone.

It is off by default and enabled per site.

## Turning it on

```bash
curl -s -X PATCH "$DOCSARY_API/v1/sites/acme" \
  -H "authorization: Bearer $DOCSARY_KEY" \
  -H "content-type: application/json" \
  -d '{"settings":{"pwa":true}}'
```

:::warning
`settings` is replaced wholesale, not merged. The call above erases any other settings the site had — logo, colours, footer links. Read the current object first with `GET /v1/sites/acme`, add your key to it, and send the result back.
:::

With `pwa` enabled, every page links a web app manifest and registers a small offline script at `/sw.js`. Browsers then offer to install the docs, and the installed app opens standalone, without browser chrome.

## What the manifest contains

`/manifest.webmanifest` is generated from site settings:

| Field | Source |
| --- | --- |
| `name`, `short_name` | `settings.name`, falling back to the site's name |
| `start_url` | `/` |
| `display` | `standalone` |
| `theme_color` | `settings.colors.primary`, falling back to the default blue |
| `background_color` | `#ffffff` |
| `icons` | `settings.logo` if set, declared at `sizes: "any"`; otherwise empty |

Set `settings.logo` to an SVG for a good install icon. A single raster image declared as `any` will be scaled by the platform to every size it needs, and small launcher icons are where that shows.

When `pwa` is off, `/manifest.webmanifest` returns `404`.

## What it stores, and when

The strategy is **network-first with a cache fallback**. Online readers always get current content; the cache exists only to answer a request the network cannot.

On each request it fetches from the network. A successful response is stored and returned. If the fetch fails, the stored copy is returned. If there is no stored copy, the failure surfaces normally.

It handles `GET` requests to your docs site only. Non-`GET` requests, other origins, and API paths are passed straight through, so API traffic is never cached or intercepted.

**Only pages a reader has actually opened are available offline.** There is no precaching and no site-wide download. Practically: a technician who reads a procedure over the office network has it in the field; a page nobody opened is not there.

Search does not work offline. Results are produced on the server, so a new query needs the network.

## Publishing and the offline cache

Publishing retires everything readers have stored. The next time a reader opens the docs online, the stored copies from before the publish are dropped and replaced as pages are read again.

The effect is that **stale offline content cannot outlive a publish**. It also means offline coverage resets after each publish: pages must be visited again to be available offline again. That trade — correctness over coverage — is the right one for documentation, where a confidently served obsolete procedure is worse than no page at all.

The new version takes over immediately rather than waiting for open tabs to close, so a reader never has two versions of the docs in play.

## Turning it off

Set `pwa` back to `false`:

```bash
curl -s -X PATCH "$DOCSARY_API/v1/sites/acme" \
  -H "authorization: Bearer $DOCSARY_KEY" \
  -H "content-type: application/json" \
  -d '{"settings":{"pwa":false}}'
```

Removing the registration from new page loads is not enough on its own — a copy already installed in a reader's browser keeps running, and would otherwise keep serving your docs from a cache nobody is maintaining. So `/sw.js` does not disappear when the feature is disabled. It starts serving a self-destructing version instead, which clears every cache it holds, unregisters itself, and reloads any open tab onto the live site.

`/sw.js` is cached for 60 seconds in both states, so an installed reader picks up the self-destruct within about a minute of the change. Turning offline mode off is a clean uninstall, not an abandonment.

## Not included

No push notifications, no background sync, no offline editing, no app store packaging. This is offline reading of pages already read, and nothing more.
