If you’re starting from scratch, Cloudflare Pages might be the better solution to do this since they also can run functions now.

If you need more logic in your Workers or have an existing one and want to include some HTML as well, read on.

I’ve got a Worker and want to serve an HTML form when a GET request is made and want to do some other logic when the form is submitted as a POST request.

Import HTML files

I don’t want to have my HTML code inline with all the other Worker stuff, so I put it in a separate file in my src directory. Let's call this file … you guessed it: index.html I'm not going to show an HTML file here, it's really just anything you want in there. I have a form.

Now, back in your Worker JavaScript file, you can import this HTML file like so:

import html from './index.html'

It’ll be available as the variable name html in your JavaScript. An example Worker could look like this:

import html from './index.html'

async function handleRequest(request, env) {
if(request.method === 'POST') {
return doPostRequestThings()
}

const output = html
const headers = { 'Content-Type': 'text/html' }
return new Response(output, { headers })
}

If a POST request is made, it’ll call the doPostRequestThings() function, otherwise it'll just print out the HTML file with the text/html content-type to render it properly in the browser.

esbuild HTML loader

Now, when using esbuild to mangle everything together, you need to tell esbuild how an HTML file should be treated. What we want to do is, treat HTML files as text. To make this happen, open your package.json file, go to the scripts section and add this:

"build": "esbuild src/index.mjs --format=esm --bundle --minify --loader:.html=text --outfile=dist/index.mjs",

--loader:.html=text will tell esbuild to take HTML files as text.