docs(project): record SPA-mode decision and SvelteKit feature usage
Document that the frontend deliberately runs as a pure client-side SPA (adapter-static, ssr=false) and that we stay on SvelteKit rather than migrating to a bare Svelte + router setup: the file-based routing, client router, and — most importantly — shallow routing (pushState + page.state, on which the overlay file viewer depends) carry their weight, while the server half (SSR, endpoints, form actions, hooks) is intentionally unused. Also drop the stale hooks.* entries from the directory layout, since no such files exist. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,46 @@
|
|||||||
- **Font**: Epilogue (variable weight)
|
- **Font**: Epilogue (variable weight)
|
||||||
- **Package manager**: npm
|
- **Package manager**: npm
|
||||||
|
|
||||||
|
## SPA mode — why SvelteKit without the server
|
||||||
|
|
||||||
|
This frontend runs as a **pure client-side SPA**: `adapter-static` with
|
||||||
|
`fallback: 'index.html'` and `ssr = false` globally (see
|
||||||
|
`src/routes/+layout.ts`). There is no Node server in production — the build is
|
||||||
|
static assets, and the only backend is the Go API. SvelteKit is used here
|
||||||
|
purely as an SPA framework: file-based routing, the client router, and build
|
||||||
|
tooling.
|
||||||
|
|
||||||
|
**SvelteKit features we *do* use:**
|
||||||
|
|
||||||
|
- File-based routing with nested layouts (`admin/` has its own guard) and
|
||||||
|
dynamic segments (`[id]`).
|
||||||
|
- The client router: `goto`, the `page` store/state, `afterNavigate`,
|
||||||
|
`navigating`.
|
||||||
|
- **Shallow routing** — `pushState`/`replaceState` + `page.state`. The
|
||||||
|
Immich-style file viewer in `files/` and `pools/[id]/` opens as an overlay
|
||||||
|
over the still-mounted list via shallow routing, so the browser back button
|
||||||
|
dismisses it without reloading the grid. This is the single biggest reason we
|
||||||
|
stay on SvelteKit rather than a plain router.
|
||||||
|
- `load` functions, used *only* as client-side route guards (auth redirect,
|
||||||
|
admin redirect, `/` → `/files`).
|
||||||
|
- `$lib` alias, generated `./$types`, Vite/HMR integration.
|
||||||
|
|
||||||
|
**SvelteKit features we deliberately do *not* use** (the "server half"):
|
||||||
|
|
||||||
|
- SSR / hydration.
|
||||||
|
- `+page.server.ts`, `+server.ts` endpoints, form actions — all data goes
|
||||||
|
through the Go API via the `$lib/api` client.
|
||||||
|
- `hooks.*`, prerendering, server-only modules — no `hooks.server.ts` /
|
||||||
|
`hooks.client.ts` files exist.
|
||||||
|
|
||||||
|
**Decision: stay on SvelteKit, do not migrate to a bare Svelte + router SPA.**
|
||||||
|
The project already *is* an SPA, so there is no runtime gain from switching
|
||||||
|
(adapter-static tree-shakes the unused server bits; the client-runtime size
|
||||||
|
difference is negligible). A migration would mean re-implementing nested
|
||||||
|
layouts, guards, dynamic params, and — most painfully — shallow routing /
|
||||||
|
history-state overlays by hand, for zero benefit. New contributors should not
|
||||||
|
expect SSR, endpoints, or hooks to do anything here; that is intentional.
|
||||||
|
|
||||||
## Monorepo Layout
|
## Monorepo Layout
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -49,8 +89,7 @@ frontend/
|
|||||||
├── src/
|
├── src/
|
||||||
│ ├── app.html # Shell HTML (PWA meta, font preload)
|
│ ├── app.html # Shell HTML (PWA meta, font preload)
|
||||||
│ ├── app.css # Tailwind directives + CSS custom properties
|
│ ├── app.css # Tailwind directives + CSS custom properties
|
||||||
│ ├── hooks.server.ts # Server hooks (not used in SPA mode)
|
│ │ # (no hooks.* — see "SPA mode" above)
|
||||||
│ ├── hooks.client.ts # Client hooks (global error handling)
|
|
||||||
│ │
|
│ │
|
||||||
│ ├── lib/ # Shared code ($lib/ alias)
|
│ ├── lib/ # Shared code ($lib/ alias)
|
||||||
│ │ │
|
│ │ │
|
||||||
|
|||||||
Reference in New Issue
Block a user