Publish web app as static website
Instructions for publishing Flet app into a standalone static website (SPA) that runs entirely in the browser with Pyodide and does not require any code running on the server side.
Pyodide is a port of CPython to WebAssembly (WASM) which is an emerging technology with some limitations.
::note Native Python packages
Native Python packages (vs "pure" Python packages written in Python only) are packages that partially written in
C, Rust or other languages producing native code. Example packages are numpy
, cryptography
, lxml
, pydantic
.
Pyodide comes with a big list of built-in packages. However, to use a Python package from PyPI it must be a pure Python package or provide a wheel with binaries built for Emscripten. ::
Async and threading#
Flet app that published to a static website could use both sync and async event handlers and methods.
Pyodide is a WebAssembly application which does not support threading. The entire Flet is running in a single thread
and all sync and async control event handlers are running in the same thread. If your app has CPU-bound logic
(e.g. calculating Fibonacci 😀) or "sleeps" to make UI prettier it may "hang" UI. Consider moving that logic to
a server and calling it via web API. Using asyncio.sleep
in async methods is OK though.
flet build web
#
Publish Flet app as a static website.
This is the recommended publishing method for static website.
Prerequisites#
Flutter SDK must be installed on your computer for flet build web
command to work.
Building website#
To publish Flet app as a static website run the following command from the root of your Flet app:
A static website is published into ./build/web
directory.
Testing website#
You can test a published Flet app using Python's built-in http.server
module:
Open http://localhost:8000
in your browser to check the published app.
Packaging assets#
Once the website is published all files from assets
directory will be copied "as is" to the root of the website.
This allows overriding such things as favicon.png
or manifest.json
with your own content.
URL strategy#
Flet apps support two ways of configuring URL-based routing:
- path (default) - paths are read and written without a hash. For example,
fletapp.dev/path/to/view
. - hash - paths are read and written to the hash fragment. For example,
fletapp.dev/#/path/to/view
.
If a hosting provider supports Single-page application (SPA) rendering you can leave default "path" URL strategy as it gives pretty URLs.
However, if a hosting provider (like GitHub Pages) doesn't support SPA mode then you need to publish your app with "hash" URL strategy.
Use --route-url-strategy
argument to change URL strategy.
Web renderer#
You can change default "canvaskit" web renderer (more about renderers here to "html" with --web-renderer
option:
Color emojis#
To reduce app size default "CanvasKit" renderer does not use colorful emojis, because the font file with color emojies weights around 8 MB.
You can, however, opt-in for color emojis with --use-color-emoji
flag:
Alternatively, switch to html
renderer which uses browser fonts.
Hosting website in a sub-directory#
Multiple Flet apps can be hosted on a single domain - each app in it's own sub-directory.
To make a published Flet app work in a sub-directory you have to publish it with --base-url
option:
For example, if app's URL is https://mywebsite.com/myapp
then it must be published with --base-url myapp
.
Disable splash screen#
The splash screen is enabled/shown by default.
It can be disabled as follows:
flet publish
#
An alternative method to publish Flet app as a static website.
Compared to flet build web
command it does not require Flutter SDK to be installed on your computer.
However, static websites built with flet build web
command, compared to flet publish
, have faster load time
as all Python dependencies are now packaged into a single archive instead of being pulled in runtime with micropip
.
flet build web
also detects native Python packages built into Pyodide, such as bcrypt
, html5lib
, numpy
and many others, and installs them from Pyodide package registry.
Publish app as a static website#
Run the following command to publish Flet app to a standalone website:
A static website is published into ./dist
directory.
Command optional arguments:
--pre
- allow micropip to install pre-release Python packages.-a ASSETS_DIR
,--assets ASSETS_DIR
- path to an assets directory.--app-name APP_NAME
- application namee.--app-description APP_DESCRIPTION
- application description.--base-url BASE_URL
- base URL for the app.--web-renderer {canvaskit,html}
- web renderer to use.--route-url-strategy {path,hash}
- URL routing strategy.
Testing website#
You can test a published Flet app using Python's built-in http.server
module:
Open http://localhost:8000
in your browser to check the published app.
Loading packages#
You can load custom packages from PyPI during app start by listing them in requirements.txt
. requirements.txt
must be created in the same directory with <your-flet-app.py>
.
Each line of requirements.txt
contains a package name followed by an optional version specifier.
Micropip
To install custom packages Pyodide uses micropip - a lightweight version of pip
that works in a browser.
You can use Micropip API directly in your Flet app:
Pre-release Python packages#
You can allow loading pre-release versions of PyPI packages, by adding --pre
option to flet publish
command:
Assets#
If your app requires assets (images, fonts, etc.) you can copy them into website directory by using --assets <directory>
option with flet publish
command:
::caution
If you have assets
directory in your app's directory and don't specify --assets
option then the contents of assets
will be packaged along with a Python application rather than copied to dist
.
::
URL strategy#
Flet apps support two ways of configuring URL-based routing:
- Path (default) - paths are read and written without a hash. For example,
fletapp.dev/path/to/view
. - Hash - paths are read and written to the hash fragment. For example,
fletapp.dev/#/path/to/view
.
If a hosting provider supports Single-page application (SPA) rendering you can leave default "path" URL strategy as it gives pretty URLs.
However, if a hosting provider (like GitHub Pages) doesn't support SPA mode then you need to publish your app with "hash" URL strategy.
To specify "hash" URL strategy during static app publishing use --route-url-strategy
option:
Web renderer#
You can change default "canvaskit" web renderer (more about renderers here) to "html" with --web-renderer
option:
Color emojis#
To reduce app size default "CanvasKit" renderer does not use colorful emojis, because the font file with color emojies weights around 8 MB.
You can, however, opt-in for color emojis with --use-color-emoji
flag:
Alternatively, switch to html
renderer which uses browser fonts.
Hosting website in a sub-directory#
Multiple Flet apps can be hosted on a single domain - each app in it's own sub-directory.
To make a published Flet app work in a sub-directory you have to publish it with --base-url
option:
For example, if app's URL is https://mywebsite.com/myapp
then it must be published with --base-url myapp
.