# Progressive Web App (PWA) Guide (Français) 🌐 **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) · 🇮🇪 [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) · 🇮🇹 [it](../../../it/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 est fourni sous la forme d’une Progressive Web App entièrement installable. Lorsque vous accédez au tableau de bord depuis n’importe quel navigateur mobile — Android (Chrome) ou iOS (Safari) — vous pouvez sélectionner « Ajouter à l’écran d’accueil » et profiter d’une expérience similaire à celle d’une application native, sans passer par une boutique d’applications. ## Qu’est-ce qu’une PWA ? Une Progressive Web App transforme le tableau de bord web d’OmniRoute en une application qui ressemble et se comporte comme une application mobile native. Une fois installée, elle : - Se lance depuis votre écran d’accueil avec sa propre icône - S’ouvre en plein écran — sans barre d’adresse ni interface d’onglets du navigateur - Fonctionne hors ligne grâce à une page dédiée à la connectivité - Met en cache les ressources statiques pour accélérer le chargement - Prend en charge les orientations portrait et paysage ## Installation ### Android (Chrome) 1. Ouvrez le tableau de bord OmniRoute dans Chrome : `http://YOUR_IP:20128` 2. Chrome affiche automatiquement une bannière **« Ajouter OmniRoute à l’écran d’accueil »**, sinon : - Appuyez sur le menu **⋮** (trois points) → **« Ajouter à l’écran d’accueil »** ou **« Installer l’application »** 3. Confirmez l’invite 4. OmniRoute apparaît sur votre écran d’accueil en tant qu’application autonome ### iOS (Safari) 1. Ouvrez le tableau de bord OmniRoute dans Safari : `http://YOUR_IP:20128` 2. Appuyez sur le bouton **Partager** (carré avec une flèche) 3. Faites défiler vers le bas et appuyez sur **« Sur l’écran d’accueil »** 4. Nommez l’application (« OmniRoute » par défaut), puis appuyez sur **Ajouter** 5. OmniRoute apparaît sur votre écran d’accueil avec l’icône de l’application ### Ordinateur (Chrome / Edge) 1. Ouvrez le tableau de bord OmniRoute 2. Cliquez sur l’**icône d’installation** dans la barre d’adresse (ou sur ⋮ → « Installer OmniRoute... ») 3. Confirmez l’invite 4. OmniRoute s’ouvre dans une fenêtre autonome — sans onglets ni barre d’adresse ## Fonctionnalités ### Expérience en plein écran Le manifeste est configuré avec `display: "fullscreen"`, ce qui signifie que l’application installée utilise la totalité de l’écran — sans interface du navigateur ni chevauchement avec la barre d’état. Le tableau de bord offre ainsi une expérience véritablement native. ### Prise en charge hors ligne OmniRoute inclut un service worker (`sw.js`) qui assure une mise en cache intelligente : | Type de ressource | Stratégie | Comportement | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | | **Structure de l’application** | Cache en priorité | `/`, `/offline`, le manifeste et les icônes sont préchargés dans le cache lors de l’installation | | **Ressources statiques** (CSS, JS, images, polices) | Réseau en priorité avec repli sur le cache | Récupère les ressources à jour depuis le réseau ; utilise le cache en cas de déconnexion | | **Bundles Next.js** (`/_next/`) | Réseau en priorité avec mise à jour du cache | Récupère les ressources depuis le réseau et met à jour le cache ; fournit la version en cache en cas de déconnexion | | **Requêtes de navigation** | Contournement (jamais interceptées) | Le navigateur gère le repli de HTTP/3 vers HTTP/2 ; un socket QUIC inactif ne doit pas devenir `Response.error()` | | **Routes de l’API / du tableau de bord** (`/api/`, `/a2a`, `/dashboard`, les alias de l’API cliente `/v1`, `/v1beta`, `/models`, `/chat`, `/responses`, `/codex`, ainsi que `/callback`, `/login` ; comparaison insensible à la casse) | Contournement (jamais mises en cache) | Accèdent toujours directement au serveur — elles ne sont jamais interceptées par le service worker | ### Page hors ligne Lorsque le réseau est indisponible et qu’un utilisateur accède à une nouvelle page, le service worker affiche une page `/offline` dédiée qui : - Affiche un message clair **« Problème de connectivité »** - Affiche un **indicateur d’état en ligne/hors ligne** actualisé en temps réel - Fournit un bouton **« Réessayer la connexion »** pour recharger la page lorsque la connectivité est rétablie - Propose un lien vers la **page d’état** à des fins de diagnostic ### Icônes de l’application OmniRoute fournit des icônes optimisées pour chaque plateforme : | Fichier | Taille | Utilisé par | | ---------------------- | ------------------- | ------------------------------------------------- | | `icon-512.png` | 512×512 | Invite d’installation Android, écran de démarrage | | `apple-touch-icon.png` | 180×180 | Icône de l’écran d’accueil iOS | | `icon-192.svg` | 192×192 (vectoriel) | Icône adaptative Android | | `apple-touch-icon.svg` | 180×180 (vectoriel) | Icône de secours Apple | | `favicon.svg` | Vectoriel | Onglets du navigateur | | `favicon.ico` | Plusieurs tailles | Navigateurs anciens | ### Enregistrement automatique Le service worker est enregistré automatiquement via le composant `` dans la mise en page racine. Aucune action de l’utilisateur n’est nécessaire — l’application peut être installée dès que le navigateur détecte le manifeste et le service worker valides. ## Architecture technique ### Manifeste de l’application web (`manifest.webmanifest`) Généré par 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`) Un service worker natif (sans dépendance à un framework) avec : - **Phase d’installation** : met en cache de manière anticipée le shell de l’application (racine, page hors ligne, manifeste, icônes) - **Phase d’activation** : supprime les anciennes versions du cache et prend le contrôle de tous les clients - **Phase de récupération** : routage intelligent selon le type de requête (navigation, ressource statique, API) - **Gestion des versions du cache** : `omniroute-pwa-v3` — incrémentez cette version pour forcer la création d’un nouveau cache lors d’une mise à jour ### Métadonnées de la mise en page (`src/app/layout.tsx`) La mise en page racine fournit toutes les balises méta requises pour la conformité PWA : - Lien `manifest` vers `/manifest.webmanifest` - `apple-web-app-capable: true` pour le mode autonome sur iOS - `apple-web-app-status-bar-style: black-translucent` - `mobile-web-app-capable: yes` pour Chrome sur Android - `theme-color: #0b0f1a` - `viewport-fit: cover` pour un rendu bord à bord ### Composant : `PwaRegister` Situé dans `src/shared/components/PwaRegister.tsx`, ce composant client : 1. S’exécute au montage (côté client uniquement) 2. Vérifie la prise en charge de `serviceWorker` dans le navigateur 3. Enregistre `/sw.js` silencieusement (les erreurs sont ignorées afin de ne pas bloquer l’application) 4. N’affiche rien (`return null`) — il s’agit d’un composant servant uniquement à produire un effet secondaire ## Utilisation avec Termux (Android) Lorsque vous exécutez OmniRoute sur Android via Termux, la PWA fonctionne de manière transparente : 1. Démarrez OmniRoute dans Termux : `npx omniroute` 2. Ouvrez Chrome sur le même téléphone : `http://localhost:20128` 3. Installez la PWA via « Ajouter à l’écran d’accueil » 4. La PWA se connecte au serveur Termux local — tout s’exécute sur l’appareil Cette combinaison signifie que votre téléphone Android est à la fois le **serveur** (Termux) et le **client** (PWA) — une passerelle d’IA complète et autonome. ## Utilisation depuis d’autres appareils Installez la PWA sur tout appareil disposant d’un accès par navigateur à votre serveur OmniRoute : - **Autre téléphone/tablette** : accédez à `http://PHONE_IP:20128` et installez la PWA - **Ordinateur portable** : ouvrez Chrome/Edge et installez-la en tant que PWA de bureau - **Smart TV avec navigateur** : accédez au tableau de bord en plein écran ## Personnalisation ### Nom de l’instance Le titre de la PWA respecte le paramètre **Nom de l’instance** dans `Dashboard → Settings`. Si vous renommez votre instance « Ma passerelle d’IA », la PWA installée affichera ce nom. ### Favicon personnalisé Si vous téléversez un favicon personnalisé via `Dashboard → Settings`, l’icône de la PWA sur ordinateur reflétera cette icône personnalisée. Les icônes de l’écran d’accueil sur mobile utilisent les fichiers prédéfinis `icon-512.png` et `apple-touch-icon.png`. ## Limitations - **Aucune notification push** — Le service worker n’implémente pas l’API Push. Les notifications sont gérées par l’application Electron. - **Aucune synchronisation en arrière-plan** — Les actions hors ligne ne sont pas mises en file d’attente pour être rejouées. La PWA sert principalement à consulter le tableau de bord. - **Restrictions sur iOS** — Safari sur iOS ne prend pas en charge toutes les fonctionnalités des PWA (par exemple, les invites d’installation sont manuelles et les service workers en arrière-plan sont limités). - **Taille du cache** — Le service worker met uniquement en cache les ressources statiques. Les charges utiles volumineuses des réponses provenant des routes `/api/` ne sont jamais mises en cache. - **Icônes personnalisées sur mobile** — La modification du favicon dans les paramètres ne met pas à jour l’icône de l’écran d’accueil sur mobile (cela nécessite de régénérer les icônes de la PWA). ## Référence des fichiers | Fichier | Objectif | | --------------------------------------- | --------------------------------------------------------------------------- | | `src/app/manifest.ts` | Route de manifeste Next.js (génère `manifest.webmanifest`) | | `public/sw.js` | Service worker avec logique de mise en cache | | `src/shared/components/PwaRegister.tsx` | Composant client qui enregistre le service worker | | `src/app/offline/page.tsx` | Page de secours hors ligne avec indicateur d’état en temps réel | | `src/app/layout.tsx` | Mise en page racine avec métadonnées PWA (apple-web-app, theme-color, etc.) | | `public/icon-512.png` | Icône PNG 512×512 (Android, écran de démarrage) | | `public/apple-touch-icon.png` | Icône PNG 180×180 (écran d’accueil iOS) | | `public/icon-192.svg` | Icône SVG 192×192 (icône adaptative Android) | | `public/apple-touch-icon.svg` | Icône SVG 180×180 (solution de secours pour Apple) |