diff --git a/.changeset/fresh-needles-join.md b/.changeset/fresh-needles-join.md new file mode 100644 index 00000000000..fa8b3fce052 --- /dev/null +++ b/.changeset/fresh-needles-join.md @@ -0,0 +1,24 @@ +--- +"remix": patch +"@remix-run/dev": patch +--- + +use `index` without leading underscore for colocation + +when using flat routes with folder colocation, use `index` without leading underscore for route + +before: +``` + app_.projects.$id.roadmap/ + _index.tsx + chart.tsx + update-timeline.server.tsx +``` + +after: +``` + app_.projects.$id.roadmap/ + index.tsx + chart.tsx + update-timeline.server.tsx +``` diff --git a/packages/remix-dev/__tests__/flat-routes-test.ts b/packages/remix-dev/__tests__/flat-routes-test.ts index 8735e752556..5446afec45a 100644 --- a/packages/remix-dev/__tests__/flat-routes-test.ts +++ b/packages/remix-dev/__tests__/flat-routes-test.ts @@ -4,6 +4,7 @@ import { createRoutePath, flatRoutesUniversal, getRouteSegments, + isIndexRoute, } from "../config/flat-routes"; import type { ConfigRoute } from "../config/routes"; @@ -25,10 +26,10 @@ describe("flatRoutes", () => { ["nested/$slug", "/nested/:slug"], ["flat.$slug", "/flat/:slug"], ["flat.sub", "/flat/sub"], - ["nested/_index", "/nested"], + ["nested/index", "/nested"], ["flat._index", "/flat"], ["_index", undefined], - ["_layout/_index", undefined], + ["_layout/index", undefined], ["_layout/test", "/test"], ["_layout.test", "/test"], ["_layout/$slug", "/:slug"], @@ -88,7 +89,8 @@ describe("flatRoutes", () => { for (let [input, expected] of tests) { it(`"${input}" -> "${expected}"`, () => { let routeSegments = getRouteSegments(input); - expect(createRoutePath(routeSegments)).toBe(expected); + let isIndex = isIndexRoute(input); + expect(createRoutePath(routeSegments, isIndex)).toBe(expected); }); } @@ -332,9 +334,9 @@ describe("flatRoutes", () => { }, ], [ - "routes/app_.skipall_/_index.tsx", + "routes/app_.skipall_/index.tsx", { - id: "routes/app_.skipall_/_index", + id: "routes/app_.skipall_/index", index: true, parentId: "root", path: "app/skipall", @@ -580,9 +582,9 @@ describe("flatRoutes", () => { }, ], [ - "routes/brand/_index.tsx", + "routes/brand/index.tsx", { - id: "routes/brand/_index", + id: "routes/brand/index", parentId: "root", path: "brand", index: true, diff --git a/packages/remix-dev/config/flat-routes.ts b/packages/remix-dev/config/flat-routes.ts index 65d59e39406..16af3738278 100644 --- a/packages/remix-dev/config/flat-routes.ts +++ b/packages/remix-dev/config/flat-routes.ts @@ -103,8 +103,11 @@ export function flatRoutesUniversal( return routes; } -function isIndexRoute(routeId: string) { - return routeId.endsWith("_index"); +export function isIndexRoute(routeId: string) { + let isFlatFile = !routeId.includes(path.posix.sep); + return isFlatFile + ? routeId.endsWith("_index") + : /\/index$/.test(routeId); } type State = @@ -262,7 +265,7 @@ function getRouteInfo( let routeIdWithoutRoutes = routeId.slice(routeDirectory.length + 1); let index = isIndexRoute(routeIdWithoutRoutes); let routeSegments = getRouteSegments(routeIdWithoutRoutes); - let routePath = createRoutePath(routeSegments); + let routePath = createRoutePath(routeSegments, index); return { id: routeIdWithoutRoutes, @@ -274,9 +277,13 @@ function getRouteInfo( }; } -export function createRoutePath(routeSegments: string[]) { +export function createRoutePath(routeSegments: string[], isIndex: boolean) { let result = ""; + if (isIndex) { + routeSegments = routeSegments.slice(0, -1); + } + for (let segment of routeSegments) { // skip pathless layout segments if (segment.startsWith("_")) {