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 <poldsberg@gmail.com>
Made-with: Cursor
This commit is contained in:
Patrik Oldsberg
2026-03-30 14:46:18 +02:00
parent 4a01a66da3
commit baa72405ac
2 changed files with 77 additions and 1 deletions
@@ -370,6 +370,79 @@ describe('AppRoutes', () => {
});
});
it('should only redirect the root path when from is /', async () => {
const LocationDisplay = () => {
const location = useLocation();
return <div data-testid="location">{location.pathname}</div>;
};
const catalogPage = PageBlueprint.make({
name: 'catalog',
params: {
path: '/catalog',
loader: async () => (
<div>
Catalog Page
<LocationDisplay />
</div>
),
},
});
const homePage = PageBlueprint.make({
name: 'home',
params: {
path: '/home',
loader: async () => (
<div>
Home Page
<LocationDisplay />
</div>
),
},
});
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',
+4 -1
View File
@@ -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: <Navigate to={redirect.to} replace />,
})),
...inputs.routes.map(route => {