diff --git a/src/app.d.ts b/src/app.d.ts index be7d5b8..53a4264 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -9,6 +9,9 @@ import type { import type { ThreadDetail } from "$lib/forum/thread"; declare global { + // Injected by vite.config.ts from PUBLIC_SSR + const __SQUALK_SSR__: boolean; + namespace App { // interface Error {} // interface Locals {} diff --git a/src/lib/config.ts b/src/lib/config.ts index 95f70f6..e736634 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -18,9 +18,9 @@ export const GROUP_ID = env.PUBLIC_GROUP_ID ?? ""; if (MODE === "simple" && !GROUP_ID) { throw new Error("PUBLIC_GROUP_ID is required in simple mode"); } -// Server-side rendering: opt-in, and only meaningful when the build targets the -// Node adapter (svelte.config.js reads the same variable). -export const SSR_ENABLED = env.PUBLIC_SSR === "yes"; +// 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__; // 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. diff --git a/svelte.config.js b/svelte.config.js index f3b9c64..75459b0 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -3,8 +3,8 @@ import adapterNode from "@sveltejs/adapter-node"; import adapterStatic from "@sveltejs/adapter-static"; // PUBLIC_SSR picks the deployment target: a Node server that renders pages -// (yes) or a static single-page bundle (no, the default). The same flag turns -// SSR on in +layout.ts. +// (yes) or a static single-page bundle (no, the default). vite.config.ts bakes +// the same flag into the app as SSR_ENABLED. const env = loadEnv( process.env.NODE_ENV ?? "production", process.cwd(), diff --git a/vite.config.ts b/vite.config.ts index 23797da..a02ee62 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,15 @@ import tailwindcss from "@tailwindcss/vite"; import { sveltekit } from "@sveltejs/kit/vite"; -import { defineConfig } from "vite"; +import { defineConfig, loadEnv } from "vite"; -export default defineConfig({ plugins: [tailwindcss(), sveltekit()] }); +// PUBLIC_SSR is a build-time decision (it also picks the adapter in +// svelte.config.js), so it is compiled in as a constant rather than read from +// the environment when the server starts. +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd(), "PUBLIC_"); + const ssr = (process.env.PUBLIC_SSR ?? env.PUBLIC_SSR) === "yes"; + return { + plugins: [tailwindcss(), sveltekit()], + define: { __SQUALK_SSR__: JSON.stringify(ssr) }, + }; +});