diff --git a/contributors.yml b/contributors.yml index 044bdc5f48..205fe06b05 100644 --- a/contributors.yml +++ b/contributors.yml @@ -36,6 +36,7 @@ - goldins - gowthamvbhat - GraxMonzo +- GuptaSiddhant - haivuw - hernanif1 - hongji00 diff --git a/packages/react-router/__tests__/createRoutesFromChildren-test.tsx b/packages/react-router/__tests__/createRoutesFromChildren-test.tsx index a2727a13e4..854de937ad 100644 --- a/packages/react-router/__tests__/createRoutesFromChildren-test.tsx +++ b/packages/react-router/__tests__/createRoutesFromChildren-test.tsx @@ -196,4 +196,26 @@ describe("creating routes from JSX", () => { ] `); }); + + it("throws when the index route has children", () => { + expect(() => { + createRoutesFromChildren( + 💥} path="/"> + {}} + shouldRevalidate={() => true} + element={

home

} + > + {}} + element={

users index

} + /> +
+
+ ); + }).toThrow("An index route must not have child routes."); + }); }); diff --git a/packages/react-router/lib/components.tsx b/packages/react-router/lib/components.tsx index cd1795e95a..0e252ae99f 100644 --- a/packages/react-router/lib/components.tsx +++ b/packages/react-router/lib/components.tsx @@ -585,6 +585,7 @@ export function createRoutesFromChildren( }; if (element.props.children) { + invariant(!route.index, "An index route must not have child routes."); route.children = createRoutesFromChildren( element.props.children, treePath @@ -619,7 +620,7 @@ export function enhanceManualRouteObjects( if (routeClone.hasErrorBoundary == null) { routeClone.hasErrorBoundary = routeClone.errorElement != null; } - if (routeClone.children) { + if (!routeClone.index && routeClone.children) { routeClone.children = enhanceManualRouteObjects(routeClone.children); } return routeClone; diff --git a/packages/react-router/lib/context.ts b/packages/react-router/lib/context.ts index bb0fa2396a..db84e38c7a 100644 --- a/packages/react-router/lib/context.ts +++ b/packages/react-router/lib/context.ts @@ -13,16 +13,14 @@ import type { Action as NavigationType } from "@remix-run/router"; // Create react-specific types from the agnostic types in @remix-run/router to // export from react-router -export interface RouteObject extends AgnosticRouteObject { - children?: RouteObject[]; +export type RouteObject = Omit & { element?: React.ReactNode | null; errorElement?: React.ReactNode | null; -} +} & ({ index?: false; children?: RouteObject[] } | { index: true }); -export interface DataRouteObject extends RouteObject { - children?: DataRouteObject[]; +export type DataRouteObject = Omit & { id: string; -} +} & ({ index?: false; children?: DataRouteObject[] } | { index: true }); export interface RouteMatch< ParamKey extends string = string,