Offline bundles
Pro+ feature. Ship the launcher as a self-contained ZIP that runs from local storage on each device, with no network required to boot.
Why you might want this
The hosted launcher URL (app.mobilauncher.com/t/your-tenant) works
great if your devices have network the moment they boot. They often
don't:
- Field handhelds that boot inside a warehouse with no Wi-Fi yet
- Tablets staged in a back room before deployment
- Devices in cellular dead zones that re-boot during travel
- Sites where the launcher needs to come up BEFORE the VPN tunnel
- Compliance shops where "phones home on boot" is a non-starter
The bundle solves all of those. The launcher renders entirely from files on the device. It still reaches our server later for things like broadcasts and (Enterprise) remote config — but it never needs the network just to show up.
What's in the bundle
A standard ZIP:
launcher/
├── index.html
├── assets/
│ ├── main-<hash>.js
│ ├── main-<hash>.css
│ └── ... (fonts, icons, lazy-loaded chunks)
├── config.json ← your tenant's launcher config
├── license.json ← your signed Pro/Ent license (the launcher verifies it on boot)
└── README.txt ← deployment notes (this doc, short version)
Total size: ~400 KB gzipped renderer + your config + license. Under a megabyte for every customer. No frameworks pulled at runtime.
How to get one
Portal → Your fleets → click your tenant → Launcher tab → Download offline bundle button at the bottom.
What happens behind the scenes:
- Browser fetches the current renderer template from our R2 (Cloudflare's S3)
- Fetches your tenant's current config + license from our API
- Combines them in your browser with JSZip
- Hands you a
.zipfile to save
No server-side per-customer build. Generation is instant.
How to deploy with SOTI MobiControl File Sync
This is the production path for most Pro customers. MobiControl
File Sync pushes the unpacked bundle to a known directory on every
device, and the Lockdown Profile points at that directory's
index.html via file://.
Step by step:
1. Unpack the ZIP
Locally, or on a build server. You'll push the contents of the
launcher/ directory, not the ZIP itself.
unzip mobilauncher-bundle-<tenant>.zip
# → produces ./launcher/
2. Configure File Sync
MobiControl Console → Profiles → your profile → File Sync section:
| Setting | Value |
|---|---|
| Source | The unpacked launcher/ directory on your build machine |
| Target directory | /sdcard/mobilauncher/ (or another path of your choice) |
| Sync mode | Replace (so old assets don't pile up between updates) |
| Sync on profile apply | Yes |
Save. Push the profile to a test device.
3. Point the Lockdown launcher at the local file
Same profile → Lockdown Profile → Launcher:
| Setting | Value |
|---|---|
| Mode | Web URL |
| URL | file:///sdcard/mobilauncher/index.html |
Save and push. The device reboots into the launcher, loaded entirely from local storage.
4. Update workflow
When you change config in the Portal:
- Re-download the bundle
- Re-push via File Sync
- Devices pick up the change on next sync (or you can force a sync from MobiControl Console)
Yes, this is more steps than the hosted URL (where the device just re-fetches on next reload). The tradeoff is "boots on a sliced network without phoning home" — for fleets that need it, it's worth the extra friction.
How to deploy without MobiControl
If you're using our standalone Android app (no MDM):
# 1. Unpack the bundle locally
unzip mobilauncher-bundle-<tenant>.zip -d /tmp/bundle
# 2. Push the unpacked dir into the app's external files dir
adb push /tmp/bundle/. \
/sdcard/Android/data/com.oakash.mobilauncher.beta/files/launcher
# 3. Launch pointing at the local index.html
adb shell am start -n com.oakash.mobilauncher.beta/.MainActivity \
--es url "file:///sdcard/Android/data/com.oakash.mobilauncher.beta/files/launcher/index.html"
Re-push each time you want to roll out a new bundle.
What still needs network when bundled
- Broadcasts — devices poll our server every 60s. No network = no new broadcasts. Existing ones already on the device continue to display until they expire.
- Remote config (Enterprise) — devices poll for config updates. No network = stays on the bundled config.
- License verification on boot — the license is in the bundle and is locally verified (Ed25519 signature against an embedded public key). No network needed.
If a device is offline indefinitely, it keeps running the bundled config indefinitely. Nothing breaks, nothing expires, no nag screens.
Bundle versioning
The bundle filename includes a content hash, so you can tell at a glance whether two devices are on the same bundle:
mobilauncher-bundle-acme-tools-2026-05-16-a3f7b21.zip
Internally, the renderer also records its assetBundleHash in the
config — diagnostic overlay shows it on-device. If you're debugging
a fleet, that's the first thing to check.
Bundle freshness
When you re-download from the Portal, you always get the current template + current config + current license. If you set up File Sync to grab from a CI artifact instead of a manual download, you can automate "re-bundle weekly so the renderer template stays fresh." Talk to us if you want help wiring that.