@hicards/flutter-web-app-loader
v0.1.0
Published
Load Flutter web applications directly into React and JavaScript host pages.
Maintainers
Readme
Flutter Web App Loader
@hicards/flutter-web-app-loader charge une application Flutter Web directement dans un élément HTML. Le package fournit un composant React, une API JavaScript et un script autonome utilisable dans WordPress ou un site HTML classique.
Le rendu direct dans la page utilise le moteur Flutter Web et le DOM de la page hôte. Le site intégrateur doit réserver une largeur et une hauteur non nulles au conteneur.
Par défaut, le loader récupère les scripts JavaScript exécutables déclarés dans l’index.html de l’application Flutter et les charge dans le même ordre. Il ignore les scripts de démarrage Flutter, que le loader prend en charge lui-même. additionalScripts sert aux scripts complémentaires qui ne sont pas déclarés dans cet index.html.
React
npm install @hicards/flutter-web-app-loaderimport { FlutterWebApp } from "@hicards/flutter-web-app-loader";
export function EventWidget() {
return (
<FlutterWebApp
appRepo="https://assets.example.com/flutter"
appName="my-app"
loadingScreen={{
imageUrl: "https://example.com/logo.svg",
backgroundColor: "#ffffff",
}}
style={{ height: "640px" }}
/>
);
}Quand version n’est pas fournie, le loader lit version.json sous appRepo/appName/, puis charge les fichiers de cette version dans appRepo/appName/version/. Une version fixe peut être fournie pour épingler le déploiement :
<FlutterWebApp
appRepo="https://assets.example.com/flutter"
appName="my-app"
version="2026.09.24-1"
/>Il est également possible de fournir directement l’URL du dossier de build :
<FlutterWebApp entrypoint="https://assets.example.com/flutter/my-app/2026.09.24-1/" />assetBase permet de pointer les assets vers un dossier différent de l’entrypoint. additionalScripts charge des scripts complémentaires avant l’initialisation Flutter, par exemple une dépendance qui n’est pas déclarée dans l’index.html de l’application.
Pour laisser Flutter prendre le contrôle de toute la fenêtre plutôt que de dessiner dans le conteneur, utiliser displayMode="full-page" :
<FlutterWebApp
entrypoint="https://assets.example.com/flutter/my-app/2026.09.24-1/"
displayMode="full-page"
/>Dans ce mode, l’élément interne du composant sert au cycle de vie du loader ; Flutter rend l’application en pleine page. Le site hôte ne doit pas initialiser un autre moteur Flutter sur cette page.
Le moteur pleine page n’expose pas de retrait de vue : dispose() retire l’overlay du loader, mais l’application Flutter reste active jusqu’au rechargement ou à la navigation hors de la page.
Options React et JavaScript
| Option | Description |
| --- | --- |
| appRepo, appName, version | Résolution dynamique de la version publiée de l’application. |
| entrypoint, assetBase | URLs directes de l’entrypoint Flutter et des assets. |
| displayMode | embedded par défaut, ou full-page pour utiliser le mode pleine page natif de Flutter. |
| engineMode | single-view par défaut, ou multi-view pour rattacher plusieurs vues au même moteur. |
| renderer | auto par défaut, javascript ou wasm. |
| wasmAllowList, forceSingleThreadedSkwasm | Réglages avancés du moteur WebAssembly. |
| targetStyle | Dimensions et positionnement de l’élément hôte Flutter. |
| initialData | Données passées à addView en mode multi-view. |
| loadIndexScripts | Charge les scripts exécutables de l’index.html Flutter. Activé par défaut ; désactivable si l’hébergeur ne fournit pas ce fichier. |
| loadingScreen | Image ou texte, couleurs de fond et de texte de l’écran de chargement. |
| additionalScripts | Scripts supplémentaires, relatifs à l’entrypoint ou absolus, chargés après ceux de l’index.html. |
| serviceWorker | Active l’enregistrement du service worker Flutter lorsqu’il est disponible sur la même origine. |
| sqfliteEntrypointCookieName | Écrit l’entrypoint Flutter dans un cookie pour un proxy sqflite_common_ffi_web installé sur le site hôte. |
| onStateChange, onReady, onError | Callbacks du cycle de vie du loader. |
Les scripts de l’index.html sont exécutés dans le contexte de la page hôte. Le loader ignore flutter.js, flutter_bootstrap.js, le service worker et les scripts Dart compilés : il démarre lui-même le moteur Flutter sans réexécuter le bootstrap original. Les scripts personnalisés héritent des règles de sécurité CSP du site intégrateur. Les paramètres de moteur et d’entrypoint restent fixes pendant la vie de la page.
Pour contrôler manuellement le cycle de vie depuis React ou du JavaScript :
import { createFlutterWebAppLoader } from "@hicards/flutter-web-app-loader";
const target = document.getElementById("flutter-widget");
if (!target) {
throw new Error("Flutter widget host was not found.");
}
const instance = createFlutterWebAppLoader({
target,
appRepo: "https://assets.example.com/flutter",
appName: "my-app",
});
await instance.ready;
instance.dispose();JavaScript vanilla et WordPress
Le fichier IIFE inclus dans npm s’auto-monte à partir des attributs de la balise <script> :
<div id="flutter-widget"></div>
<script
src="https://cdn.jsdelivr.net/npm/@hicards/[email protected]/dist/flutter-web-app-loader.iife.js"
data-target="flutter-widget"
data-app-repo="https://assets.example.com/flutter"
data-app-name="my-app"
data-loading-text="Chargement de l’expérience…"
data-height="600px"
async
></script>Le loader donne une hauteur par défaut de 600px aux conteneurs vides. data-height et data-width permettent de la personnaliser. Il est préférable d’utiliser une URL CDN avec une version npm épinglée plutôt que @latest.
Les attributs data-entrypoint et data-asset-base remplacent respectivement data-app-repo / data-app-name et l’URL d’assets. Les options JSON suivantes sont disponibles :
<script
src="https://cdn.jsdelivr.net/npm/@hicards/[email protected]/dist/flutter-web-app-loader.iife.js"
data-target="flutter-widget"
data-entrypoint="https://assets.example.com/flutter/my-app/2026.09.24-1/"
data-display-mode="full-page"
data-engine-mode="single-view"
data-renderer="auto"
data-scripts='["scripts/site-dependency.js"]'
data-loading-image="https://example.com/logo.svg"
data-loading-background="#ffffff"
data-service-worker="true"
></script>Les scripts exécutables présents dans l’index.html de Flutter sont repris automatiquement. data-scripts accepte un tableau JSON de scripts complémentaires. data-load-index-scripts="false" désactive la lecture de l’index.html.
Attributs reconnus : data-target, data-app-repo, data-app-name, data-version, data-entrypoint, data-asset-base, data-display-mode, data-engine-mode, data-renderer, data-force-single-threaded-skwasm, data-service-worker, data-load-index-scripts, data-scripts, data-wasm-allow-list, data-initial-data, data-sqflite-entrypoint-cookie, data-loading-text, data-loading-image, data-loading-background, data-loading-text-color, data-width, data-height, data-min-height, data-position et data-overflow.
Le script expose aussi window.FlutterWebAppLoader.mountFlutterWebApp(options) et renvoie une instance avec ready et dispose(). Les événements flutter-web-app-loader:state, flutter-web-app-loader:ready et flutter-web-app-loader:error sont émis sur le conteneur.
Pour un montage manuel avec l’IIFE, omettre data-target de la balise puis appeler :
const target = document.getElementById("flutter-widget");
if (target) {
const widget = window.FlutterWebAppLoader.mountFlutterWebApp({
target,
entrypoint: "https://assets.example.com/my-app/2026.09.24-1/",
});
widget.ready.catch(console.error);
}Préparer l’application Flutter
Le mode single-view s’appuie sur hostElement et convient à une seule intégration par page. Le mode multi-view permet de rattacher plusieurs conteneurs au même moteur. Pour l’utiliser, l’application Flutter doit être construite pour le multi-view : son point d’entrée Dart doit utiliser runWidget avec des widgets View / ViewCollection, et non le runApp habituel.
Un seul moteur Flutter peut être initialisé par page. Plusieurs conteneurs peuvent partager ce moteur en mode multi-view s’ils utilisent la même application et la même configuration. Un moteur Flutter déjà chargé par un autre script sur la page entre en conflit avec ce loader.
Les builds skwasm multithreadés nécessitent un contexte navigateur isolé avec les en-têtes COOP et COEP de Flutter. forceSingleThreadedSkwasm permet de choisir le mode mono-thread lorsque l’hébergeur ne peut pas fournir ces en-têtes.
Le conteneur doit avoir une largeur et une hauteur calculées supérieures à zéro. Le script vanilla applique position: relative, overflow: hidden et une hauteur par défaut de 600px lorsqu’elles manquent. Le composant React fournit également une hauteur par défaut de 600px, modifiable avec style.
Hébergement et limites navigateur
- Les fichiers Flutter doivent être servis en HTTPS en production.
- L’
index.html, l’entrypoint,flutter_bootstrap.js,version.jsonet les assets doivent autoriser les requêtes CORS depuis l’origine du site hôte. - Un service worker ne peut être enregistré que lorsqu’il est sur la même origine que la page hôte. Le loader ignore automatiquement le service worker distant.
sqflite_common_ffi_webcherchesqflite_sw.jsetsqlite3.wasmà la racine de l’origine de la page. Si ces fichiers sont utilisés, le site hôte doit les servir ou installer un proxy compatible.sqfliteEntrypointCookieNamepermet au proxy de retrouver le dossier Flutter résolu.- En mode
single-view, la vue est attachée directement au conteneur fourni. Utilisermulti-viewpour ajouter et retirer proprement des vues au cours de la vie d’une page. Les vues multi-view partagent le même programme Dart et son état ; transmettreinitialDatasi chaque vue doit recevoir un contexte distinct. displayMode="full-page"est incompatible avecengineMode="multi-view": le mode pleine page prend le contrôle du viewport, tandis que le multi-view exige des vues attachées à des éléments hôtes.- Flutter Web ne fournit pas de mode multi-moteur indépendant pour charger des builds Flutter différents directement dans le même document. Pour rester sans iframe, réunir ces expériences dans un même build Flutter conçu pour le multi-view. Les moteurs indépendants sont officiellement pris en charge sur Android, iOS et macOS, pas sur le Web.
Développement
npm install
npm run typecheck
npm run buildLa commande de build génère les entrées ESM et CommonJS, les déclarations TypeScript et le script navigateur dist/flutter-web-app-loader.iife.js.
Licence
MIT
