Flutter web: deploying your app to the browser
By Ann Tech · 21 April 2026
Flutter web compiles Dart to JavaScript (or WASM) and renders using either a DOM-based or CanvasKit renderer. You can ship the same codebase to iOS, Android, and web — with some caveats.
Enabling web support
flutter config --enable-web
flutter create . --platforms web # Add web to existing project
flutter run -d chrome
Renderer options
Flutter web has two renderers:
HTML renderer (default for mobile web):
- Uses HTML/CSS/Canvas elements
- Smaller initial download (~1 MB)
- Less accurate font rendering
- Better performance on low-end devices
CanvasKit renderer (default for desktop web):
- Renders using WebAssembly + Skia
- Pixel-perfect output matching mobile
- Larger initial download (~2 MB for CanvasKit WASM)
- Better for complex graphics and text
# Force a renderer:
flutter build web --web-renderer canvaskit
flutter build web --web-renderer html
flutter run -d chrome --web-renderer canvaskit
Building for production
flutter build web --release --web-renderer canvaskit
# Output is in build/web/
# Deploy the entire build/web/ directory to your hosting provider
Deploying to Firebase Hosting
npm install -g firebase-tools
firebase login
firebase init hosting # Point public directory to build/web
flutter build web --release
firebase deploy
firebase.json:
{
"hosting": {
"public": "build/web",
"rewrites": [{ "source": "**", "destination": "/index.html" }],
"headers": [{
"source": "**/*.@(js|wasm)",
"headers": [{ "key": "Cache-Control", "value": "max-age=31536000" }]
}]
}
}
Handling URL routing
Flutter web uses hash-based routing by default (/#/products). Switch to path-based routing for cleaner URLs:
// main.dart
import 'package:flutter_web_plugins/url_strategy.dart';
void main() {
usePathUrlStrategy(); // Must be called before runApp
runApp(const MyApp());
}
Your server must serve index.html for all routes — the Firebase Hosting rewrite rule above handles this.
SEO and meta tags
Flutter web renders in a canvas — search engine crawlers can't read it. For SEO-critical content, use pre-rendering or add meta tags:
<!-- web/index.html -->
<meta name="description" content="Your app description">
<meta property="og:title" content="Your App">
<meta property="og:image" content="https://yourapp.com/og-image.png">
For full SEO, consider a server-side rendering solution for landing pages and serve the Flutter app for authenticated/app screens.
Platform-specific code
import 'package:flutter/foundation.dart';
if (kIsWeb) {
// Web-only behavior
// Can't use dart:io, platform channels, or mobile-specific packages
}
// Conditional imports for platform-specific implementations:
import 'share_stub.dart'
if (dart.library.io) 'share_mobile.dart'
if (dart.library.html) 'share_web.dart';
Packages that don't support web
Some popular packages don't support Flutter web:
flutter_secure_storage(no Keychain/Keystore on web)sqflite(uses SQLite via native)- Platform-channel-based packages without a web implementation
Check pub.dev for the "Web" platform badge before adding a package if web is a target.
Common pitfalls
Using dart:io on web. dart:io (File, HttpClient, Platform) is not available on web. Use dart:html for browser APIs or use conditional imports.
Ignoring load time. A Flutter web app with CanvasKit downloads ~2 MB before showing anything. Use a loading indicator in index.html, and consider the HTML renderer for simpler apps targeting mobile browsers.
Not testing across browsers. Flutter web targets Chrome primarily, but test in Firefox and Safari. Some CanvasKit rendering differences appear in Safari.
Sign in to like, dislike, or report.