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.