Workers htaccess/ rewrite url

I am trying to accomplish something like what’s documented here: Different History modes | Vue Router

I believe I had it working just a few weeks ago, using the htaccess file, but now I can’t seem to get it working.

I have some routes like this: /my-account/orders/, that are not pre-generated by my application made with Nuxt. I would like, say this link: /my-account/orders/1234 to fall back to the index.html file inside the /my-account/orders/ folder. I have tried like this:

<IfModule mod_rewrite.c>
	RewriteEngine On
	RewriteBase /my-account/orders/
	RewriteRule ^index\.html$ - [L]
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteRule . /index.html [L]
</IfModule>

However, when I visit the given route, I get this error:

could not find my-account/orders/wc_order_EyME9hphZyHXi/index.html in your content namespace

What am I doing wrong? and how could I achieve something similar, but using some workers scripting, instead of htaccess? I have a few different routes I need to have this fallback mechanism on (/my-account/orders/, /product/, etc)

Maybe I need to se the RewriteBase to “/” or perhaps “/dist/” because this is the path to my wrangler bucket?

I need to create a catch-all fallback, as I am hosting on Cloudflare workers. This article describes how to do it for various different platforms: Different History modes | Vue Router (nginx, apache, etc) but not for Cloudflare workers. Could anybody help me with the correct approach to create this fallback?

I have done like this, so far:

async function handleEvent(event) {
const url = new URL(event.request.url)
let options = {}

/**
 * You can add custom logic to how we fetch your assets
 * by configuring the function `mapRequestToAsset`
 */
options.mapRequestToAsset = (request) => {
	  let defaultAssetKey = mapRequestToAsset(request);
	  let url = new URL(defaultAssetKey.url);

	  // orders
	  url.pathname = 'something-else';

	  // inherit all other props from the default request
	  return new Request(url.toString(), defaultAssetKey);
  };

try {
  if (DEBUG) {
	// customize caching
	options.cacheControl = {
	  bypassCache: true,
	}
  }
  return await getAssetFromKV(event, options)
} catch (e) {
  // if an error is thrown try to serve the asset at 404.html
  if (!DEBUG) {
	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 })
	} catch (e) {}
  }

  return new Response(e.message || e.toString(), { status: 500 })
}

}

However, there is one issue. I only want to replace the pathname (e.g. to /index.html) when the file requested is not found. Not sure how / if I can handle this.

I am trying to serve another file, than what has been requested. I found this old link: https://developers.cloudflare.com/workers/archive/recipes/vcl-conversion/conditionally-changing-a-url/

However, I am getting some sort of error when requesting – I am not sure what. It tells me to check the “error logs” but there is no error log to be found (getting Error 1101).

This is what I am trying to do:

	 if (!url.href.includes('_nuxt') && url.pathname !== '/') {
			url.pathname = '/index.html';
			event.request.url = url.href;
	 }

Basically, if any file is requested, that is not containing “_nuxt” (as this is most likely an static asset), I wish to return the “index.html” file, as in this file there’s a javascript router that will deliver the requested resource.

The whole worker file looks like this:

addEventListener('fetch', (event) => {
	try {
	event.respondWith(handleEvent(event))
	} catch (e) {
	if (DEBUG) {
		return event.respondWith(
		new Response(e.message || e.toString(), {
			status: 500,
		}),
		)
	}
	event.respondWith(new Response('Internal Error', { status: 500 }))
	}
})

async function handleEvent(event) {
	const url = new URL(event.request.url)
	let options = {}

	/**
	 * Check for 301 redirects
	 */

	const redirect = await REDIRECTS.get(url.pathname).then((redirectJson) => {
	if(redirectJson) {
		let redirect = JSON.parse(redirectJson);
		url.pathname = redirect.path;

		// return { url: url.href, type: redirect.type.replace };
		return { url: url.href, type: 301 };
	}
	});
	if(redirect) {
		return Response.redirect(redirect.url, redirect.type);
	}

	/**
	 * Fallback for non generated static sites
	 */

	if (!url.href.includes('_nuxt') && url.pathname !== '/') {
			url.pathname = '/index.html';
			event.request.url = url.href;
	}

	/**
	 * You can add custom logic to how we fetch your assets
	 * by configuring the function `mapRequestToAsset`
	 */
	// options.mapRequestToAsset = handlePrefix(/^\/docs/)

	try {
	if (DEBUG) {
		// customize caching
		options.cacheControl = {
		bypassCache: true,
		}
	}
	return await getAssetFromKV(event, options)
	} catch (e) {
	// if an error is thrown try to serve the asset at 404.html
	if (!DEBUG) {
		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 })
		} catch (e) {}
	}

	return new Response(e.message || e.toString(), { status: 500 })
	}
}

I ended up doing like so:

async function handleEvent(event) {
const url = new URL(event.request.url)
let options = {}

/**
 * You can add custom logic to how we fetch your assets
 * by configuring the function `mapRequestToAsset`
 */
options.mapRequestToAsset = (request) => {
	  let defaultAssetKey = mapRequestToAsset(request);
	  let url = new URL(defaultAssetKey.url);

	  // orders
	  url.pathname = 'something-else';

	  // inherit all other props from the default request
	  return new Request(url.toString(), defaultAssetKey);
  };

try {
  if (DEBUG) {
	// customize caching
	options.cacheControl = {
	  bypassCache: true,
	}
  }
  return await getAssetFromKV(event, options)
} catch (e) {
  // if an error is thrown try to serve the asset at 404.html
  if (!DEBUG) {
	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 })
	} catch (e) {}
  }

  return new Response(e.message || e.toString(), { status: 500 })
}
}

However, I still need to find out how I can only replace the pathname, if the requested resource is not found.