This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
Web (TeaVM/WebGL) 🌐
The most honest page in the section. The web target (module web, WebLauncher) compiles the app to
JavaScript via TeaVM and runs it on a WebGL2 <canvas> (backend gdx-teavm). It is not GWT and
it is not an embedded webview: it is the app itself running in the browser.
Build and serve
gradlew :web:webBundle # (alias: dist)
Generates web/build/webapp/ with index.html, web.js, scripts/howler.js, gdx.wasm.js, and
assets/ + assets.txt. Serve it locally:
cd web/build/webapp && python -m http.server 8080
# open http://127.0.0.1:8080/index.html
The WebLauncher does new TeaApplication(new Main(true, cmdline), config).
⚠️ What does NOT work (it is a stub)
On the web, PlatformUtilsWeb implements most features as a stub — the call exists but does
nothing useful:
| Feature | Behavior on the web |
|---|---|
WebContainer |
createWebView() returns null |
| GPS / location | stub (no fix) |
| Bluetooth / radios | stub (WirelessState.UNSUPPORTED) |
| Biometrics | AuthResult.ERROR “Not supported” |
| Voice (TTS/STT) | voiceToText → onError |
| Native maps | not supported |
| Vibration / battery | stub |
| File persistence | Device.homeFolder = null |
Since
crossfly-lib(JNI) is not loaded on WebGL (Main.create()skips theSharedLibraryLoaderon the WebGL target), everything that depends on native code falls back to the stubs above.
What DOES work
- Rendering the full UI (it is the real app on the WebGL2 canvas).
- Opening an external URL / dialing:
PlatformUtils.instance.view(url)/dial(numero)(viaGdx.net.openURI). - HTTP with restrictions (CORS;
Utils.getRemoteFilereturnsnullon failure).
Mandatory pattern: detect and fall back
if (PlatformUtils.instance.createWebView() != null) {
// Android/iOS/Desktop: embedded webview
} else {
PlatformUtils.instance.view(url); // Web: opens in a new tab
}
And check Device.homeFolder == null before attempting to persist a file on the web.
Best practices
- Disable/adapt device features on the web (don’t leave buttons that do nothing).
- Persistence on the web: use whatever is available in your build (don’t count on
homeFolder). - Test by serving the static bundle locally before hosting.
Common mistakes
- Assuming
WebContainer/GPS/biometrics on the web (they are stubs). - Trying
Device.homeFolder + "arquivo"on the web (homeFolderisnull→ NPE).