import type { Handle } from '@sveltejs/kit'; import { getTextDirection, isLocale } from '$lib/paraglide/runtime'; import { paraglideMiddleware } from '$lib/paraglide/server'; const DATA_CACHE_CONTROL = 'private, max-age=300'; const MIN_GZIP_SIZE_BYTES = 1024; function isBucketDataRequest(request: Request) { const segments = new URL(request.url).pathname.split('/').filter(Boolean); if (segments.at(-1) !== '__data.json') return false; segments.pop(); if (segments[0] && isLocale(segments[0])) segments.shift(); const route = segments.join('/'); return route === '' || route === 'details' || route === 'tools'; } function acceptsGzip(request: Request) { return (request.headers.get('accept-encoding') ?? '').split(',').some((entry) => { const [encoding, ...parameters] = entry.trim().toLowerCase().split(';'); if (encoding !== 'gzip' && encoding !== '*') return false; const quality = parameters .map((parameter) => parameter.trim()) .find((parameter) => parameter.startsWith('q=')); return quality ? Number(quality.slice(2)) > 0 : true; }); } function appendVary(headers: Headers, value: string) { const values = new Set( (headers.get('vary') ?? '') .split(',') .map((item) => item.trim()) .filter(Boolean) ); values.add(value); headers.set('vary', [...values].join(', ')); } function optimizeBucketDataResponse(request: Request, response: Response) { if (!response.ok || !response.body || !isBucketDataRequest(request)) return response; const headers = new Headers(response.headers); headers.set('cache-control', DATA_CACHE_CONTROL); appendVary(headers, 'Accept-Encoding'); const contentLength = Number(headers.get('content-length') ?? 0); if (request.method === 'HEAD' || contentLength < MIN_GZIP_SIZE_BYTES || !acceptsGzip(request)) { return new Response(response.body, { status: response.status, statusText: response.statusText, headers }); } headers.delete('content-length'); headers.set('content-encoding', 'gzip'); return new Response(response.body.pipeThrough(new CompressionStream('gzip')), { status: response.status, statusText: response.statusText, headers }); } const handleParaglide: Handle = ({ event, resolve }) => paraglideMiddleware(event.request, async ({ request, locale }) => { event.request = request; const response = await resolve(event, { transformPageChunk: ({ html }) => html .replace('%paraglide.lang%', locale) .replace('%paraglide.dir%', getTextDirection(locale)) }); return optimizeBucketDataResponse(request, response); }); export const handle: Handle = handleParaglide;