From a92974378f8f73e575ba251875d199183bb3ef68 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Fri, 21 Nov 2025 18:57:30 +0100 Subject: [PATCH 1/3] refactor(router-core): interpolatePath skips optional segments w/ nullish param value --- packages/router-core/src/path.ts | 13 +++---------- .../tests/optional-path-params.test.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/router-core/src/path.ts b/packages/router-core/src/path.ts index 0a424bf96c..484f797307 100644 --- a/packages/router-core/src/path.ts +++ b/packages/router-core/src/path.ts @@ -320,22 +320,15 @@ export function interpolatePath({ if (kind === SEGMENT_TYPE_OPTIONAL_PARAM) { const key = path.substring(segment[2], segment[3]) - const prefix = path.substring(start, segment[1]) - const suffix = path.substring(segment[4], end) const valueRaw = params[key] // Check if optional parameter is missing or undefined - if (valueRaw == null) { - if (prefix || suffix) { - // For optional params with prefix/suffix, keep the prefix/suffix but omit the param - joined += '/' + prefix + suffix - } - // If no prefix/suffix, omit the entire segment - continue - } + if (valueRaw == null) continue usedParams[key] = valueRaw + const prefix = path.substring(start, segment[1]) + const suffix = path.substring(segment[4], end) const value = encodeParam(key, params, decodeCharMap) ?? '' joined += '/' + prefix + value + suffix continue diff --git a/packages/router-core/tests/optional-path-params.test.ts b/packages/router-core/tests/optional-path-params.test.ts index 79a368eb52..7d7087c83a 100644 --- a/packages/router-core/tests/optional-path-params.test.ts +++ b/packages/router-core/tests/optional-path-params.test.ts @@ -205,6 +205,12 @@ describe('Optional Path Parameters', () => { name: 'optional param with prefix - omitted', path: '/posts/prefix{-$category}', params: {}, + result: '/posts', + }, + { + name: 'optional param with prefix - empty string', + path: '/posts/prefix{-$category}', + params: { category: '' }, result: '/posts/prefix', }, { @@ -217,6 +223,12 @@ describe('Optional Path Parameters', () => { name: 'optional param with suffix - omitted', path: '/posts/{-$category}.html', params: {}, + result: '/posts', + }, + { + name: 'optional param with suffix - empty string', + path: '/posts/{-$category}.html', + params: {category: ''}, result: '/posts/.html', }, { @@ -229,6 +241,12 @@ describe('Optional Path Parameters', () => { name: 'optional param with prefix and suffix - omitted', path: '/posts/prefix{-$category}suffix', params: {}, + result: '/posts', + }, + { + name: 'optional param with prefix and suffix - empty string', + path: '/posts/prefix{-$category}suffix', + params: { category: '' }, result: '/posts/prefixsuffix', }, { From 3716539474cded7515cbf17dd94eaa2a0ee8b8a1 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 17:59:42 +0000 Subject: [PATCH 2/3] ci: apply automated fixes --- packages/router-core/tests/optional-path-params.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/router-core/tests/optional-path-params.test.ts b/packages/router-core/tests/optional-path-params.test.ts index 7d7087c83a..304e9aebc0 100644 --- a/packages/router-core/tests/optional-path-params.test.ts +++ b/packages/router-core/tests/optional-path-params.test.ts @@ -228,7 +228,7 @@ describe('Optional Path Parameters', () => { { name: 'optional param with suffix - empty string', path: '/posts/{-$category}.html', - params: {category: ''}, + params: { category: '' }, result: '/posts/.html', }, { From a30b88decc2d53b4ac41d15e4121d01c48b4bcf3 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Fri, 21 Nov 2025 19:29:42 +0100 Subject: [PATCH 3/3] fix tests --- packages/react-router/tests/navigate.test.tsx | 4 ++-- packages/react-router/tests/optional-path-params.test.tsx | 2 +- packages/solid-router/tests/navigate.test.tsx | 4 ++-- packages/solid-router/tests/optional-path-params.test.tsx | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/react-router/tests/navigate.test.tsx b/packages/react-router/tests/navigate.test.tsx index 1e520c2621..3aaaa7124b 100644 --- a/packages/react-router/tests/navigate.test.tsx +++ b/packages/react-router/tests/navigate.test.tsx @@ -1146,7 +1146,7 @@ describe('router.navigate navigation using optional path parameters - edge cases }) await router.invalidate() - expect(router.state.location.pathname).toBe('/files/prefix.txt') + expect(router.state.location.pathname).toBe('/files') // Add the name parameter back await router.navigate({ @@ -1236,7 +1236,7 @@ describe('router.navigate navigation using optional path parameters - edge cases }) await router.invalidate() - expect(router.state.location.pathname).toBe('/files/prefix.txt') + expect(router.state.location.pathname).toBe('/files') }) }) diff --git a/packages/react-router/tests/optional-path-params.test.tsx b/packages/react-router/tests/optional-path-params.test.tsx index 59924e219f..1a69d70b96 100644 --- a/packages/react-router/tests/optional-path-params.test.tsx +++ b/packages/react-router/tests/optional-path-params.test.tsx @@ -578,7 +578,7 @@ describe('React Router - Optional Path Parameters', () => { const filesLink = await screen.findByTestId('files-link') const docLink = await screen.findByTestId('doc-link') - expect(filesLink).toHaveAttribute('href', '/files/prefix.txt') + expect(filesLink).toHaveAttribute('href', '/files') expect(docLink).toHaveAttribute('href', '/files/prefixdocument.txt') }) }) diff --git a/packages/solid-router/tests/navigate.test.tsx b/packages/solid-router/tests/navigate.test.tsx index 8c5ac5ade4..4aaacc8674 100644 --- a/packages/solid-router/tests/navigate.test.tsx +++ b/packages/solid-router/tests/navigate.test.tsx @@ -1170,7 +1170,7 @@ describe('router.navigate navigation using optional path parameters - edge cases }) await router.invalidate() - expect(router.state.location.pathname).toBe('/files/prefix.txt') + expect(router.state.location.pathname).toBe('/files') // Add the name parameter back await router.navigate({ @@ -1260,7 +1260,7 @@ describe('router.navigate navigation using optional path parameters - edge cases }) await router.invalidate() - expect(router.state.location.pathname).toBe('/files/prefix.txt') + expect(router.state.location.pathname).toBe('/files') }) }) diff --git a/packages/solid-router/tests/optional-path-params.test.tsx b/packages/solid-router/tests/optional-path-params.test.tsx index a1c7b6f79d..8901a508b0 100644 --- a/packages/solid-router/tests/optional-path-params.test.tsx +++ b/packages/solid-router/tests/optional-path-params.test.tsx @@ -579,7 +579,7 @@ describe('Solid Router - Optional Path Parameters', () => { const filesLink = await screen.findByTestId('files-link') const docLink = await screen.findByTestId('doc-link') - expect(filesLink).toHaveAttribute('href', '/files/prefix.txt') + expect(filesLink).toHaveAttribute('href', '/files') expect(docLink).toHaveAttribute('href', '/files/prefixdocument.txt') }) })