Customizing web app initialization
You can customize how a Flutter app is initialized on the web using the _flutter.loader
JavaScript API provided by flutter.js
. This API can be used to display a loading indicator in CSS, prevent the app from loading based on a condition, or wait until the user presses a button before showing the app.
The initialization process is split into the following stages:
- Loading the entrypoint script
- Fetches the
main.dart.js
script and initializes the service worker. - Initializing the Flutter engine
- Initializes Flutter's web engine by downloading required resources such as assets, fonts, and CanvasKit.
- Running the app
- Prepares the DOM for your Flutter app and runs it.
This page shows how to customize the behavior at each stage of the initialization process.
Getting started
#By default, the index.html
file generated by the flutter create
command contains a script tag that calls loadEntrypoint
from the flutter.js
file:
<html>
<head>
<!-- ... -->
<script src="flutter.js" defer></script>
</head>
<body>
<script>
window.addEventListener('load', function (ev) {
// Download main.dart.js
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: async function(engineInitializer) {
// Initialize the Flutter engine
let appRunner = await engineInitializer.initializeEngine();
// Run the app
await appRunner.runApp();
}
});
});
</script>
</body>
</html>
The loadEntrypoint
function calls the onEntrypointLoaded
callback once the Service Worker is initialized, and the main.dart.js
entrypoint has been downloaded and run by the browser. Flutter also calls onEntrypointLoaded
on every hot restart during development.
The onEntrypointLoaded
callback receives an engine initializer object as its only parameter. Use the engine initializer to set the run-time configuration, and start the Flutter Web engine.
The initializeEngine()
function returns a Promise
that resolves with an app runner object. The app runner has a single method, runApp()
, that runs the Flutter app.
Customizing web app initialization
#In this section, learn how to customize each stage of your app's initialization.
Loading the entrypoint
#The loadEntrypoint
method accepts these parameters:
Name | Description | JS Type |
---|---|---|
entrypointUrl | The URL of your Flutter app's entrypoint. Defaults to "main.dart.js" . | String |
onEntrypointLoaded | The function called when the engine is ready to be initialized. Receives an engineInitializer object as its only parameter. | Function |
serviceWorker | The configuration for the flutter_service_worker.js loader. (If not set, the service worker won't be used.) | Object |
The serviceWorker
JavaScript object accepts the following properties:
Name | Description | JS Type |
---|---|---|
serviceWorkerUrl | The URL of the Service Worker JS file. The serviceWorkerVersion is appended to the URL. Defaults to "flutter_service_worker.js?v=" | String |
serviceWorkerVersion | Pass the serviceWorkerVersion variable set by the build process in your index.html file. | String |
timeoutMillis | The timeout value for the service worker load. Defaults to 4000 . | Number |
Initializing the engine
#As of Flutter 3.7.0, you can use the initializeEngine
method to configure several run-time options of the Flutter web engine through a plain JavaScript object.
You can add any of the following optional parameters:
Name | Description | Dart Type |
---|---|---|
assetBase | The base URL of the assets directory of the app. Add this when Flutter loads from a different domain or subdirectory than the actual web app. You might need this when you embed Flutter web into another app, or when you deploy its assets to a CDN. | String |
canvasKitBaseUrl | The base URL from where canvaskit.wasm is downloaded. | String |
canvasKitVariant | The CanvasKit variant to download. Your options cover: 1. auto : Downloads the optimal variant for the browser. The option defaults to this value.2. full : Downloads the full variant of CanvasKit that works in all browsers.3. chromium : Downloads a smaller variant of CanvasKit that uses Chromium compatible APIs. Warning: Don't use the chromium option unless you plan on only using Chromium-based browsers. | String |
canvasKitForceCpuOnly | When true , forces CPU-only rendering in CanvasKit (the engine won't use WebGL). | bool |
canvasKitMaximumSurfaces | The maximum number of overlay surfaces that the CanvasKit renderer can use. | double |
debugShowSemanticNodes | If true , Flutter visibly renders the semantics tree onscreen (for debugging). | bool |
hostElement | HTML Element into which Flutter renders the app. When not set, Flutter web takes over the whole page. | HtmlElement |
renderer | Specifies the web renderer for the current Flutter application, either "canvaskit" or "skwasm" . | String |
Engine configuration example
#The initializeEngine
method lets you pass any of the configuration parameters described above to your Flutter app.
Consider the following example.
Your Flutter app should target an HTML element with id="flutter_app"
and use the canvaskit
renderer. The resulting JavaScript code would resemble the following:
onEntrypointLoaded: async function(engineInitializer) {
let appRunner = await engineInitializer.initializeEngine({
hostElement: document.querySelector("#flutter_app"),
renderer: "canvaskit"
});
appRunner.runApp();
}
For a more detailed explanation of each parameter, take a look at the "Runtime parameters" documentation section of the configuration.dart
file of the web engine.
Skipping this step
#Instead of calling initializeEngine()
on the engine initializer (and then runApp()
on the application runner), you can call autoStart()
to initialize the engine with its default configuration, and then start the app immediately after the initialization is complete:
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: async function(engineInitializer) {
await engineInitializer.autoStart();
}
});
Example: Display a progress indicator
#To give the user of your application feedback during the initialization process, use the hooks provided for each stage to update the DOM:
<html>
<head>
<!-- ... -->
<script src="flutter.js" defer></script>
</head>
<body>
<div id="loading"></div>
<script>
window.addEventListener('load', function(ev) {
var loading = document.querySelector('#loading');
loading.textContent = "Loading entrypoint...";
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: async function(engineInitializer) {
loading.textContent = "Initializing engine...";
let appRunner = await engineInitializer.initializeEngine();
loading.textContent = "Running app...";
await appRunner.runApp();
}
});
});
</script>
</body>
</html>
For a more practical example using CSS animations, see the initialization code for the Flutter Gallery.
Upgrading an older project
#If your project was created in Flutter 2.10 or earlier, you can create a new index.html
file with the latest initialization template by running flutter create
as follows.
First, remove the files from your /web
directory.
Then, from your project directory, run the following:
flutter create . --platforms=web
Unless stated otherwise, the documentation on this site reflects the latest stable version of Flutter. Page last updated on 2024-08-16. View source or report an issue.