Skip to content

Trailing slash snafu when applying adapter-node's handler to a dynamic base path #13702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
HoldYourWaffle opened this issue Apr 11, 2025 · 0 comments

Comments

@HoldYourWaffle
Copy link
Contributor

HoldYourWaffle commented Apr 11, 2025

Describe the bug

Related: #595 and #7242.

I need to integrate a SvelteKit app into an existing Express.js server at a dynamic base path. Based on #595 (comment) I assume this is intended to be supported through the kit.paths.relative option, but there's a bit of a snafu with trailing slashes on the base path.

Standard static paths.base behavior (repro branch)

With a configuration like this:

const config = {
	kit: {
		adapter: adapterNode(),
		paths: {
			base: '/sveltekit',
			relative: true
		}
	}
}

...and integration into a custom server like this:

app.use(handler);

/sveltekit is always redirected to /sveltekit/, regardless of trailingSlash configuration. This makes sense, because the trailing slash is necessary to resolve relative paths starting with ./ correctly.
This seems to be handled by this snippet that eventually ends up in build/server/index.js:

// if `paths.base === '/a/b/c`, then the root route is `/a/b/c/`,
// regardless of the `trailingSlash` route option
if (url.pathname === base || url.pathname === base + '/') {
trailing_slash = 'always';

Dynamic paths.base attempt (repro branch)

With a configuration like this:

const config = {
	kit: {
		adapter: adapterNode(),
		paths: {
			relative: true
		}
	}
};

...and integration like this:

app.use('/sveltekit', handler);

/sveltekit is no longer redirected to /sveltekit/, regardless of trailingSlash configuration. As expected this breaks basically everything with a relative path.

Reproduction

HoldYourWaffle/sveltekit-express-dynamic-basepath, specifically repro--static-base and repro--dynamic-base.

System Info

System:
    OS: Windows 10 10.0.19045
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 16.98 GB / 31.81 GB
  Binaries:
    Node: 22.14.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.9.2 - C:\Program Files\nodejs\npm.CMD
    pnpm: 10.6.2 - ~\AppData\Local\pnpm\pnpm.CMD
  Browsers:
    Edge: Chromium (133.0.3065.69)
    Internet Explorer: 11.0.19041.4355

Severity

serious, but I can work around it

Additional Information

After some digging I realized that app.use strips out the provided prefix path, which causes url.pathname to be / in both situations, therefore the aforementioned check can't tell the difference.
I assume #7242 would solve this issue, since there's no need to pass a prefix path to app.use if paths.base can be provided at runtime.

Workaround

In my case I can just implement the redirect myself outside the context of app.use:

app.all('/sveltekit', (req, res, next) => {
	if (!req.url.endsWith('/')) {
		res.redirect(308, '/sveltekit/');
	} else {
		next();
	}
});

app.use('/sveltekit', handler);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant