From 646f8791723c727cffdf4081ba6af9bd124f940d Mon Sep 17 00:00:00 2001 From: yuki0418 Date: Fri, 22 Aug 2025 17:06:14 +0900 Subject: [PATCH] fix: resolve_route prevent dropping a trailing slash of id --- .changeset/every-kings-wink.md | 5 +++++ packages/kit/src/utils/routing.js | 5 ++++- packages/kit/src/utils/routing.spec.js | 30 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 .changeset/every-kings-wink.md diff --git a/.changeset/every-kings-wink.md b/.changeset/every-kings-wink.md new file mode 100644 index 000000000000..6d643e8ac53a --- /dev/null +++ b/.changeset/every-kings-wink.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: resolve_route prevent dropping a trailing slash of id diff --git a/packages/kit/src/utils/routing.js b/packages/kit/src/utils/routing.js index ee129976b6e4..f36988f370b8 100644 --- a/packages/kit/src/utils/routing.js +++ b/packages/kit/src/utils/routing.js @@ -240,6 +240,8 @@ const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g; */ export function resolve_route(id, params) { const segments = get_route_segments(id); + const has_id_trailing_slash = id != '/' && id.endsWith('/'); + return ( '/' + segments @@ -262,7 +264,8 @@ export function resolve_route(id, params) { }) ) .filter(Boolean) - .join('/') + .join('/') + + (has_id_trailing_slash ? '/' : '') ); } diff --git a/packages/kit/src/utils/routing.spec.js b/packages/kit/src/utils/routing.spec.js index 03ab03af3c78..75f5487eb2fa 100644 --- a/packages/kit/src/utils/routing.spec.js +++ b/packages/kit/src/utils/routing.spec.js @@ -278,30 +278,60 @@ describe('resolve_route', () => { params: { one: 'one', two: 'two' }, expected: '/blog/one/two' }, + { + route: '/blog/[one]/[two]/', + params: { one: 'one', two: 'two' }, + expected: '/blog/one/two/' + }, { route: '/blog/[one=matcher]/[...two]', params: { one: 'one', two: 'two/three' }, expected: '/blog/one/two/three' }, + { + route: '/blog/[one=matcher]/[...two]/', + params: { one: 'one', two: 'two/three' }, + expected: '/blog/one/two/three/' + }, { route: '/blog/[one=matcher]/[[two]]', params: { one: 'one' }, expected: '/blog/one' }, + { + route: '/blog/[one=matcher]/[[two]]/', + params: { one: 'one' }, + expected: '/blog/one/' + }, { route: '/blog/[one]/[two]-and-[three]', params: { one: 'one', two: '2', three: '3' }, expected: '/blog/one/2-and-3' }, + { + route: '/blog/[one]/[two]-and-[three]/', + params: { one: 'one', two: '2', three: '3' }, + expected: '/blog/one/2-and-3/' + }, { route: '/blog/[...one]', params: { one: '' }, expected: '/blog' }, + { + route: '/blog/[...one]/', + params: { one: '' }, + expected: '/blog/' + }, { route: '/blog/[one]/[...two]-not-three', params: { one: 'one', two: 'two/2' }, expected: '/blog/one/two/2-not-three' + }, + { + route: '/blog/[one]/[...two]-not-three/', + params: { one: 'one', two: 'two/2' }, + expected: '/blog/one/two/2-not-three/' } ];