Platform Mobile App (Capacitor)
iOS and Android app that wraps the Platform web frontend using Capacitor. The same Svelte app built by dev/prod is copied into www/ and loaded by the native shell.
Prerequisites
- Node.js and Rush (see root README)
- iOS: macOS with Xcode
- Android: Android Studio
Quick start
From the repo root:
- Build the web app:
rush build --to @hcengineering/prod cd mobilenpm run sync(copies web assets towww/and runscap sync)npm run open:iosornpm run open:androidto open the native IDE
Scripts
| Script | Description |
|---|---|
npm run build:web |
Copy dev/prod/dist and dev/prod/public into mobile/www. Run after building the web app. |
npm run sync |
Run build:web then cap sync (updates native projects with www content). |
npm run open:ios |
Open the iOS project in Xcode. |
npm run open:android |
Open the Android project in Android Studio. |
npm run run:ios |
Run on iOS simulator/device. |
npm run run:android |
Run on Android emulator/device. |
Configuration
- capacitor.config.ts:
appIdisio.huly.platform;appNameisHuly. Change these if you need a different bundle ID or display name. - Local-first load: The app loads from the bundled
www/directory (noserver.url), so it opens without requiring a connection to any server. The login page and shell are served from local resources. - Backend URL: The web app reads
/config.jsonfrom the bundle. The copy script usesdev/prod/public/config-mobile.jsonaswww/config.jsonwhen present (full backend URLs); otherwise it copiesconfig.json. For production, use a config that points to your production backend. On Android emulator, replacelocalhostwith10.0.2.2inconfig-mobile.jsonif the app cannot reach the backend. - Server unavailable: When the user tries to use backend features (e.g. login) and the server is unreachable, the app shows a “Server unavailable” message in the login (or relevant) UI. To use the webpack dev server for live reload, temporarily add
server: { url: 'http://localhost:8080', cleartext: true }tocapacitor.config.tsand runnpx cap sync.
Native Shell Architecture
The mobile app implements a native shell that handles error states when the server is unavailable:
Error Handling
- Android:
MainActivity.javaincludes a customWebViewClientthat intercepts WebView load errors (connection refused, timeout, no network) and displays a native error screen with a Retry button. - iOS:
CustomBridgeViewController.swiftimplementsWKNavigationDelegateto intercept navigation errors and show a native error overlay.
Network Monitoring
Both platforms monitor network connectivity:
- When network is lost, the native shell shows an error screen
- When network is restored, the error message updates to indicate retry is available
- The
@capacitor/networkplugin provides JavaScript-level network status if needed
Splash Screen
The @capacitor/splash-screen plugin is configured with manual control (launchAutoHide: false). The native shell keeps the splash screen visible until the WebView successfully loads, providing a smooth transition.
Error Screen
When the server is unavailable:
- Native error screen appears with app branding
- User sees "Connection Error" message with description
- "Retry" button reloads the WebView
- On success, error screen hides and web app is displayed
Icons and splash
App and splash icons use the Huly branding from dev/prod/public/huly/ (same source as the web app: icon-1024.png, etc.). To refresh mobile icons after updating Huly assets, copy dev/prod/public/huly/icon-1024.png to:
- Android:
android/app/src/main/res/mipmap-*/ic_launcher.png,ic_launcher_foreground.png,ic_launcher_round.png, anddrawable*/splash.png. - iOS:
ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.pngandSplash.imageset/splash-2732x2732*.png.
Web assets
The www/ directory is generated by npm run build:web and is ignored by git. Always run npm run sync after building the web app or changing public assets so the native projects have the latest content.
Adding platforms (first-time setup)
If the ios/ or android/ folders are missing (e.g. after a fresh clone), run once from mobile/:
npm run add:ios
npm run add:android
Then run npm run sync before opening the native projects.