Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.laportenard.com/llms.txt

Use this file to discover all available pages before exploring further.

The Android app wraps the same statically exported Next.js frontend in a Tauri v2 Android WebView. The Android-specific generated files live in nu_pos_react/src-tauri/gen/android/.

Commands

Run from nu_pos_react/:
npm run tauri android dev     # Build + launch on connected device/emulator
npm run tauri android build   # Build production APK/AAB
Both commands run the Next.js static export first, then invoke the Android Gradle build.

Prerequisites

1

Android SDK

Install Android Studio or the standalone SDK. Set ANDROID_HOME and ensure platform-tools and build-tools are installed.
2

NDK

Install the Android NDK via Android Studio SDK Manager. Required for compiling the Rust native library.
3

Rust Android targets

Add the Android compilation targets:
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
4

USB debugging

On the tablet, enable Developer Options (tap Build Number 7 times), then enable USB Debugging.

Content Security Policy

The CSP is defined in src-tauri/tauri.conf.json under app.security.csp. Android WebView enforces CSP more strictly than desktop platforms.
"csp": "default-src 'self' 'wasm-unsafe-eval'; connect-src 'self' https://ipc.localhost * ; img-src 'self' asset: http://asset.localhost data: http: https:; style-src 'self' 'unsafe-inline';"
Android WebView does not match scheme-specific wildcards like ws://* against IP addresses. Use a bare * in connect-src instead of listing individual scheme wildcards. Desktop platforms are unaffected by this limitation.

Why bare wildcard is needed

The hub runs on the local network at a plain IP address (e.g. ws://10.0.20.63:8766). Per the CSP spec, http://* covers HTTP hosts but not WebSocket schemes. Adding ws://* and wss://* should work in theory, but Android WebView’s CSP implementation fails to match them against raw IP addresses. The bare * wildcard matches all schemes and hosts.

Cleartext traffic

Android 9+ blocks cleartext (non-TLS) network traffic by default. Since the hub uses ws:// on the local network, cleartext must be explicitly allowed. Two files control this:
In src-tauri/gen/android/app/build.gradle.kts, the usesCleartextTraffic manifest placeholder must be "true" for both debug and release:
defaultConfig {
    manifestPlaceholders["usesCleartextTraffic"] = "true"
}
By default, Tauri only sets this to "true" for debug builds. If your hub runs on ws:// (not wss://), you must change the default as well.

Debugging

Inspect the Android WebView remotely using Chrome on your development machine.
1

Enable devtools in Cargo.toml

Add the devtools feature to the Tauri dependency in src-tauri/Cargo.toml:
tauri = { version = "2", features = ["devtools"] }
Without this, Chrome cannot see the WebView in release builds. Debug builds enable it automatically.
2

Connect the device

Connect the Android tablet via USB with USB Debugging enabled.
3

Open Chrome inspector

Navigate to chrome://inspect/#devices in Chrome on your Mac. The app’s WebView should appear in the remote devices list.
4

Inspect

Click Inspect to open full DevTools: Console for JS errors, Network tab (filter by WS for WebSocket), and DOM inspector.
The devtools Cargo feature increases the binary size slightly. You can remove it for production distribution once debugging is complete.

ADB logcat (fallback)

If Chrome DevTools is not available, use ADB to tail logs:
# Filter for your app's process
adb logcat --pid=$(adb shell pidof com.ecohub.nu.restaurant.pos)

# Filter for WebView/network-related messages
adb logcat -s chromium:V | grep -iE "websocket|csp|blocked"

Key differences from desktop

AspectDesktopAndroid
CSP enforcementLenient (Chromium desktop)Strict (Android WebView)
Cleartext trafficAllowed by defaultBlocked by default on Android 9+
WebView debuggingAlways availableRequires devtools Cargo feature for release builds
Window managementtauri-plugin-window-stateNot applicable (excluded via cfg(not(target_os = "android")))
Screen orientationUser-controlledLocked to landscape via AndroidManifest.xml

Sideloading the APK

After building, the APK is located at:
src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk
Install via ADB:
adb install -r app-universal-release.apk
Or transfer the APK to the device and open it from a file manager.