Publish to the Web
Production build, Firebase Hosting, Vercel, a custom domain, and PWA.
Implementation
Via MCP: for web Auth with a custom domain, ask "list authorized domains" or "add app.yourbrand.com to the domains" (manage_domain). Favicon: set_favicon. Static build/hosting is still via the terminal (below). See Kasy MCP.
-
Generate the production build:
flutter build web --release --dart-define=ENV=prodThe finished site lands in the
build/webfolder. It's a static site: any hosting works.--dart-define=ENV=prodis required. Without it the build uses the development config.Optional: compile to WebAssembly.
flutter build web --wasm --release --dart-define=ENV=prodcompiles to WebAssembly instead of JavaScript, with an automatic fallback to JavaScript on browsers without support (no user is left without an app). Tested and working in Kasy starting from Flutter 3.47. Details and why it isn't the default in WebAssembly (Wasm), below. -
Choose your hosting:
Option 1: Firebase Hosting (Firebase backend)
If your backend is Firebase, the project already comes configured:
firebase.jsonpoints atbuild/web, with the right SPA rewrites and cache headers. Publishing is just:flutter build web --release --dart-define=ENV=prod firebase deploy --only hostingAt the end, the terminal shows the URL (
https://your-project.web.app).For a custom domain:
- Firebase Console → Hosting → Add custom domain
- Type in the domain (e.g.,
app.yourbrand.com) - Create the DNS records the console shows you (at your domain provider)
- Wait for verification: the HTTPS certificate is automatic
Option 2: Vercel (any backend)
Works with Firebase, Supabase, or REST API, since the build is static.
- Create an account at vercel.com
- Run the production build (command above)
- Publish the folder:
npm i -g vercel cd build/web vercel --prodCustom domain: Vercel dashboard → your project → Settings → Domains.
Netlify, Cloudflare Pages, or any static host also work: the process is the same, build and upload the
build/webfolder. -
After publishing, unlock login:
Google Sign-In
Add the production domain and
http://localhost:5555as authorized origins: Google Cloud Console → Credentials → your OAuth Client → Authorized JavaScript origins.Firebase Auth (authorized domains)
Firebase Console → Authentication → Settings → Authorized domains → add the production domain. Without this, social login fails with
auth/unauthorized-domain.Supabase Auth (authorized domains)
Supabase Dashboard → Authentication → URL Configuration → add the production domain (and
http://localhost:5555while testing locally) under Site URL / Redirect URLs. Without this, social login redirects to the wrong domain or fails silently. Automated deploy only setslocalhost:5555inuri_allow_list.
Information
Development
kasy run --web # prints localhost:5555
kasy run --web --open-browser # opens in your browser (Google account, extensions)
kasy run --web --open-browser --fresh # same browser, clears dev storage (onboarding)
kasy clear-web # clear storage only (app already running)
kasy run --web --open # Flutter's isolated Chrome (clean profile, no account)| Command | Where it opens |
|---|---|
--open-browser | System default browser, in the profile where you're already logged in |
--open | A separate Flutter Chrome window, no accounts or extensions |
Port 5555 is fixed so the Firebase Auth session persists between runs. Details in Run the app.
WebAssembly (Wasm)
flutter build web --wasm compiles the app to WebAssembly instead of JavaScript. Real, measured gain, per the Flutter team's own numbers: up to 2x faster on screens with heavy animation or widget rebuilds, with less jitter. A browser without Wasm support loads the JavaScript version automatically, no extra configuration needed.
It still isn't the recommended default command for one reason: the full performance gain (parallel rendering, not just the compilation) requires the server to send the Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers. Those headers isolate the browser tab and can break social login done via popup (Google, Facebook). Without them, the app in Wasm still works normally, just without the extra multithreading gain.
If you want to turn it on:
- Swap the build for
flutter build web --wasm --release --dart-define=ENV=prod. - Publish as usual (Firebase Hosting, Vercel, etc.).
- Only add the COOP/COEP headers if you want to test the multithreading gain, and test social login afterward, in an incognito tab, before confirming in production.
More technical details: docs.flutter.dev/platform-integration/web/wasm.
PWA
The web app is already installable as a PWA. Customize:
- Icons and colors:
web/manifest.json(background_color,theme_color) - Favicon:
kasy favicon --image your-icon.png(guide)
Last updated on 08/23/2026

