77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
import path from 'node:path';
|
|
import type { Handle } from '@sveltejs/kit';
|
|
|
|
const MIME_TYPES: Record<string, string> = {
|
|
'.js': 'application/javascript; charset=utf-8',
|
|
'.mjs': 'application/javascript; charset=utf-8',
|
|
'.css': 'text/css; charset=utf-8',
|
|
'.json': 'application/json; charset=utf-8',
|
|
'.svg': 'image/svg+xml; charset=utf-8',
|
|
'.woff2': 'font/woff2',
|
|
'.woff': 'font/woff',
|
|
'.ttf': 'font/ttf',
|
|
'.otf': 'font/otf'
|
|
};
|
|
|
|
const HTML_CACHE_CONTROL = 'public, max-age=0, must-revalidate';
|
|
const IMMUTABLE_ASSET_CACHE_CONTROL = 'public, max-age=31536000, immutable';
|
|
const ASSET_404_CACHE_CONTROL = 'no-store';
|
|
const LONG_CACHE_EXTENSIONS = new Set([
|
|
'.js',
|
|
'.mjs',
|
|
'.css',
|
|
'.json',
|
|
'.svg',
|
|
'.png',
|
|
'.jpg',
|
|
'.jpeg',
|
|
'.webp',
|
|
'.avif',
|
|
'.ico',
|
|
'.woff2',
|
|
'.woff',
|
|
'.ttf',
|
|
'.otf'
|
|
]);
|
|
|
|
export const handle: Handle = async ({ event, resolve }) => {
|
|
const response = await resolve(event);
|
|
const pathname = event.url.pathname;
|
|
const contentType = response.headers.get('content-type') ?? '';
|
|
|
|
if (pathname.startsWith('/_app/')) {
|
|
const existing = response.headers.get('content-type');
|
|
const hasValidHeader = existing && existing.trim().length > 0;
|
|
if (!hasValidHeader) {
|
|
const extension = path.extname(pathname).toLowerCase();
|
|
const mime = extension && MIME_TYPES[extension];
|
|
if (mime) {
|
|
response.headers.set('content-type', mime);
|
|
}
|
|
}
|
|
|
|
// Missing hashed assets should never be cached; otherwise stale HTML can
|
|
// keep pointing to already-rotated files long after a deployment.
|
|
if (response.status >= 400) {
|
|
response.headers.set('cache-control', ASSET_404_CACHE_CONTROL);
|
|
} else if (pathname.startsWith('/_app/immutable/')) {
|
|
response.headers.set('cache-control', IMMUTABLE_ASSET_CACHE_CONTROL);
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
const extension = path.extname(pathname).toLowerCase();
|
|
if (LONG_CACHE_EXTENSIONS.has(extension) && !contentType.includes('text/html')) {
|
|
response.headers.set('cache-control', IMMUTABLE_ASSET_CACHE_CONTROL);
|
|
}
|
|
|
|
// HTML documents should revalidate so they can reference the latest client
|
|
// bundle hashes after each deployment.
|
|
if (contentType.includes('text/html')) {
|
|
response.headers.set('cache-control', HTML_CACHE_CONTROL);
|
|
}
|
|
|
|
return response;
|
|
};
|