Workers Reverse Proxy Assets


I am trying to set cloudflare workers up as a reverse proxy. Aim is to have to load data from and to load data from and to load data from

There will be other routes for both of these, but this is enough for an example hopefully. Both of these are apps hosted on Vercel.
I have two basic workers that look like

addEventListener('fetch', event => {

async function handleRequest(request) {
  const url = new URL(request.url)
  const hostname = ''
  return fetch(`${hostname}${url.pathname}`)

They are loading the site (see but everything in _next/static/* and external images are not loading. They just error with 522 if you look in the console.

Everything I can find points me to the most basic “Conditional Routing” example, which doesn’t contain this logic. All of the examples are really basic and I can’t find any decent, fleshed out reverse proxy with workers code.
Ideally I want a reverse proxy with assets and caching if anybody has an example?

I have also just noticed if I access it via the url, it works totally fine.

Also my DNS setup for this subdomain is

I’m trying to solve the same problem, I think. We have a React app served under
We want any requests to to server a second React app served that is available under The code below works for the first click - it serves the newapp under the base domain. The problem is that the browser still knows it’s coming from and is adding that to the links - then we get issues trying to navigate to different domain. In essence, we are trying to mimic a NGINX reverse proxy. Any help would be greatly appreciated.

async function handleRequest(request) {
  const base = ''
  const url = new URL(request.url)
  const { pathname, search, hash } = url
  // Rebuild the url to request from
  const destinationURL = base + pathname + search + hash
  let response

  if (pathname.startsWith('/newapp') ) {
    const originalResponse = await fetch(destinationURL)

    response = new Response(originalResponse.body, {
      status: originalResponse.status,
      headers: originalResponse.headers,
  } else {
    response = await fetch(request)

  return response

addEventListener("fetch", event => {

It’s easier to use url.href if you want to reconstruct the original URL.
Notice that hashes are not passed to servers, only url parameters.

The problem here is probably that different contents have different content headers and types.

To be able to proxy all of it, you’ll need quite a lot of boilerplate to handle the situations.

For example, to proxy an image you cannot use response.body to fetch it using fetch, you’d need to stream the binary data, know which image type it is and set the appropriate headers for that specific image type.

Check this project for clues:

1 Like