Make routing work from a file-served Capacitor bundle (#24) (#27)
Unit Tests / test (push) Successful in 10s

## Summary
- Closes #24
- Introduce `AppRouter` + `getAppRouter()` so Capacitor uses `HashRouter` (filesystem bundle, no nginx rewrite) while web keeps `BrowserRouter`
- Isolate platform checks in `nativePlatform` (no `Capacitor.isNativePlatform()` sprinkled through the route tree)
- Auth forced redirects (`axiosApi` → `/signin/`) use hash-safe `redirectToAppPath` on native
- Leave CRA `homepage` / absolute `PUBLIC_URL` asset paths unchanged so `/var/www/{env}.chat.aimloperations/html` deploy stays intact; HashRouter keeps document URL at the bundle root so assets resolve

## Test plan
- [x] Unit tests: `AppRouter` + `nativePlatform` (`npm run test:ci`)
- [ ] Capacitor build: open nested route (`/#/account/`), force WebView reload — no blank/404
- [ ] Browser back/forward + Android hardware back with HashRouter
- [ ] Web deploy smoke: deep link reload at `/account/` still works via nginx rewrite
- [ ] Confirm login redirects after 401 still land on sign-in (web path + native hash)Reviewed-on: #27
This commit was merged in pull request #27.
This commit is contained in:
2026-07-26 13:46:41 -07:00
parent 7f16a3dca8
commit 0fc8739d26
7 changed files with 264 additions and 7 deletions
+18
View File
@@ -1 +1,19 @@
/// <reference types="react-scripts" />
interface CapacitorBridge {
isNativePlatform?: () => boolean;
isNative?: boolean;
Plugins?: {
App?: { addListener?: (...args: unknown[]) => unknown };
Network?: { addListener?: (...args: unknown[]) => unknown };
Preferences?: {
get?: (options: { key: string }) => Promise<{ value?: string | null }>;
set?: (options: { key: string; value: string }) => Promise<void>;
remove?: (options: { key: string }) => Promise<void>;
};
};
}
interface Window {
Capacitor?: CapacitorBridge;
}