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
+3 -3
View File
@@ -2,7 +2,7 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import AppRouter from './llm-fe/platform/AppRouter';
import { AuthProvider } from './llm-fe/contexts/AuthContext';
import { AccountProvider } from './llm-fe/contexts/AccountContext';
import { WebSocketProvider } from './llm-fe/contexts/WebSocketContext';
@@ -16,7 +16,7 @@ const root = ReactDOM.createRoot(
);
root.render(
<React.StrictMode>
<BrowserRouter>
<AppRouter>
<script async defer src="https://tianji.aimloperations.com/tracker.js" data-website-id="cm7x7m52m03kbddswbswrt17y"></script>
<AuthProvider>
<AccountProvider>
@@ -33,6 +33,6 @@ root.render(
</WebSocketProvider>
</AccountProvider>
</AuthProvider>
</BrowserRouter>
</AppRouter>
</React.StrictMode>
);