Skip to content

Instantly share code, notes, and snippets.

@Nooshu
Created February 20, 2026 13:01
Show Gist options
  • Select an option

  • Save Nooshu/5176f0d3446e05629501130912f09570 to your computer and use it in GitHub Desktop.

Select an option

Save Nooshu/5176f0d3446e05629501130912f09570 to your computer and use it in GitHub Desktop.
The Cloudflare function that does the content negotiation for the HTML that has been compressed to Brotli 11.
/**
* Catch-all Pages Function for HTML document content negotiation.
* Serves pre-compressed Brotli 11 .br files when client sends Accept-Encoding: br,
* otherwise passes through to static assets (uncompressed HTML).
* Only runs for GET and HEAD; POST /api/contact is handled by functions/api/contact.js.
*/
async function handleHtmlWithBrotli(request, env) {
const url = new URL(request.url);
const pathname = url.pathname;
// Only handle HTML document requests: /, paths ending with /, or /404.html
const isHtmlDocument = pathname === '/' || pathname.endsWith('/') || pathname === '/404.html';
if (!isHtmlDocument) {
return env.ASSETS.fetch(request);
}
const acceptsBrotli = request.headers.get('Accept-Encoding')?.includes('br') ?? false;
if (!acceptsBrotli) {
return env.ASSETS.fetch(request);
}
// Construct path to .br file: / -> /index.html.br, /blog/post/ -> /blog/post/index.html.br
const brPath =
pathname === '/' ? '/index.html.br' : pathname === '/404.html' ? '/404.html.br' : `${pathname}index.html.br`;
const brUrl = new URL(brPath, url.origin);
const brResponse = await env.ASSETS.fetch(brUrl.toString());
if (!brResponse.ok) {
return env.ASSETS.fetch(request);
}
const headers = new Headers(brResponse.headers);
headers.set('Content-Encoding', 'br');
headers.set('Content-Type', 'text/html; charset=UTF-8');
headers.set('Vary', 'Accept-Encoding');
// Prevent Cloudflare from re-compressing or modifying the response
headers.set('Cache-Control', 'public, max-age=31536000, no-transform');
return new Response(brResponse.body, {
status: brResponse.status,
headers,
// Prevents Workers from re-compressing; required for pre-compressed Brotli
encodeBody: 'manual',
});
}
export const onRequestGet = async ({ request, env }) => {
return handleHtmlWithBrotli(request, env);
};
export const onRequestHead = async ({ request, env }) => {
return handleHtmlWithBrotli(request, env);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment