diff --git a/backend/internal/backend/handlers.go b/backend/internal/backend/handlers.go index 150fca1..d3bda3c 100644 --- a/backend/internal/backend/handlers.go +++ b/backend/internal/backend/handlers.go @@ -1279,6 +1279,10 @@ func (s *Server) handleTranslationRead(w http.ResponseWriter, r *http.Request) { return } + // Translated chapter content is immutable once generated — cache aggressively. + // The browser and any intermediary (CDN, SvelteKit fetch cache) can reuse this + // response for 1 hour without hitting MinIO again. + w.Header().Set("Cache-Control", "public, max-age=3600, stale-while-revalidate=86400") writeJSON(w, 0, map[string]string{"html": buf.String(), "lang": lang}) } diff --git a/ui/src/routes/api/translation/[slug]/[n]/+server.ts b/ui/src/routes/api/translation/[slug]/[n]/+server.ts index 4fb6d09..5492a39 100644 --- a/ui/src/routes/api/translation/[slug]/[n]/+server.ts +++ b/ui/src/routes/api/translation/[slug]/[n]/+server.ts @@ -23,9 +23,12 @@ export const GET: RequestHandler = async ({ params, url }) => { return new Response(null, { status: res.status }); } const data = await res.json(); - return new Response(JSON.stringify(data), { - headers: { 'Content-Type': 'application/json' } - }); + const headers: Record = { 'Content-Type': 'application/json' }; + // Forward the immutable cache header from the backend so browsers and CDNs + // can cache translated chapter content without hitting MinIO on every load. + const cc = res.headers.get('Cache-Control'); + if (cc) headers['Cache-Control'] = cc; + return new Response(JSON.stringify(data), { headers }); }; export const POST: RequestHandler = async ({ params, url, locals }) => {