Install your website as a phone app
Let people add your site, or one section of it, to a phone's home screen, open it in its own window, and keep chosen pages for when the signal drops.
People who use a site often - members checking a portal, staff on a stock page, a club looking up fixtures - want it on the home screen, one tap away, opening in its own window. A native app means building for each app store, publishing through each one, and keeping a second code base in step with the website.
Browsers have their own answer: a progressive web app. The website you already run can be installed from the browser's menu and opened from the home screen, without an address bar.
The general approach
A browser installs a site as an app when the site gives it two documents:
- A web app manifest - the app's name, icons, colours, and which part of the site it covers.
- A service worker - a small script that decides what the device keeps, so the app's own files are on the device and some pages open with no signal.
Both are easy to get subtly wrong: a worker that keeps the wrong answer can show one person's page to the next. The safer arrangement is for the site engine to generate them from a few settings.
How lazysite does it
Turn it on
Set app_name and the site is an app. Lazysite then generates the manifest and the service worker itself; nobody writes either one, and there is no extension to enable. The settings go in lazysite.conf, or on the manager's Config page under Install as an app, which needs no shell access:
app_name: Example Portal
app_short_name: Portal
app_theme_colour: #0a5c36
app_scope: /portal/
app_icon_192: /icons/app-192.png
app_icon_512: /icons/app-512.png
app_offline_pages: /portal/, /portal/new
- Scope - the app can be the whole site (
/, the default) or one section, such as/portal/. A link outside the scope opens in the browser. On a site serving several domains, each domain can be its own app. - Icons - you supply the image files (png, webp, svg or jpg) at paths the site serves; the engine makes none. A maskable icon should be 512 by 512.
- Checks - the Config page refuses, when you save, a value that would turn the app off or an icon missing from the site, naming the setting.
lazysite checkreports a bad scope or start page, a colour written other than as hex, a missing icon, and an app with no icons.
Pages already rendered are cached, so after turning the app on, invalidate the page cache so the pages carry the link to the manifest.
It needs https
The service worker needs a secure context: https, or localhost. That is the browser's rule. A phone reaching a development server at http://<lan-ip>:port is never offered the install; use https, or reach it through localhost with a port forward.
What works offline
- The app shell - the engine's own stylesheet and script, the icons, the stylesheets and scripts the start page links, and any extra files listed in
app_shell- is kept on the device when the app installs. - The pages you list in
app_offline_pagesopen with no connection. Each is fetched from the network first, and the last good copy opens the page when there is no signal. The worker fetches the listed pages when it installs, so they are on the device after the first visit. - A listed page must be the same for every visitor. The worker keeps the page as a signed-out visitor receives it, fetched without credentials. The Config page refuses a page that needs a sign-in, a group, a payment or an address rule, a page under a read list, a page with
odoo-identity:or adb:...(mine)binding, and a page markednocache,apiorraw. A page with anodoo:binding qualifies. A person's own data belongs in what the page fetches as it runs. - Everything else goes to the server as usual. The worker leaves the manager, sign-in and sign-out, the Odoo endpoint and the engine's other endpoints to the network, never keeps a response sent
no-storeorprivate, and holds no queue of actions to send later. A page carrying a form is sentno-store, private, so the worker keeps nothing of it.
Images are kept cache-first, so give a changed image a new file name.
Updates
A deploy that changes the release, the shell files or the offline page list changes the worker, and the browser installs the new one on its next check. With app_update: now, the default, it takes over at once. With app_update: wait, pages already open keep the old version until the page asks, so a form being filled in is left alone; the page can listen for the lazysite-app-update event and offer a reload.
The worker's own page fetches are counted apart in the visitor figures, as app_hits, so they are kept separate from visits.
- Read Installing a site as an app for every setting, the caching rules and how to check an install.
- See what else it does.