Custom 404 page shows as text instead of HTML

Hello. I have a static HTML site that I host with Cloudflare Workers. I’m now trying to migrate it from Wrangler 1 to Wrangler 2.

I just copied the contents of the old index.js file that Wrangler 1 used to the new index.ts file (see code below). The website is working fine, with the only problem being that when I enter a non-existing URL, the browser shows the contents of 404.html as raw text instead of parsing it as an HTML page. It worked fine with Wrangler 1, but now it doesn’t. Can you help me out?

import { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler'

addEventListener('fetch', event => {
    event.respondWith(handleEvent(event))
})

async function handleEvent(event) {
    try {
        return await getAssetFromKV(event)
    } catch (e) {
        try {
            let notFoundResponse = await getAssetFromKV(event, {
                mapRequestToAsset: req => new Request(`${new URL(req.url).origin}/404.html`, req)
            })

            return new Response(notFoundResponse.body, { ...notFoundResponse, status: 404, statusText: "Not Found" })
        } catch (e) {
            return new Response('Error 404: Page not found', { status: 404, statusText: "Not Found" })
        }
    }
}

You can check it, but it sounds like the response is being sent with no Content-Type, or as text/plain.

Try adding a content-type header here.

return new Response(notFoundResponse.body, { ...notFoundResponse, status: 404, statusText: "Not Found", headers: { 'content-type': 'text/html' } })
3 Likes

Thank you! Your solution worked like a charm. That’s correct, the response has no content-type. I guess they changed Response() in Wrangler 2 to return no content-type by default.

2 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.