Spaces:
Runtime error
Runtime error
| title: "Progressive Web App (PWA) Guide" | |
| version: 3.8.2 | |
| lastUpdated: 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) | |
| 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) | | |