2.1 KiB
2.1 KiB
name, description
| name | description |
|---|---|
| tibi-ssr-caching | 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
ssr/get_read.jsreceives a page request and callslib/ssr-server.js.ssr-server.jsloadslib/app.server.js(the Svelte SSR bundle) and renders the page.- During rendering, API calls are tracked as dependencies (collection + entry ID).
- The rendered HTML + dependencies are stored in the
ssrcollection. - On the client,
lib/ssr.jshydrates usingwindow.__SSR_CACHE__injected by the server.
Building the SSR bundle
yarn build:server
- Output:
api/hooks/lib/app.server.js - Uses
babel.config.server.jsonto 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:
// 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
-1to 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,localStorageetc. don't exist in goja. Guard withtypeof window !== "undefined". - SSR cache can go stale: Always ensure
clear_cache.jscovers any new collection that affects rendered output.