Publish Flet App as Static Website

Flet apps can be published as standalone static websites (SPAs) running in the browser via Pyodide. This requires no server-side code.

Pyodide and Package Support

  • Pyodide is a WebAssembly port of CPython with limitations.
  • Pure Python packages from PyPI are supported.
  • Native Python packages (C/C++/Rust extensions) require wheels built for Emscripten.
  • Pyodide includes many built-in packages.
  • Async and Threading

  • Flet apps in Pyodide run on a single thread.
  • Both sync and async event handlers execute on this thread.
  • CPU-bound logic or blocking operations (e.g., time.sleep) can freeze the UI.
  • asyncio.sleep in async methods is acceptable.
  • Consider offloading heavy computation to a web API.
  • Publishing Methods

    1. flet build web

  • **Description**: Recommended method for static website publishing.
  • **Prerequisites**: Flutter SDK must be installed.
  • **Command**: flet build web
  • **Output Directory**: ./build/web
  • **Testing**: Use flet serve (opens http://localhost:8000).
  • **Options**:
  • * --web-renderer {canvaskit,html}: Sets the web renderer. Default is canvaskit. * --use-color-emoji: Enables color emojis (increases app size). * --base-url : Publishes the app to a sub-directory (e.g., myapp for https://domain.com/myapp). * --route-url-strategy {path,hash}: Sets URL routing strategy. path (default) for SPA-friendly hosting, hash for providers like GitHub Pages.
  • **Assets**: Files in the assets directory are copied to the website root, allowing overrides (e.g., favicon.png, manifest.json).
  • 2. flet publish

  • **Description**: Alternative method, does not require Flutter SDK.
  • **Command**: flet publish
  • **Output Directory**: ./dist
  • **Testing**: Use flet serve dist (opens http://localhost:8000).
  • **Performance**: Generally slower load time than flet build web as dependencies are pulled at runtime via micropip.
  • **Package Loading**:
  • * Custom packages from PyPI can be listed in requirements.txt in the same directory as the app script. * micropip is used in the browser to install packages. * Direct micropip installation is possible within the app: await micropip.install("package_name") (only if sys.platform == "emscripten").
  • **Options**:
  • * --pre: Allows installation of pre-release Python packages. * -a ASSETS_DIR, --assets ASSETS_DIR: Path to an assets directory to be copied to the output. * --app-name APP_NAME: Sets the application name. * --app-description APP_DESCRIPTION: Sets the application description. * --base-url BASE_URL: Same as in flet build web. * --web-renderer {canvaskit,html}: Same as in flet build web. * --route-url-strategy {path,hash}: Same as in flet build web.
  • **Assets**: Use --assets to copy assets. If assets directory exists and --assets is not specified, its contents are packaged with the Python app, not copied to dist.
  • General Options and Configurations

  • **Web Renderer**: Default is canvaskit. Can be switched to html using --web-renderer html.
  • **Color Emojis**: Default canvaskit renderer omits color emojis to save size. Enable with --use-color-emoji. html renderer uses browser fonts and supports color emojis.
  • **URL Strategy**:
  • * path (default): Suitable for SPA-rendering hosts (e.g., Cloudflare Pages). * hash: Use for hosts that don't support SPA rendering (e.g., GitHub Pages).
  • **Hosting in Sub-directory**: Use --base-url for apps hosted at https://domain.com/.
  • **Disable Splash Screen**:
  • * Command line: Not directly specified for web builds, but related to general splash screen control. * pyproject.toml: Set [tool.flet.splash] android = false (Note: This specific example is for Android, but indicates configuration method).

    Assets

  • Files in the assets directory are copied to the website root.
  • This allows overriding default assets like favicon.png or manifest.json.
  • Use --assets with flet publish to specify an assets directory.
  • If assets directory exists and --assets is not used with flet publish, its contents are packaged internally, not copied to dist.