Feature 18: Mobile Wrapping & Deployment
Overview
Wrap the SvelteKit SPA in Capacitor for iOS and Android distribution. Configure push notifications, deep links, app lifecycle handling, safe area layout, and the build/release pipeline for app stores.
Dependencies
- Feature 13 (Notifications) — push notification integration
- All client UI features complete (or sufficiently built)
Technical Tasks
1. Capacitor Setup
- Install Capacitor in the client project:
npm install @capacitor/core @capacitor/clinpx cap init delve com.delve.gamenpx cap add iosnpx cap add android
- Configure
capacitor.config.ts:server.urlpointing to production APIpluginsconfiguration for each native plugin
2. Native Plugin Integration
- Install and configure plugins:
@capacitor/push-notifications— FCM (Android) + APNs (iOS)@capacitor/haptics— tactile feedback for loot drops, crits, level ups@capacitor/app— foreground/background detection@capacitor/status-bar— immersive UI (dark status bar, game theme)@capacitor/splash-screen— branded loading screen@capacitor/browser— external links (Stripe checkout, Discord, support)@capacitor/preferences— local key-value storage (cached auth token, settings)
3. Push Notification Flow
- Create
lib/push.ts:- On app start: request push permission
- On token received:
POST /api/push/register { platform, token } - On token refresh: re-register
- On notification received (foreground): show in-app toast
- On notification tapped (background): deep link to relevant screen
- Configure FCM:
- Create Firebase project, add Android app
- Download
google-services.json→android/app/
- Configure APNs:
- Enable Push Notifications capability in Xcode
- Create APNs key in Apple Developer portal
- Upload key to Firebase for FCM→APNs bridging
4. App Lifecycle Handling
- Create
lib/lifecycle.ts:- On
appStateChangeto background:- Pause TanStack Query polling (no network requests while backgrounded)
- Save current state to Preferences (cached auth, last viewed screen)
- On
appStateChangeto foreground:- Resume polling
- Invalidate stale queries (refetch character state, notifications)
- Check for session validity
- On app resume after long background:
- Full state refresh
- On
5. Deep Linking
- Configure URL scheme:
delve:// - Routes:
delve://character/{id}→ character sheetdelve://run/{id}→ run resultdelve://guild/{id}→ guild pagedelve://marketplace→ marketplacedelve://pvp→ PVP arena
- Configure iOS Universal Links and Android App Links for web→app handoff
- Push notification payloads include deep link URLs
6. Responsive & Mobile Polish
- Audit all screens for mobile breakpoint (< 640px):
- Bottom tab navigation instead of sidebar
- Stacked panels instead of side-by-side
- Touch-friendly tap targets (minimum 44px)
- Drag-and-drop (skill queue, inventory) works with touch via pointer events
- Item tooltips trigger on tap-and-hold, dismiss on tap elsewhere
- Safe area handling:
env(safe-area-inset-top)for status barenv(safe-area-inset-bottom)for home indicator / gesture bar
- Keyboard handling:
- Search inputs in marketplace, friend name, mail compose
- Viewport resize on keyboard open (prevent content hidden behind keyboard)
7. App Store Assets
- Generate app icons and splash screens via
@capacitor/assets:- Source: single 1024x1024 icon SVG/PNG
- Outputs: all required iOS and Android icon sizes
- Splash screen: centered logo on brand color background
- Prepare store metadata:
- App name: “Delve”
- Short description (30 chars)
- Full description (4000 chars)
- Keywords
- Screenshots (6.7“ iPhone, 12.9“ iPad, phone + tablet Android)
- Privacy policy URL
- Support URL
8. Build Pipeline
- iOS:
pnpm build→npx cap sync ios- Build via Xcode Cloud or self-hosted Mac runner
- Signing: automatic with App Store Connect API key
- Distribute: TestFlight (beta), App Store (production)
- Android:
pnpm build→npx cap sync android- Build via Gradle:
./gradlew bundleRelease→.aab - Signing: upload key in Play Console
- Distribute: internal testing (beta), production track
- CI integration:
- Add mobile build steps to the
v*tag pipeline - Cache Gradle and CocoaPods dependencies
- Add mobile build steps to the
9. App Store Compliance
- Payment handling:
- All purchases via Stripe web checkout (opens in external browser)
- No in-app purchase SDK
- App description clearly states “subscription managed via web”
- Monitor Apple/Google policy changes on external payment links
- Privacy:
- App Privacy Details (Apple): email address collected for account
- Data Safety (Google Play): email collected, no tracking
- Age rating: fantasy violence (text-based, no graphic content), in-app purchases
Tests
Manual Tests (mobile builds require manual QA)
- App launches on iOS simulator and Android emulator
- Push notification permission prompt appears on first launch
- Push notification received when run completes (app backgrounded)
- Tapping push notification opens correct screen
- App resumes from background and refreshes data
- All screens render correctly at mobile breakpoint
- Safe areas respected on notch/dynamic island devices
- Drag-and-drop works with touch (skill queue, inventory)
- Stripe checkout opens in external browser and returns to app
- Deep links open correct screens
- App works offline (shows cached data, queues actions)
Automated Tests
- Capacitor build succeeds for iOS (
npx cap sync ios→ Xcode build) - Capacitor build succeeds for Android (
npx cap sync android→ Gradle build) - All client unit tests pass in the Capacitor web view context
- Deep link routing resolves to correct pages