# SSR and Caching

Server-side rendering via goja (Go JS runtime) with HTML caching.

## Request flow

1. `get_read.js` receives the request and calls `lib/ssr-server.js`.
2. `get_read.js` loads `lib/app.server.js` and calls `app.default.render({ url })`.
3. `frontend/src/ssr.ts` stays thin and only initializes locale state before rendering `App.svelte`.
4. `frontend/src/App.svelte` is responsible for actual page data loading for both browser and SSR.
5. During SSR, `App.svelte` calls the same `loadContent(...)` path directly inside `typeof window === "undefined"`.
6. Rendered HTML is stored in the `ssr` collection together with dependency tracking strings.

## Build

- SSR bundle is built via `yarn build:server` and outputs to `lib/app.server.js`.
- The project no longer uses Babel for SSR.
- goja-compatible transforms are configured in `esbuild.config.server.js` via `supported`.
- The server build must remove frontend-only splitting/outdir options inherited from the shared esbuild config.

## Cache invalidation

- `clear_cache.js` hook invalidates SSR cache entries based on collection dependencies.
- Dependencies are stored as strings like `content:<id>` or `content:*`.
- `DELETE` invalidation must be robust even when `context.data.id` is missing.

## Route validation

- SSR route validation is active in `config.js`.
- Public page URLs are language-prefixed (`/de/...`, `/en/...`), while `content.path` in the DB is stored without that prefix.
- `ssrValidatePath()` must strip the language prefix before querying content and return a canonical language-prefixed URL when needed.
