193 lines
9.5 KiB
Markdown
193 lines
9.5 KiB
Markdown
---
|
||
title: "Progressive Web App (PWA) Guide"
|
||
version: 3.8.40
|
||
lastUpdated: 2026-06-28
|
||
---
|
||
|
||
# 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)
|
||
|
||
1. Open the OmniRoute dashboard in Chrome: `http://YOUR_IP:20128`
|
||
2. Chrome will show an **"Add OmniRoute to Home screen"** banner automatically, or:
|
||
- Tap the **⋮** menu (three dots) → **"Add to Home screen"** or **"Install app"**
|
||
3. Confirm the prompt
|
||
4. OmniRoute appears on your home screen as a standalone app
|
||
|
||
### iOS (Safari)
|
||
|
||
1. Open the OmniRoute dashboard in Safari: `http://YOUR_IP:20128`
|
||
2. Tap the **Share** button (box with arrow)
|
||
3. Scroll down and tap **"Add to Home Screen"**
|
||
4. Name it (defaults to "OmniRoute") and tap **Add**
|
||
5. OmniRoute appears on your home screen with the app icon
|
||
|
||
### Desktop (Chrome / Edge)
|
||
|
||
1. Open the OmniRoute dashboard
|
||
2. Click the **install icon** in the address bar (or ⋮ → "Install OmniRoute...")
|
||
3. Confirm the prompt
|
||
4. 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`:
|
||
|
||
```json
|
||
{
|
||
"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:
|
||
|
||
- `manifest` link to `/manifest.webmanifest`
|
||
- `apple-web-app-capable: true` for iOS standalone mode
|
||
- `apple-web-app-status-bar-style: black-translucent`
|
||
- `mobile-web-app-capable: yes` for Android Chrome
|
||
- `theme-color: #0b0f1a`
|
||
- `viewport-fit: cover` for edge-to-edge rendering
|
||
|
||
### Component: `PwaRegister`
|
||
|
||
Located at `src/shared/components/PwaRegister.tsx`, this client component:
|
||
|
||
1. Runs on mount (client-side only)
|
||
2. Checks for `serviceWorker` support in the browser
|
||
3. Registers `/sw.js` silently (errors are swallowed to avoid blocking the app)
|
||
4. 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:
|
||
|
||
1. Start OmniRoute in Termux: `npx omniroute`
|
||
2. Open Chrome on the same phone: `http://localhost:20128`
|
||
3. Install the PWA via "Add to Home Screen"
|
||
4. 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:20128` and 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) |
|