sveltejs / kit

web development, streamlined

Home Page:https://kit.svelte.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

adapter-cloudflare-workers produces broken build with kit.paths.base filled with some subpath

nosovk opened this issue · comments

Describe the bug

I wan't to embed sveltekit project inside existing project (I have no access to server, that's why I stick up with CloudFlare Workers to inject my code into new routes inside existing site).
For example site.com/blog.
In svelte kit doc mentioned that there is no problem to server SvelteKit not from the root of the domain.
For that we should use kit.paths.base param.

  kit: { adapter: adapter(),
    paths: {
    relative: false,
    base: "/blog"
    }
  },

This works like a charm when I use local env or npm run preview. Problems appears when I publish site to workers.
wrangler.toml

name = "blog"
account_id = "df3d22d535d31ae83574535632890645"
main = "./.cloudflare/worker.js"
site.bucket = "./.cloudflare/public"
build.command = "npm run build"
compatibility_date = "2023-10-01"
workers_dev = true
routes = [
    { pattern = "b4ukraine.org/blog/*", zone_name = "b4ukraine.org" }
]

The config is pretty straight forward, but on workers env it broken. It seems that there are problems with router:
image
It seems that path not matched to registered routes inside the app.

Reproduction

setup any base url parameter in sveltekit config, and deploy using @sveltejs/adapter-cloudflare-workers

Logs

No response

System Info

System:
    OS: Windows 10 10.0.22621
    CPU: (20) x64 13th Gen Intel(R) Core(TM) i7-1370P
    Memory: 37.59 GB / 63.67 GB
  Binaries:
    Node: 20.5.1 - ~\AppData\Local\fnm_multishells\15836_1698362075353\node.EXE
    npm: 9.8.0 - ~\AppData\Local\fnm_multishells\15836_1698362075353\npm.CMD
    pnpm: 8.6.12 - ~\AppData\Local\fnm_multishells\15836_1698362075353\pnpm.CMD
  Browsers:
    Edge: Chromium (118.0.2088.69)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    @sveltejs/adapter-cloudflare-workers: ^1.1.4 => 1.1.4
    @sveltejs/kit: ^1.25.0 => 1.25.0
    svelte: ^3.59.1 => 3.59.2
    vite: ^4.4.9 => 4.4.9

Severity

blocking all usage of SvelteKit

Additional Information

No response

Please provide a minimal reproduction. I'm not sure how to reproduce this without the code that causes the screenshot shown.

It seems your home page can be found at /blog//. It also causes the worker to throw an exception. Could you share the error logs if you can find them? The same thing happens for the other two known routes /blog/about and /blog/404

I have a suspicion the routing fixes in adapter-cloudflare need to be copied over to adapter-cloudflare-workers.

You mean that: https://github.com/sveltejs/kit/pull/8618/files ?
I don't see other fixes related to routes except that one.

You mean that: #8618 (files) ? I don't see other fixes related to routes except that one.

No, it’s a routing fix that was only applied to adapter-cloudflare (I didn't know we had a adapter-cloudflare-workers at the time I sent the original PR)

let { pathname } = new URL(req.url);
try {
pathname = decodeURIComponent(pathname);
} catch {
// ignore invalid URI
}
const stripped_pathname = pathname.replace(/\/$/, '');
// prerendered pages and /static files
let is_static_asset = false;
const filename = stripped_pathname.substring(1);
if (filename) {
is_static_asset =
manifest.assets.has(filename) || manifest.assets.has(filename + '/index.html');
}
const location = pathname.at(-1) === '/' ? stripped_pathname : pathname + '/';
if (is_static_asset || prerendered.has(pathname)) {
res = await env.ASSETS.fetch(req);
} else if (location && prerendered.has(location)) {
res = new Response('', {
status: 308,
headers: {
location
}
});
} else {
// dynamically-generated pages
res = await server.respond(req, {
// @ts-ignore
platform: { env, context, caches, cf: req.cf },
getClientAddress() {
return req.headers.get('cf-connecting-ip');
}
});
}

compared to the cloudflare workers adapter which has the following bugs:

  • no prerendered trailing slash redirects
  • incorrectly comparing the encoded url pathname with the decoded ones in the manifest
  • does not correctly match with the /base/ pathname
    // prerendered pages and index.html files
    const pathname = url.pathname.replace(/\/$/, '');
    let file = pathname.substring(1);
    try {
    file = decodeURIComponent(file);
    } catch (err) {
    // ignore
    }
    if (
    manifest.assets.has(file) ||
    manifest.assets.has(file + '/index.html') ||
    prerendered.has(pathname || '/')
    ) {
    return get_asset_from_kv(req, env, context, (request, options) => {
    if (prerendered.has(pathname || '/')) {
    url.pathname = '/' + prerendered.get(pathname || '/').file;
    return new Request(url.toString(), request);
    }
    return mapRequestToAsset(request, options);
    });
    }
    // dynamically-generated pages
    return await server.respond(req, {
    platform: {
    env,
    context,
    // @ts-expect-error lib.dom is interfering with workers-types
    caches,
    // @ts-expect-error req is actually a Cloudflare request not a standard request
    cf: req.cf
    },
    getClientAddress() {
    return req.headers.get('cf-connecting-ip');
    }
    });