trailingSlash=always ignored on client render when error boundary is defined before/above node config
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 20.8k
- Forks
- 2.3k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 156
Description
Describe the bug
Issue
I'm a bit newer to svelte kit, so it's a bit unclear if this is actually intended behavior, but I couldn't find any documentation around it, and the behavior feels like a bug.
Given a file structure like:
routes/
test/
+page.js // trailingSlash = 'always' configured here
+page.svelte
// important: no trailingSlash = 'always' is set at a higher level
If an http error (error()) is thrown in the loader for /test/, the client render/hydration will change the url.pathname to /test without the trailing slash. In our specific app, it actually caused an infinite redirect because of how we ensure trailing slash; however, for svelte kit, but you can still replicate in a brand new svelte kit app that it changes the url incorrectly, but doesn't seem to cause an infinite redirect.
This behavior only happens during client loading (via CSN to the page that errors) or client hydration after server render.
Example
Locally:
Stack Blitz:
Cause
On this specific line:
branch: branch.slice(0, error_load.idx).concat(error_load.node),
Given a branch structure like:
layout
layout (error.svelte could be defined at this layer or above or not at all)
page (trailingSlash defined here)
The branch value passed into get_navigation_result_from_branch will remove all nodes below the error node which removes the trailing slash config and the url.pathname will get overridden to the default never setting: https://github.com/sveltejs/kit/blob/3cf2b77b4ae87bbd4fc46367c37c129133af41f1/packages/kit/src/runtime/client/client.js#L503-L515
Work around
To prevent this issue from happening, you need to just ensure that the closest error.svelte to the route is below where the trailingSlash = 'always' config is set.
So defining trailingSlash = 'always' in a root layout could fix the issue (if no error.svelte is configured in the app), or just actually defining an error.svelte in folder below where the trailingSlash is configured (and obviously above or at where the actual route loader is).
Reproduction
Logs
System Info
System:
OS: macOS 15.3.1
CPU: (12) arm64 Apple M3 Pro
Memory: 120.05 MB / 36.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.20.6 - ~/bin/node
npm: 10.8.2 - ~/bin/npm
Browsers:
Chrome: 133.0.6943.142
Safari: 18.3
npmPackages:
@sveltejs/adapter-auto: ^4.0.0 => 4.0.0
@sveltejs/kit: ^2.16.0 => 2.17.3
@sveltejs/vite-plugin-svelte: ^5.0.0 => 5.0.3
svelte: ^5.0.0 => 5.20.5
vite: ^6.0.0 => 6.2.0
Severity
annoyance
Additional Information
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the StackBlitz reproduction and inspect packages/kit/src/runtime/client/client.js around lines 1058-1068 and 503-515. Trace how the truncated branch affects trailingSlash during client navigation and hydration when the error boundary is above the route configuration. Done means preserving the configured trailing slash for the error page without breaking normal error handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 56/100