Warm the server cache from client-side navigations, PUBLIC_SSR_WARM opts out
This commit is contained in:
parent
7883e6df8a
commit
5329c611b1
4 changed files with 15 additions and 2 deletions
|
|
@ -4,6 +4,8 @@ PUBLIC_GROUP_ID=mygrouprandomid # required in simple mode; the single for
|
|||
PUBLIC_TITLE= # top-bar title; empty falls back to the group name
|
||||
# Render on the server (Node deploy) instead of shipping a static SPA
|
||||
PUBLIC_SSR=no
|
||||
# With SSR on, warm the server cache from client-side navigations (yes/no)
|
||||
PUBLIC_SSR_WARM=yes
|
||||
|
||||
PUBLIC_SEARCH=no # yes | no — enable the search box (requires a relay with NIP-50 support)
|
||||
PUBLIC_LABELS= # comma-separated discussion labels (e.g., bug,feature,question)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ Squalk is configured entirely through environment variables (all prefixed `PUBLI
|
|||
| `PUBLIC_TITLE` | no | group name | Title shown in the top bar. When empty it falls back to the group's name. |
|
||||
| `PUBLIC_JOINCODE` | no | `no` | `yes` to show an invite-code field when a join request is rejected (for code-gated relays). |
|
||||
| `PUBLIC_SSR` | no | `no` | `yes` to render pages on the server (crawlable HTML, real 404s). The build then targets Node (`node build`) instead of a static bundle; see [Deploying](#deploying). |
|
||||
| `PUBLIC_SSR_WARM` | no | `yes` | With `PUBLIC_SSR=yes`, each client-side navigation also asks the server to fetch and cache that page, so a later refresh, shared link or crawler hit is served warm. Costs one extra relay query per navigation on the server; set to `no` to disable. |
|
||||
| `PUBLIC_SEARCH` | no | `no` | `yes` to show a search box at the top of the homepage. Requires a relay with NIP-50 search support. |
|
||||
| `PUBLIC_LABELS` | no | — | Comma-separated discussion labels offered when composing, e.g. `bug,feature,question`. |
|
||||
| `PUBLIC_BLOSSOM_URL` | no | — | Blossom server URL used for media uploads, e.g. `https://blossom.primal.net`. Uploads are disabled when unset. |
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@ if (MODE === "simple" && !GROUP_ID) {
|
|||
// Server-side rendering: opt-in, decided at build time (vite.config.ts bakes
|
||||
// PUBLIC_SSR in; svelte.config.js picks the matching adapter).
|
||||
export const SSR_ENABLED = __SQUALK_SSR__;
|
||||
// With SSR on, a client-side navigation also asks the server for the same
|
||||
// snapshot (without waiting for it) so the page is already cached for the
|
||||
// next refresh, shared link or crawler. Costs one server→relay query per
|
||||
// navigation; opt out with PUBLIC_SSR_WARM=no.
|
||||
export const SSR_WARM = SSR_ENABLED && env.PUBLIC_SSR_WARM !== "no";
|
||||
// Server-rendered pages and snapshots are anonymous, so a shared cache may
|
||||
// hold them: fresh for 5 minutes, served stale for an hour while revalidating.
|
||||
// Browsers always revalidate (max-age=0) so a login shows its content at once.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { browser } from "$app/environment";
|
||||
import { error } from "@sveltejs/kit";
|
||||
import { SSR_WARM } from "$lib/config";
|
||||
import type { NostrUser } from "$lib/gadgets";
|
||||
import type { GroupMetadata, GroupSummary } from "./groups";
|
||||
import type { Resource } from "./resources";
|
||||
|
|
@ -37,14 +38,18 @@ type Fetch = typeof fetch;
|
|||
// Read a snapshot endpoint. On the server the response is inlined into the
|
||||
// HTML; in the browser it is consumed only while hydrating that HTML. Client
|
||||
// navigations get null, leaving the stores to fetch live (and authenticated)
|
||||
// data as they always did — the same path a client-only build takes.
|
||||
// data as they always did — the same path a client-only build takes — but
|
||||
// may still poke the endpoint so the server has the page cached.
|
||||
// A 404 from the endpoint becomes a real 404 page on the server, so crawlers
|
||||
// never index an empty shell; the client keeps its own not-found handling.
|
||||
export async function snapshot<T>(
|
||||
fetch: Fetch,
|
||||
url: string,
|
||||
): Promise<T | null> {
|
||||
if (browser && !hasInlinedResponse(url)) return null;
|
||||
if (browser && !hasInlinedResponse(url)) {
|
||||
if (SSR_WARM) fetch(url).catch(() => {});
|
||||
return null;
|
||||
}
|
||||
let res: Response;
|
||||
try {
|
||||
res = await fetch(url);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue