# Progressive Web App (PWA) Guide (Italiano) 🌐 **Languages:** 🇺🇸 [English](../../../../guides/PWA_GUIDE.md) · 🇪🇹 [am](../../../am/docs/guides/PWA_GUIDE.md) · 🇸🇦 [ar](../../../ar/docs/guides/PWA_GUIDE.md) · 🇦🇿 [az](../../../az/docs/guides/PWA_GUIDE.md) · 🇧🇬 [bg](../../../bg/docs/guides/PWA_GUIDE.md) · 🇧🇩 [bn](../../../bn/docs/guides/PWA_GUIDE.md) · 🇧🇦 [bs](../../../bs/docs/guides/PWA_GUIDE.md) · 🇨🇿 [cs](../../../cs/docs/guides/PWA_GUIDE.md) · 🇩🇰 [da](../../../da/docs/guides/PWA_GUIDE.md) · 🇩🇪 [de](../../../de/docs/guides/PWA_GUIDE.md) · 🇬🇷 [el](../../../el/docs/guides/PWA_GUIDE.md) · 🇪🇸 [es](../../../es/docs/guides/PWA_GUIDE.md) · 🇪🇪 [et](../../../et/docs/guides/PWA_GUIDE.md) · 🇮🇷 [fa](../../../fa/docs/guides/PWA_GUIDE.md) · 🇫🇮 [fi](../../../fi/docs/guides/PWA_GUIDE.md) · 🇫🇷 [fr](../../../fr/docs/guides/PWA_GUIDE.md) · 🇮🇪 [ga](../../../ga/docs/guides/PWA_GUIDE.md) · 🇮🇳 [gu](../../../gu/docs/guides/PWA_GUIDE.md) · 🇳🇬 [ha](../../../ha/docs/guides/PWA_GUIDE.md) · 🇮🇱 [he](../../../he/docs/guides/PWA_GUIDE.md) · 🇮🇳 [hi](../../../hi/docs/guides/PWA_GUIDE.md) · 🇭🇷 [hr](../../../hr/docs/guides/PWA_GUIDE.md) · 🇭🇺 [hu](../../../hu/docs/guides/PWA_GUIDE.md) · 🇦🇲 [hy](../../../hy/docs/guides/PWA_GUIDE.md) · 🇮🇩 [id](../../../id/docs/guides/PWA_GUIDE.md) · 🇳🇬 [ig](../../../ig/docs/guides/PWA_GUIDE.md) · 🇯🇵 [ja](../../../ja/docs/guides/PWA_GUIDE.md) · 🇬🇪 [ka](../../../ka/docs/guides/PWA_GUIDE.md) · 🇰🇭 [km](../../../km/docs/guides/PWA_GUIDE.md) · 🇮🇳 [kn](../../../kn/docs/guides/PWA_GUIDE.md) · 🇰🇷 [ko](../../../ko/docs/guides/PWA_GUIDE.md) · 🇱🇹 [lt](../../../lt/docs/guides/PWA_GUIDE.md) · 🇱🇻 [lv](../../../lv/docs/guides/PWA_GUIDE.md) · 🇮🇳 [ml](../../../ml/docs/guides/PWA_GUIDE.md) · 🇮🇳 [mr](../../../mr/docs/guides/PWA_GUIDE.md) · 🇲🇾 [ms](../../../ms/docs/guides/PWA_GUIDE.md) · 🇲🇹 [mt](../../../mt/docs/guides/PWA_GUIDE.md) · 🇲🇲 [my](../../../my/docs/guides/PWA_GUIDE.md) · 🇳🇵 [ne](../../../ne/docs/guides/PWA_GUIDE.md) · 🇳🇱 [nl](../../../nl/docs/guides/PWA_GUIDE.md) · 🇳🇴 [no](../../../no/docs/guides/PWA_GUIDE.md) · 🇮🇳 [or](../../../or/docs/guides/PWA_GUIDE.md) · 🇮🇳 [pa](../../../pa/docs/guides/PWA_GUIDE.md) · 🇵🇭 [phi](../../../phi/docs/guides/PWA_GUIDE.md) · 🇵🇱 [pl](../../../pl/docs/guides/PWA_GUIDE.md) · 🇵🇹 [pt](../../../pt/docs/guides/PWA_GUIDE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/guides/PWA_GUIDE.md) · 🇷🇴 [ro](../../../ro/docs/guides/PWA_GUIDE.md) · 🇷🇺 [ru](../../../ru/docs/guides/PWA_GUIDE.md) · 🇱🇰 [si](../../../si/docs/guides/PWA_GUIDE.md) · 🇸🇰 [sk](../../../sk/docs/guides/PWA_GUIDE.md) · 🇸🇮 [sl](../../../sl/docs/guides/PWA_GUIDE.md) · 🇷🇸 [sr](../../../sr/docs/guides/PWA_GUIDE.md) · 🇸🇪 [sv](../../../sv/docs/guides/PWA_GUIDE.md) · 🇰🇪 [sw](../../../sw/docs/guides/PWA_GUIDE.md) · 🇮🇳 [ta](../../../ta/docs/guides/PWA_GUIDE.md) · 🇮🇳 [te](../../../te/docs/guides/PWA_GUIDE.md) · 🇹🇭 [th](../../../th/docs/guides/PWA_GUIDE.md) · 🇹🇷 [tr](../../../tr/docs/guides/PWA_GUIDE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/guides/PWA_GUIDE.md) · 🇵🇰 [ur](../../../ur/docs/guides/PWA_GUIDE.md) · 🇺🇿 [uz](../../../uz/docs/guides/PWA_GUIDE.md) · 🇻🇳 [vi](../../../vi/docs/guides/PWA_GUIDE.md) · 🇳🇬 [yo](../../../yo/docs/guides/PWA_GUIDE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/guides/PWA_GUIDE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/guides/PWA_GUIDE.md) --- OmniRoute viene distribuito come Progressive Web App completamente installabile. Quando accedi alla dashboard da qualsiasi browser mobile — Android (Chrome) o iOS (Safari) — puoi selezionare "Aggiungi alla schermata Home" e ottenere un'esperienza simile a quella di un'app nativa, senza dover utilizzare alcun app store. ## Che cos'è una PWA? Una Progressive Web App trasforma la dashboard web di OmniRoute in qualcosa che ha l'aspetto e il comportamento di un'app mobile nativa. Una volta installata: - Si avvia dalla schermata Home con una propria icona - Si apre a schermo intero, senza barra degli indirizzi o interfaccia delle schede del browser - Funziona offline grazie a una pagina dedicata alla connettività - Memorizza nella cache le risorse statiche per un caricamento più rapido - Supporta sia l'orientamento verticale sia quello orizzontale ## Installazione ### Android (Chrome) 1. Apri la dashboard di OmniRoute in Chrome: `http://YOUR_IP:20128` 2. Chrome mostrerà automaticamente il banner **"Aggiungi OmniRoute alla schermata Home"** oppure: - Tocca il menu **⋮** (tre puntini) → **"Aggiungi alla schermata Home"** o **"Installa app"** 3. Conferma la richiesta 4. OmniRoute viene visualizzato sulla schermata Home come app autonoma ### iOS (Safari) 1. Apri la dashboard di OmniRoute in Safari: `http://YOUR_IP:20128` 2. Tocca il pulsante **Condividi** (riquadro con freccia) 3. Scorri verso il basso e tocca **"Aggiungi alla schermata Home"** 4. Assegna un nome all'app (quello predefinito è "OmniRoute") e tocca **Aggiungi** 5. OmniRoute viene visualizzato sulla schermata Home con l'icona dell'app ### Desktop (Chrome / Edge) 1. Apri la dashboard di OmniRoute 2. Fai clic sull'**icona di installazione** nella barra degli indirizzi (oppure ⋮ → "Installa OmniRoute...") 3. Conferma la richiesta 4. OmniRoute si apre come finestra autonoma, senza schede né barra degli indirizzi ## Funzionalità ### Esperienza a schermo intero Il manifest è configurato con `display: "fullscreen"`, il che significa che l'app installata utilizza l'intero schermo, senza elementi dell'interfaccia del browser né sovrapposizioni della barra di stato. In questo modo, la dashboard offre un'esperienza realmente simile a quella di un'app nativa. ### Supporto offline OmniRoute include un service worker (`sw.js`) che offre una gestione intelligente della cache: | Tipo di risorsa | Strategia | Comportamento | | --------------------------------------------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | | **Shell dell'app** | Prima la cache | `/`, `/offline`, il manifest e le icone vengono memorizzati nella cache durante l'installazione | | **Risorse statiche** (CSS, JS, immagini, caratteri) | Prima la rete, con fallback sulla cache | Recupera risorse aggiornate dalla rete; se offline, utilizza la cache | | **Bundle Next.js** (`/_next/`) | Prima la rete, con aggiornamento della cache | Recupera dalla rete e aggiorna la cache; se offline, fornisce la versione memorizzata nella cache | | **Richieste di navigazione** | Esclusione (mai intercettate) | Il browser gestisce il fallback HTTP/3→HTTP/2; un socket QUIC non attivo non deve diventare `Response.error()` | | **Route API / dashboard** (`/api/`, `/a2a`, `/dashboard`) | Esclusione (mai memorizzate nella cache) | Vanno sempre direttamente al server, senza mai essere intercettate dal service worker | ### Pagina offline Quando la rete non è disponibile e un utente passa a una nuova pagina, il service worker mostra una pagina `/offline` dedicata che: - Visualizza un chiaro messaggio **"Problema di connettività"** - Mostra un **indicatore dello stato online/offline** in tempo reale, che si aggiorna automaticamente - Fornisce un pulsante **"Riprova connessione"** per ricaricare la pagina quando la connettività viene ripristinata - Include un collegamento alla **Pagina di stato** per la diagnostica ### Icone dell'app OmniRoute fornisce icone ottimizzate per ciascuna piattaforma: | File | Dimensioni | Utilizzato da | | ---------------------- | -------------------- | ------------------------------------------------------ | | `icon-512.png` | 512×512 | Richiesta di installazione Android, schermata iniziale | | `apple-touch-icon.png` | 180×180 | Icona della schermata Home di iOS | | `icon-192.svg` | 192×192 (vettoriale) | Icona adattiva Android | | `apple-touch-icon.svg` | 180×180 (vettoriale) | Icona Apple di fallback | | `favicon.svg` | Vettoriale | Schede del browser | | `favicon.ico` | Più dimensioni | Browser legacy | ### Registrazione automatica Il service worker viene registrato automaticamente tramite il componente `` nel layout radice. Non è richiesta alcuna azione da parte dell'utente: l'app diventa installabile non appena il browser rileva il manifest e il service worker validi. ## Architettura tecnica ### Manifest dell'app web (`manifest.webmanifest`) Generato da Next.js tramite `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`) Un service worker vanilla (senza dipendenze da framework) con: - **Fase di installazione**: memorizza preventivamente nella cache la shell dell'app (pagina principale, pagina offline, manifest, icone) - **Fase di attivazione**: elimina le vecchie versioni della cache e prende il controllo di tutti i client - **Fase di fetch**: instradamento intelligente in base al tipo di richiesta (navigazione, risorsa statica, API) - **Versionamento della cache**: `omniroute-pwa-v3` — incrementare questo valore per forzare una nuova cache dopo un aggiornamento ### Metadati del layout (`src/app/layout.tsx`) Il layout radice fornisce tutti i meta tag necessari per la conformità PWA: - collegamento `manifest` a `/manifest.webmanifest` - `apple-web-app-capable: true` per la modalità standalone su iOS - `apple-web-app-status-bar-style: black-translucent` - `mobile-web-app-capable: yes` per Chrome su Android - `theme-color: #0b0f1a` - `viewport-fit: cover` per il rendering da bordo a bordo ### Componente: `PwaRegister` Situato in `src/shared/components/PwaRegister.tsx`, questo componente client: 1. Viene eseguito al montaggio (solo lato client) 2. Verifica il supporto di `serviceWorker` nel browser 3. Registra `/sw.js` in modo silenzioso (gli errori vengono ignorati per evitare di bloccare l'app) 4. Non esegue alcun rendering (`return null`) — è un componente dedicato esclusivamente agli effetti collaterali ## Utilizzo con Termux (Android) Quando OmniRoute viene eseguito su Android tramite Termux, la PWA funziona senza problemi: 1. Avviare OmniRoute in Termux: `npx omniroute` 2. Aprire Chrome sullo stesso telefono: `http://localhost:20128` 3. Installare la PWA tramite "Aggiungi a schermata Home" 4. La PWA si connette al server Termux locale — tutto viene eseguito sul dispositivo Questa combinazione fa sì che il telefono Android sia sia il **server** (Termux) sia il **client** (PWA) — un gateway AI completo e autosufficiente. ## Utilizzo da altri dispositivi Installare la PWA su qualsiasi dispositivo che possa accedere tramite browser al server OmniRoute: - **Un altro telefono/tablet**: accedere a `http://PHONE_IP:20128` e installare la PWA - **Computer portatile**: aprire Chrome/Edge e installarla come PWA desktop - **Smart TV con browser**: accedere alla dashboard a schermo intero ## Personalizzazione ### Nome dell'istanza Il titolo della PWA rispetta l'impostazione **Nome istanza** in `Dashboard → Impostazioni`. Se l'istanza viene rinominata in "Il mio gateway AI", la PWA installata mostrerà tale nome. ### Favicon personalizzata Se viene caricata una favicon personalizzata tramite `Dashboard → Impostazioni`, l'icona della PWA sul desktop rifletterà l'icona personalizzata. Le icone della schermata Home sui dispositivi mobili utilizzano i file predefiniti `icon-512.png` e `apple-touch-icon.png`. ## Limitazioni - **Nessuna notifica push** — Il service worker non implementa la Push API. Le notifiche sono invece gestite dall'app Electron. - **Nessuna sincronizzazione in background** — Le azioni offline non vengono accodate per essere riprodotte successivamente. La PWA è principalmente un visualizzatore di dashboard. - **Restrizioni di iOS** — Safari su iOS non supporta tutte le funzionalità PWA (ad esempio, le richieste di installazione sono manuali e i service worker in background sono limitati). - **Dimensione della cache** — Il service worker memorizza nella cache solo le risorse statiche. I payload di risposta di grandi dimensioni provenienti dalle route `/api/` non vengono mai memorizzati nella cache. - **Icone personalizzate sui dispositivi mobili** — La modifica della favicon nelle impostazioni non aggiorna l'icona della schermata Home sui dispositivi mobili (ciò richiede la rigenerazione delle icone PWA). ## Riferimento dei file | File | Scopo | | --------------------------------------- | -------------------------------------------------------------------- | | `src/app/manifest.ts` | Route del manifest di Next.js (genera `manifest.webmanifest`) | | `public/sw.js` | Service worker con logica di memorizzazione nella cache | | `src/shared/components/PwaRegister.tsx` | Componente client che registra il service worker | | `src/app/offline/page.tsx` | Pagina di fallback offline con indicatore dello stato in tempo reale | | `src/app/layout.tsx` | Layout radice con metadati PWA (apple-web-app, theme-color, ecc.) | | `public/icon-512.png` | Icona PNG 512×512 (Android, schermata iniziale) | | `public/apple-touch-icon.png` | Icona PNG 180×180 (schermata Home di iOS) | | `public/icon-192.svg` | Icona SVG 192×192 (icona adattiva di Android) | | `public/apple-touch-icon.svg` | Icona SVG 180×180 (fallback per Apple) |