From baa72405ac855e8b9e90d9e7ce3ce42ebd50cb9c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 30 Mar 2026 14:46:18 +0200 Subject: [PATCH] Fix root path redirect matching all routes Special-case `from: '/'` in redirect config to use an exact path match instead of the `/*` wildcard, which would match the entire app. Signed-off-by: Patrik Oldsberg Made-with: Cursor --- plugins/app/src/extensions/AppRoutes.test.tsx | 73 +++++++++++++++++++ plugins/app/src/extensions/AppRoutes.tsx | 5 +- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/plugins/app/src/extensions/AppRoutes.test.tsx b/plugins/app/src/extensions/AppRoutes.test.tsx index 62233786bd..9aa6474189 100644 --- a/plugins/app/src/extensions/AppRoutes.test.tsx +++ b/plugins/app/src/extensions/AppRoutes.test.tsx @@ -370,6 +370,79 @@ describe('AppRoutes', () => { }); }); + it('should only redirect the root path when from is /', async () => { + const LocationDisplay = () => { + const location = useLocation(); + return
{location.pathname}
; + }; + + const catalogPage = PageBlueprint.make({ + name: 'catalog', + params: { + path: '/catalog', + loader: async () => ( +
+ Catalog Page + +
+ ), + }, + }); + + const homePage = PageBlueprint.make({ + name: 'home', + params: { + path: '/home', + loader: async () => ( +
+ Home Page + +
+ ), + }, + }); + + const redirectsConfig = { + ...DEFAULT_CONFIG, + app: { + ...DEFAULT_CONFIG.app, + extensions: [ + { + 'app/routes': { + config: { + redirects: [{ from: '/', to: '/home' }], + }, + }, + }, + ], + }, + }; + + const { unmount } = renderTestApp({ + extensions: [catalogPage, homePage], + initialRouteEntries: ['/'], + config: redirectsConfig, + }); + + await waitFor(() => { + expect(screen.getByText('Home Page')).toBeInTheDocument(); + expect(screen.getByTestId('location')).toHaveTextContent('/home'); + }); + + unmount(); + + renderTestApp({ + extensions: [catalogPage, homePage], + initialRouteEntries: ['/catalog'], + config: redirectsConfig, + }); + + await waitFor(() => { + expect(screen.getByText('Catalog Page')).toBeInTheDocument(); + expect(screen.getByTestId('location')).toHaveTextContent('/catalog'); + }); + }); + it('should not interfere with normal routes when redirects are configured', async () => { const homePage = PageBlueprint.make({ name: 'home', diff --git a/plugins/app/src/extensions/AppRoutes.tsx b/plugins/app/src/extensions/AppRoutes.tsx index b8b894df16..f73c47e2cb 100644 --- a/plugins/app/src/extensions/AppRoutes.tsx +++ b/plugins/app/src/extensions/AppRoutes.tsx @@ -52,7 +52,10 @@ export const AppRoutes = createExtension({ const Routes = () => { const element = useRoutes([ ...redirects.map(redirect => ({ - path: `${redirect.from.replace(/\/$/, '')}/*`, + path: + redirect.from === '/' + ? redirect.from + : `${redirect.from.replace(/\/$/, '')}/*`, element: , })), ...inputs.routes.map(route => {