--- name: tibi-ssr-caching description: Implement and debug server-side rendering with goja (Go JS runtime) and dependency-based HTML cache invalidation for tibi-server. Use when working on SSR hooks, cache clearing, or the server-side Svelte rendering pipeline. --- # tibi-ssr-caching ## SSR request flow 1. `ssr/get_read.js` receives a page request and calls `lib/ssr-server.js`. 2. `ssr-server.js` loads `lib/app.server.js` (the Svelte SSR bundle) and renders the page. 3. During rendering, API calls are tracked as **dependencies** (collection + entry ID). 4. The rendered HTML + dependencies are stored in the `ssr` collection. 5. On the client, `lib/ssr.js` hydrates using `window.__SSR_CACHE__` injected by the server. ## Building the SSR bundle ```bash yarn build:server ``` - Output: `api/hooks/lib/app.server.js` - Uses `babel.config.server.json` to transform async/await to generators (goja doesn't support async). - Add `--banner:js='// @ts-nocheck'` to suppress type errors in the generated bundle. ## Dependency-based cache invalidation When content changes, `clear_cache.js` only invalidates SSR entries that depend on the changed collection/entry: ```js // Each SSR cache entry stores its dependencies: { url: "/some-page", html: "...", dependencies: [ { collection: "content", id: "abc123" }, { collection: "medialib", id: "def456" } ] } ``` The hook queries the `ssr` collection for entries whose `dependencies` array matches the changed collection (and optionally entry ID), then deletes only those cached pages. ## SSR route validation Route validation in `config.js` controls which paths get SSR treatment. Return: - A positive number to enable SSR for that route - `-1` to disable SSR (current default in the starter template) ## Common pitfalls - **goja has no async/await**: The babel server config transforms these, but avoid top-level await. - **No browser globals**: `window`, `document`, `localStorage` etc. don't exist in goja. Guard with `typeof window !== "undefined"`. - **SSR cache can go stale**: Always ensure `clear_cache.js` covers any new collection that affects rendered output.