Release v3.8.1 — feature flags settings page, bracketed combo names, security hardening, multi-driver SQLite
9.5 KiB
| title | version | lastUpdated |
|---|---|---|
| Progressive Web App (PWA) Guide | 3.8.1 | 2026-05-13 |
Progressive Web App (PWA) Guide
OmniRoute ships as a fully installable Progressive Web App. When you access the dashboard from any mobile browser — Android (Chrome) or iOS (Safari) — you can "Add to Home Screen" and get a native app-like experience with no app store required.
What Is a PWA?
A Progressive Web App turns the OmniRoute web dashboard into something that looks and feels like a native mobile app. Once installed, it:
- Launches from your home screen with its own icon
- Opens fullscreen — no browser address bar or tab UI
- Works offline with a dedicated connectivity page
- Caches static assets for faster loading
- Supports both portrait and landscape orientations
Installation
Android (Chrome)
- Open the OmniRoute dashboard in Chrome:
http://YOUR_IP:20128 - Chrome will show an "Add OmniRoute to Home screen" banner automatically, or:
- Tap the ⋮ menu (three dots) → "Add to Home screen" or "Install app"
- Confirm the prompt
- OmniRoute appears on your home screen as a standalone app
iOS (Safari)
- Open the OmniRoute dashboard in Safari:
http://YOUR_IP:20128 - Tap the Share button (box with arrow)
- Scroll down and tap "Add to Home Screen"
- Name it (defaults to "OmniRoute") and tap Add
- OmniRoute appears on your home screen with the app icon
Desktop (Chrome / Edge)
- Open the OmniRoute dashboard
- Click the install icon in the address bar (or ⋮ → "Install OmniRoute...")
- Confirm the prompt
- OmniRoute opens as a standalone window — no tabs, no address bar
Features
Fullscreen Experience
The manifest is configured with display: "fullscreen", which means the installed app uses the entire screen — no browser chrome, no status bar overlap. This makes the dashboard feel truly native.
Offline Support
OmniRoute includes a service worker (sw.js) that provides intelligent caching:
| Asset Type | Strategy | Behavior |
|---|---|---|
| App Shell | Cache-first | /, /offline, manifest, and icons are pre-cached on install |
| Static assets (CSS, JS, images, fonts) | Network-first with cache fallback | Fetches fresh from the network; falls back to cache if offline |
Next.js bundles (/_next/) |
Network-first with cache update | Fetches from network and updates cache; serves cached version if offline |
| Navigation requests | Network-only with offline fallback | Always fetches from network; shows /offline page if network is unavailable |
API routes (/api/, /a2a, /dashboard/endpoint) |
Bypass (never cached) | Always goes directly to the server — never intercepted by the service worker |
Offline Page
When the network is unavailable and a user navigates to a new page, the service worker serves a dedicated /offline page that:
- Displays a clear "Connectivity Issue" message
- Shows a live online/offline status indicator that updates in real time
- Provides a "Retry Connection" button to reload when connectivity returns
- Links to the Status Page for diagnostics
App Icons
OmniRoute provides icons optimized for each platform:
| File | Size | Used By |
|---|---|---|
icon-512.png |
512×512 | Android install prompt, splash screen |
apple-touch-icon.png |
180×180 | iOS home screen icon |
icon-192.svg |
192×192 (vector) | Android adaptive icon |
apple-touch-icon.svg |
180×180 (vector) | Apple fallback |
favicon.svg |
Vector | Browser tabs |
favicon.ico |
Multi-size | Legacy browsers |
Automatic Registration
The service worker is registered automatically via the <PwaRegister /> component in the root layout. No user action is needed — the app becomes installable as soon as the browser detects the valid manifest and service worker.
Technical Architecture
Web App Manifest (manifest.webmanifest)
Generated by Next.js via src/app/manifest.ts:
{
"name": "OmniRoute",
"short_name": "OmniRoute",
"description": "OmniRoute is an AI gateway for multi-provider LLMs. One endpoint for all your AI providers.",
"start_url": "/",
"scope": "/",
"display": "fullscreen",
"orientation": "any",
"background_color": "#0b0f1a",
"theme_color": "#0b0f1a",
"icons": [
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" },
{ "src": "/apple-touch-icon.png", "sizes": "180x180", "type": "image/png" }
]
}
Service Worker (public/sw.js)
A vanilla service worker (no framework dependencies) with:
- Install phase: Pre-caches the app shell (root, offline page, manifest, icons)
- Activate phase: Cleans up old cache versions and claims all clients
- Fetch phase: Intelligent routing based on request type (navigation, static asset, API)
- Cache versioning:
omniroute-pwa-v2— bump this to force a fresh cache on update
Layout Metadata (src/app/layout.tsx)
The root layout provides all the meta tags required for PWA compliance:
manifestlink to/manifest.webmanifestapple-web-app-capable: truefor iOS standalone modeapple-web-app-status-bar-style: black-translucentmobile-web-app-capable: yesfor Android Chrometheme-color: #0b0f1aviewport-fit: coverfor edge-to-edge rendering
Component: PwaRegister
Located at src/shared/components/PwaRegister.tsx, this client component:
- Runs on mount (client-side only)
- Checks for
serviceWorkersupport in the browser - Registers
/sw.jssilently (errors are swallowed to avoid blocking the app) - Renders nothing (
return null) — it's a side-effect-only component
Use With Termux (Android)
When running OmniRoute on Android via Termux, the PWA works seamlessly:
- Start OmniRoute in Termux:
npx omniroute - Open Chrome on the same phone:
http://localhost:20128 - Install the PWA via "Add to Home Screen"
- The PWA connects to the local Termux server — everything runs on-device
This combination means your Android phone is both the server (Termux) and the client (PWA) — a complete self-contained AI gateway.
Use From Other Devices
Install the PWA on any device that has browser access to your OmniRoute server:
- Another phone/tablet: Navigate to
http://PHONE_IP:20128and install the PWA - Laptop: Open Chrome/Edge and install it as a desktop PWA
- Smart TV with browser: Access the dashboard fullscreen
Customization
Instance Name
The PWA title respects the Instance Name setting from Dashboard → Settings. If you rename your instance to "My AI Gateway", the installed PWA will show that name.
Custom Favicon
If you upload a custom favicon via Dashboard → Settings, the PWA icon on desktop will reflect the custom icon. Mobile home screen icons use the pre-built icon-512.png and apple-touch-icon.png files.
Limitations
- No push notifications — The service worker does not implement the Push API. Notifications are handled by the Electron app instead.
- No background sync — Offline actions are not queued for replay. The PWA is primarily a dashboard viewer.
- iOS restrictions — Safari on iOS does not support all PWA features (e.g., install prompts are manual, and background service workers are limited).
- Cache size — The service worker caches static assets only. Large response payloads from
/api/routes are never cached. - Custom icons on mobile — Changing the favicon in settings does not update the home screen icon on mobile (this requires regenerating the PWA icons).
Files Reference
| File | Purpose |
|---|---|
src/app/manifest.ts |
Next.js manifest route (generates manifest.webmanifest) |
public/sw.js |
Service worker with caching logic |
src/shared/components/PwaRegister.tsx |
Client component that registers the service worker |
src/app/offline/page.tsx |
Offline fallback page with live status indicator |
src/app/layout.tsx |
Root layout with PWA metadata (apple-web-app, theme-color, etc.) |
public/icon-512.png |
512×512 PNG icon (Android, splash screen) |
public/apple-touch-icon.png |
180×180 PNG icon (iOS home screen) |
public/icon-192.svg |
192×192 SVG icon (Android adaptive) |
public/apple-touch-icon.svg |
180×180 SVG icon (Apple fallback) |