Felgo allows local development and deployment for the Web with WebAssembly. WebAssembly is a bytecode representation generated from C++ code that is executed inside a virtual machine in web browsers. Most of the recent browser versions of Chrome, Firefox and Safari support running WebAssembly code.
Felgo targets WebAssembly as another Desktop platform. This allows you to target your mobile users via the app stores while running the very same app from a single source code on the Web for the desktop.
Note: Due to mobile browser support of WebAssembly, running the WebAssembly target on mobile devices is currently not intended.
This guide describes how to deploy Felgo apps & games for the Web.
You can test your code on the browser without any additional setup, using the Felgo Live Client for Web. You can open the Web Live Client with the "Web Client" tab within Felgo Live Server.
The Felgo installer only installs the packages for your desktop system initially. You can add other packages via the Maintenance Tool. Please note you'll need a Qt commercial license to distribute your application with Qt for WASM. Contact us here to get access to the Felgo for WASM package first.
The Maintenance Tool is located at the installation directory of your Felgo SDK. The executable is called SDKMaintenanceTool. Run this application and select Add or remove components and then choose the platforms you want to add.
Felgo for WebAssembly uses the Emscripten compiler to build C++ portable applications to target browsers with WebAssembly support.
WebAssembly builds are created statically, which means all libraries and files required by your app are packaged within the binary format for WebAssembly (.wasm).
WASM apps can only access files that are bundled via the qrc file system. In contrast to building for Desktop or the mobile platforms, you also have to add your asset files (images, fonts, etc) to the qrc file.
Qt Creator ships with an experimental plugin to build a WASM app. Currently, the recommended way is to build your apps from the command line, as described with the following steps:
1. Open a cmd terminal and add the MinGW compiler directory to the path:
set PATH=<Path to your Felgo SDK>\Tools\mingw730_32\bin;%PATH%
2. Set compiler environment variables:
<Path to your Felgo SDK>\Felgo\wasm_32\emsdk\emsdk_env.bat
3. Create your build dir outside your project folder (shadow build directory):
mkdir build-wasm && cd build-wasm
4. Run qmake:
<Path to your Felgo SDK>\Felgo\wasm_32\bin\qmake.exe <Project Path>
5. Run `make` to build the wasm file:
1. Open a Terminal and setup the environment:
source <Path to your Felgo SDK>/Felgo/wasm_32/emsdk/emsdk_env.sh
2. Create a build directory outside your project folder (shadow build directory):
mkdir build-wasm && cd build-wasm
3. Run qmake
<Path to your Felgo SDK>/Felgo/wasm_32/bin/qmake <PROJECT_PATH>
3. Run `make` to build the wasm file
Note: You can run
make -j <nproc>, being nproc the number of cores you have available to speed up the process running in parallel build
The build process will generate multiple files:
Opening the generated index.html file directly in your web browser won’t work because loading WASM modules is only supported via a web server. To run your app, you therefore need to load it from a (local) web server.
For local testing, you can run the included web server by executing the command
emrun --browser chrome index.html from within the dist folder in your terminal.
Note: You can also run
python -m SimpleHTTPServer or
ruby -run -e httpd -- -p 8000 in your build directory to use Python or Ruby to serve your build.
In order to publish your app or game, you need to use a static web server. Most common servers do just fine, but there are a few considerations to deliver the best user experience:
In order for browsers to download and compile your binary files quicker, they can take advantage of streamed compilation. This only works if browsers know that they are dealing with a WebAssembly binary in
advance. To tell them, you need to set the
Content-Type: application/wasm header.
Make sure that your server is sending the
Cache-Control headers. This way, subsequent opens of the website load the wasm files from cache. A new download is only triggered if you have
updated your .wasm file (you can set the highest
max-age value possible for your wasm files).
Qt .wasm files might be a bit larger than what most users would expect. To reduce download time, enable compression at your server configuration. We suggest using gzip but you can also try brotli (bear in mind that is less widely supported). You can also compress the .wasm file beforehand using gzip, this reduces the download size up to half the original file size and therefore greatly improves the download time.
With the default HTML, the target canvas uses the full size of the browser window. You can modify the HTML to your needs to define a canvas that coexists with different HTML elements, like in the example illustrated below.
Your app runs in a sandboxed environment inside the browser that has the same restrictions as the rest of your website, such as:
Following NativeUtils QML APIs are not supported with WebAssembly:
The WebAssembly platform currently does not ship with the following Qt modules and QML components:
Following Qt modules can be used but functionality is not implemented for WebAssembly:
Due to the current implementation of Qt, WebAssembly applications report the platform as “unix” in the platform.os string. Instead of that you can use the “system.isPlatform(System.Wasm)” check in your QML code to get to know if you are running your app as a WebAssembly build.
Destructors are not called on app exit, due to the way WebAssembly main loop is implemented, C++ destructors execution is not not guaranteed on application exit.
Since the WebAssembly platform is single threaded, the implementation for the QML/JS Engine WorkerScript component is synchronous.
Applications do not have access to system fonts. Font files must be distributed with the app in qrc files.
Qt renders application content to a canvas element, and does not use native DOM elements. Therefore, accessibility tools like screen readers are not supported and text inputs do not necessarily trigger virtual keyboards.