Tenant Web Runtime
Why the tenant product is a React SPA with client-side routing and API-backed state, and where server rendering still belongs.
Tenant Web Runtime
Register your App entry and routes in the existing Shell, and load screen data through authenticated APIs. Do not create another React root or router. Follow Build an App screen; a registered nested route must render both through navigation and a direct URL, with the API enforcing the same permissions.
One React application
The Nexia tenant product is a React single-page application. Laravel serves one
HTML shell, React mounts once, and BrowserRouter changes product routes in the
browser. Data does not arrive as page props for each navigation. Screens read
and mutate tenant data through authenticated APIs, with React Query managing
request state and caching.
That is what SPA and CSR mean here. SPA describes the long-lived browser application; client-side rendering (CSR) describes React producing the screen after the shell loads. It does not mean that every Nexia web surface uses the same runtime. Central service pages and administrative surfaces may use other delivery patterns. The choice applies specifically to the tenant product Shell and App surfaces composed inside it.
Request lifecycle
The web runtime spans a server bootstrap and a client runtime:
| Stage | Owner | Result |
|---|---|---|
| Tenant domain request | Laravel tenant middleware | Tenant context and scoped session are established |
| Shell response | routes/tenant.php | shell-os HTML is returned for a product route |
| Client mount | resources/js/app.tsx | React, routing, localization, and query state start once |
| Shell bootstrap | Core Shell runtime | Installed Apps and allowed contributions are resolved |
| Screen data | Tenant API | Current, authorized data is returned |
| Navigation | BrowserRouter | The screen changes without replacing the document |
The server catch-all is intentional. In routes/tenant.php, named backend
routes and administrative paths are registered first. The final GET route
returns the Shell view for the remaining product paths.
The authenticated Shell response embeds ShellBootstrapBuilder output and sends Cache-Control: no-store, private. Guests redirect to /login. The catch-all excludes the admin path, .well-known, and static asset extensions; a missing asset is not a product route.
Directly opening a nested product URL therefore still obtains the SPA shell.
After mount, BrowserRouter resolves the actual client screen.
Where an App joins
An App does not create a second React root or a second router. It exports the frontend entry and contributions defined by the App SDK. Core discovers the installed App, loads its entry, and composes its routes into the existing Shell. Shared host services such as navigation, permission-aware actions, query state, and localization stay host-owned.
API and persistence rules
CSR is not permission enforcement. Anything in browser memory, a hidden button, or a route guard can be inspected or bypassed. Protected operations are checked again in Laravel.
SPA also does not mean browser storage is the database. React Query and local stores improve interaction and restoration, but durable product state remains in tenant persistence. Reloading a screen may rebuild client state from the API; it must not be the only place a business decision was recorded.
Finally, the tenant SPA does not turn every repository frontend into an App surface. Central service operations, the developer portal, and Filament admin areas have different owners. Their presence does not change the tenant runtime decision.
Check a nested route
Open a registered App route directly, then reach the same route through navigation. Both paths should mount the App screen inside the host and use its tenant API. An unknown App route is not made valid by receiving the Shell document, and a visible screen does not bypass backend read authority.
Related
- Nexia System Overview — separates host, SDK, and App ownership before frontend work.
- Shell layout regions — names the regions the single Shell composes.
- Build an App screen — applies this runtime through the supported frontend SDK.
- Tenant and context — follows the server context that must exist before the SPA calls an API.