From 8835eac687517df79df157b95e9e988fa9ae53fd Mon Sep 17 00:00:00 2001 From: Nico Lynzaad Date: Thu, 16 Oct 2025 00:42:07 +0200 Subject: [PATCH] ensure trailing slash is removed from layouts --- .../basic-file-based/src/routeTree.gen.ts | 75 ++++------ .../basic-file-based/src/routeTree.gen.ts | 75 ++++------ packages/router-generator/src/generator.ts | 8 ++ .../routeTree.snapshot.ts | 128 ++++-------------- .../routeTree.snapshot.ts | 25 +++- .../routes/a/$b/(c)/index.tsx | 5 + .../route-groups/routeTree.snapshot.ts | 87 ++---------- 7 files changed, 122 insertions(+), 281 deletions(-) create mode 100644 packages/router-generator/tests/generator/path-above-route-in-group/routes/a/$b/(c)/index.tsx diff --git a/e2e/react-router/basic-file-based/src/routeTree.gen.ts b/e2e/react-router/basic-file-based/src/routeTree.gen.ts index 5c4c85f21c7..7d0c24c98a1 100644 --- a/e2e/react-router/basic-file-based/src/routeTree.gen.ts +++ b/e2e/react-router/basic-file-based/src/routeTree.gen.ts @@ -8,8 +8,6 @@ // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. -import { createFileRoute } from '@tanstack/react-router' - import { Route as rootRouteImport } from './routes/__root' import { Route as Char45824Char54620Char48124Char44397RouteImport } from './routes/대한민국' import { Route as RemountDepsRouteImport } from './routes/remountDeps' @@ -99,12 +97,6 @@ import { Route as RelativeLinkPathPathIndexRouteImport } from './routes/relative import { Route as RelativeLinkNestedDeepIndexRouteImport } from './routes/relative/link/nested/deep/index' import { Route as ParamsPsNamedFooBarBazRouteImport } from './routes/params-ps/named/$foo/$bar.$baz' -const groupRouteImport = createFileRoute('/(group)')() - -const groupRoute = groupRouteImport.update({ - id: '/(group)', - getParentRoute: () => rootRouteImport, -} as any) const Char45824Char54620Char48124Char44397Route = Char45824Char54620Char48124Char44397RouteImport.update({ id: '/대한민국', @@ -217,19 +209,19 @@ const LayoutLayout2Route = LayoutLayout2RouteImport.update({ } as any) const groupLazyinsideRoute = groupLazyinsideRouteImport .update({ - id: '/lazyinside', + id: '/(group)/lazyinside', path: '/lazyinside', - getParentRoute: () => groupRoute, + getParentRoute: () => rootRouteImport, } as any) .lazy(() => import('./routes/(group)/lazyinside.lazy').then((d) => d.Route)) const groupInsideRoute = groupInsideRouteImport.update({ - id: '/inside', + id: '/(group)/inside', path: '/inside', - getParentRoute: () => groupRoute, + getParentRoute: () => rootRouteImport, } as any) const groupLayoutRoute = groupLayoutRouteImport.update({ - id: '/_layout', - getParentRoute: () => groupRoute, + id: '/(group)/_layout', + getParentRoute: () => rootRouteImport, } as any) const anotherGroupOnlyrouteinsideRoute = anotherGroupOnlyrouteinsideRouteImport.update({ @@ -388,9 +380,9 @@ const LayoutLayout2LayoutARoute = LayoutLayout2LayoutARouteImport.update({ getParentRoute: () => LayoutLayout2Route, } as any) const groupSubfolderInsideRoute = groupSubfolderInsideRouteImport.update({ - id: '/subfolder/inside', + id: '/(group)/subfolder/inside', path: '/subfolder/inside', - getParentRoute: () => groupRoute, + getParentRoute: () => rootRouteImport, } as any) const groupLayoutInsidelayoutRoute = groupLayoutInsidelayoutRouteImport.update({ id: '/insidelayout', @@ -572,7 +564,7 @@ const ParamsPsNamedFooBarBazRoute = ParamsPsNamedFooBarBazRouteImport.update({ } as any) export interface FileRoutesByFullPath { - '/': typeof groupLayoutRouteWithChildren + '/': typeof IndexRoute '/non-nested': typeof NonNestedRouteRouteWithChildren '/search-params': typeof SearchParamsRouteRouteWithChildren '/anchor': typeof AnchorRoute @@ -658,7 +650,7 @@ export interface FileRoutesByFullPath { '/relative/useNavigate/path/$path': typeof RelativeUseNavigatePathPathIndexRoute } export interface FileRoutesByTo { - '/': typeof groupLayoutRouteWithChildren + '/': typeof IndexRoute '/non-nested': typeof NonNestedRouteRouteWithChildren '/anchor': typeof AnchorRoute '/component-types-test': typeof ComponentTypesTestRoute @@ -758,7 +750,6 @@ export interface FileRoutesById { '/relative/link': typeof RelativeLinkRouteRouteWithChildren '/relative/useNavigate': typeof RelativeUseNavigateRouteRouteWithChildren '/(another-group)/onlyrouteinside': typeof anotherGroupOnlyrouteinsideRoute - '/(group)': typeof groupRouteWithChildren '/(group)/_layout': typeof groupLayoutRouteWithChildren '/(group)/inside': typeof groupInsideRoute '/(group)/lazyinside': typeof groupLazyinsideRoute @@ -1015,7 +1006,6 @@ export interface FileRouteTypes { | '/relative/link' | '/relative/useNavigate' | '/(another-group)/onlyrouteinside' - | '/(group)' | '/(group)/_layout' | '/(group)/inside' | '/(group)/lazyinside' @@ -1102,13 +1092,16 @@ export interface RootRouteChildren { RelativeLinkRouteRoute: typeof RelativeLinkRouteRouteWithChildren RelativeUseNavigateRouteRoute: typeof RelativeUseNavigateRouteRouteWithChildren anotherGroupOnlyrouteinsideRoute: typeof anotherGroupOnlyrouteinsideRoute - groupRoute: typeof groupRouteWithChildren + groupLayoutRoute: typeof groupLayoutRouteWithChildren + groupInsideRoute: typeof groupInsideRoute + groupLazyinsideRoute: typeof groupLazyinsideRoute RedirectTargetRoute: typeof RedirectTargetRouteWithChildren StructuralSharingEnabledRoute: typeof StructuralSharingEnabledRoute ParamsPsIndexRoute: typeof ParamsPsIndexRoute RedirectIndexRoute: typeof RedirectIndexRoute RelativeIndexRoute: typeof RelativeIndexRoute ParamsPsNamedFooRouteRoute: typeof ParamsPsNamedFooRouteRouteWithChildren + groupSubfolderInsideRoute: typeof groupSubfolderInsideRoute ParamsPsNamedPrefixChar123fooChar125Route: typeof ParamsPsNamedPrefixChar123fooChar125Route ParamsPsNamedChar123fooChar125suffixRoute: typeof ParamsPsNamedChar123fooChar125suffixRoute ParamsPsWildcardSplatRoute: typeof ParamsPsWildcardSplatRoute @@ -1125,13 +1118,6 @@ export interface RootRouteChildren { declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/(group)': { - id: '/(group)' - path: '/' - fullPath: '/' - preLoaderRoute: typeof groupRouteImport - parentRoute: typeof rootRouteImport - } '/대한민국': { id: '/대한민국' path: '/대한민국' @@ -1291,21 +1277,21 @@ declare module '@tanstack/react-router' { path: '/lazyinside' fullPath: '/lazyinside' preLoaderRoute: typeof groupLazyinsideRouteImport - parentRoute: typeof groupRoute + parentRoute: typeof rootRouteImport } '/(group)/inside': { id: '/(group)/inside' path: '/inside' fullPath: '/inside' preLoaderRoute: typeof groupInsideRouteImport - parentRoute: typeof groupRoute + parentRoute: typeof rootRouteImport } '/(group)/_layout': { id: '/(group)/_layout' - path: '/' - fullPath: '/' + path: '' + fullPath: '' preLoaderRoute: typeof groupLayoutRouteImport - parentRoute: typeof groupRoute + parentRoute: typeof rootRouteImport } '/(another-group)/onlyrouteinside': { id: '/(another-group)/onlyrouteinside' @@ -1515,7 +1501,7 @@ declare module '@tanstack/react-router' { path: '/subfolder/inside' fullPath: '/subfolder/inside' preLoaderRoute: typeof groupSubfolderInsideRouteImport - parentRoute: typeof groupRoute + parentRoute: typeof rootRouteImport } '/(group)/_layout/insidelayout': { id: '/(group)/_layout/insidelayout' @@ -2029,22 +2015,6 @@ const groupLayoutRouteWithChildren = groupLayoutRoute._addFileChildren( groupLayoutRouteChildren, ) -interface groupRouteChildren { - groupLayoutRoute: typeof groupLayoutRouteWithChildren - groupInsideRoute: typeof groupInsideRoute - groupLazyinsideRoute: typeof groupLazyinsideRoute - groupSubfolderInsideRoute: typeof groupSubfolderInsideRoute -} - -const groupRouteChildren: groupRouteChildren = { - groupLayoutRoute: groupLayoutRouteWithChildren, - groupInsideRoute: groupInsideRoute, - groupLazyinsideRoute: groupLazyinsideRoute, - groupSubfolderInsideRoute: groupSubfolderInsideRoute, -} - -const groupRouteWithChildren = groupRoute._addFileChildren(groupRouteChildren) - interface RedirectTargetRouteChildren { RedirectTargetViaBeforeLoadRoute: typeof RedirectTargetViaBeforeLoadRoute RedirectTargetViaLoaderRoute: typeof RedirectTargetViaLoaderRoute @@ -2106,13 +2076,16 @@ const rootRouteChildren: RootRouteChildren = { RelativeLinkRouteRoute: RelativeLinkRouteRouteWithChildren, RelativeUseNavigateRouteRoute: RelativeUseNavigateRouteRouteWithChildren, anotherGroupOnlyrouteinsideRoute: anotherGroupOnlyrouteinsideRoute, - groupRoute: groupRouteWithChildren, + groupLayoutRoute: groupLayoutRouteWithChildren, + groupInsideRoute: groupInsideRoute, + groupLazyinsideRoute: groupLazyinsideRoute, RedirectTargetRoute: RedirectTargetRouteWithChildren, StructuralSharingEnabledRoute: StructuralSharingEnabledRoute, ParamsPsIndexRoute: ParamsPsIndexRoute, RedirectIndexRoute: RedirectIndexRoute, RelativeIndexRoute: RelativeIndexRoute, ParamsPsNamedFooRouteRoute: ParamsPsNamedFooRouteRouteWithChildren, + groupSubfolderInsideRoute: groupSubfolderInsideRoute, ParamsPsNamedPrefixChar123fooChar125Route: ParamsPsNamedPrefixChar123fooChar125Route, ParamsPsNamedChar123fooChar125suffixRoute: diff --git a/e2e/solid-router/basic-file-based/src/routeTree.gen.ts b/e2e/solid-router/basic-file-based/src/routeTree.gen.ts index 1dab293d2e0..d9f29a8451f 100644 --- a/e2e/solid-router/basic-file-based/src/routeTree.gen.ts +++ b/e2e/solid-router/basic-file-based/src/routeTree.gen.ts @@ -8,8 +8,6 @@ // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. -import { createFileRoute } from '@tanstack/solid-router' - import { Route as rootRouteImport } from './routes/__root' import { Route as RemountDepsRouteImport } from './routes/remountDeps' import { Route as PostsRouteImport } from './routes/posts' @@ -90,12 +88,6 @@ import { Route as RelativeLinkPathPathIndexRouteImport } from './routes/relative import { Route as RelativeLinkNestedDeepIndexRouteImport } from './routes/relative/link/nested/deep/index' import { Route as ParamsPsNamedFooBarBazRouteImport } from './routes/params-ps/named/$foo/$bar.$baz' -const groupRouteImport = createFileRoute('/(group)')() - -const groupRoute = groupRouteImport.update({ - id: '/(group)', - getParentRoute: () => rootRouteImport, -} as any) const RemountDepsRoute = RemountDepsRouteImport.update({ id: '/remountDeps', path: '/remountDeps', @@ -196,19 +188,19 @@ const LayoutLayout2Route = LayoutLayout2RouteImport.update({ } as any) const groupLazyinsideRoute = groupLazyinsideRouteImport .update({ - id: '/lazyinside', + id: '/(group)/lazyinside', path: '/lazyinside', - getParentRoute: () => groupRoute, + getParentRoute: () => rootRouteImport, } as any) .lazy(() => import('./routes/(group)/lazyinside.lazy').then((d) => d.Route)) const groupInsideRoute = groupInsideRouteImport.update({ - id: '/inside', + id: '/(group)/inside', path: '/inside', - getParentRoute: () => groupRoute, + getParentRoute: () => rootRouteImport, } as any) const groupLayoutRoute = groupLayoutRouteImport.update({ - id: '/_layout', - getParentRoute: () => groupRoute, + id: '/(group)/_layout', + getParentRoute: () => rootRouteImport, } as any) const anotherGroupOnlyrouteinsideRoute = anotherGroupOnlyrouteinsideRouteImport.update({ @@ -328,9 +320,9 @@ const LayoutLayout2LayoutARoute = LayoutLayout2LayoutARouteImport.update({ getParentRoute: () => LayoutLayout2Route, } as any) const groupSubfolderInsideRoute = groupSubfolderInsideRouteImport.update({ - id: '/subfolder/inside', + id: '/(group)/subfolder/inside', path: '/subfolder/inside', - getParentRoute: () => groupRoute, + getParentRoute: () => rootRouteImport, } as any) const groupLayoutInsidelayoutRoute = groupLayoutInsidelayoutRouteImport.update({ id: '/insidelayout', @@ -512,7 +504,7 @@ const ParamsPsNamedFooBarBazRoute = ParamsPsNamedFooBarBazRouteImport.update({ } as any) export interface FileRoutesByFullPath { - '/': typeof groupLayoutRouteWithChildren + '/': typeof IndexRoute '/non-nested': typeof NonNestedRouteRouteWithChildren '/search-params': typeof SearchParamsRouteRouteWithChildren '/anchor': typeof AnchorRoute @@ -589,7 +581,7 @@ export interface FileRoutesByFullPath { '/relative/useNavigate/path/$path': typeof RelativeUseNavigatePathPathIndexRoute } export interface FileRoutesByTo { - '/': typeof groupLayoutRouteWithChildren + '/': typeof IndexRoute '/non-nested': typeof NonNestedRouteRouteWithChildren '/anchor': typeof AnchorRoute '/component-types-test': typeof ComponentTypesTestRoute @@ -679,7 +671,6 @@ export interface FileRoutesById { '/relative/link': typeof RelativeLinkRouteRouteWithChildren '/relative/useNavigate': typeof RelativeUseNavigateRouteRouteWithChildren '/(another-group)/onlyrouteinside': typeof anotherGroupOnlyrouteinsideRoute - '/(group)': typeof groupRouteWithChildren '/(group)/_layout': typeof groupLayoutRouteWithChildren '/(group)/inside': typeof groupInsideRoute '/(group)/lazyinside': typeof groupLazyinsideRoute @@ -909,7 +900,6 @@ export interface FileRouteTypes { | '/relative/link' | '/relative/useNavigate' | '/(another-group)/onlyrouteinside' - | '/(group)' | '/(group)/_layout' | '/(group)/inside' | '/(group)/lazyinside' @@ -987,12 +977,15 @@ export interface RootRouteChildren { RelativeLinkRouteRoute: typeof RelativeLinkRouteRouteWithChildren RelativeUseNavigateRouteRoute: typeof RelativeUseNavigateRouteRouteWithChildren anotherGroupOnlyrouteinsideRoute: typeof anotherGroupOnlyrouteinsideRoute - groupRoute: typeof groupRouteWithChildren + groupLayoutRoute: typeof groupLayoutRouteWithChildren + groupInsideRoute: typeof groupInsideRoute + groupLazyinsideRoute: typeof groupLazyinsideRoute RedirectTargetRoute: typeof RedirectTargetRouteWithChildren ParamsPsIndexRoute: typeof ParamsPsIndexRoute RedirectIndexRoute: typeof RedirectIndexRoute RelativeIndexRoute: typeof RelativeIndexRoute ParamsPsNamedFooRouteRoute: typeof ParamsPsNamedFooRouteRouteWithChildren + groupSubfolderInsideRoute: typeof groupSubfolderInsideRoute ParamsSingleValueRoute: typeof ParamsSingleValueRoute PostsPostIdEditRoute: typeof PostsPostIdEditRoute RedirectPreloadFirstRoute: typeof RedirectPreloadFirstRoute @@ -1002,13 +995,6 @@ export interface RootRouteChildren { declare module '@tanstack/solid-router' { interface FileRoutesByPath { - '/(group)': { - id: '/(group)' - path: '/' - fullPath: '/' - preLoaderRoute: typeof groupRouteImport - parentRoute: typeof rootRouteImport - } '/remountDeps': { id: '/remountDeps' path: '/remountDeps' @@ -1154,21 +1140,21 @@ declare module '@tanstack/solid-router' { path: '/lazyinside' fullPath: '/lazyinside' preLoaderRoute: typeof groupLazyinsideRouteImport - parentRoute: typeof groupRoute + parentRoute: typeof rootRouteImport } '/(group)/inside': { id: '/(group)/inside' path: '/inside' fullPath: '/inside' preLoaderRoute: typeof groupInsideRouteImport - parentRoute: typeof groupRoute + parentRoute: typeof rootRouteImport } '/(group)/_layout': { id: '/(group)/_layout' - path: '/' - fullPath: '/' + path: '' + fullPath: '' preLoaderRoute: typeof groupLayoutRouteImport - parentRoute: typeof groupRoute + parentRoute: typeof rootRouteImport } '/(another-group)/onlyrouteinside': { id: '/(another-group)/onlyrouteinside' @@ -1329,7 +1315,7 @@ declare module '@tanstack/solid-router' { path: '/subfolder/inside' fullPath: '/subfolder/inside' preLoaderRoute: typeof groupSubfolderInsideRouteImport - parentRoute: typeof groupRoute + parentRoute: typeof rootRouteImport } '/(group)/_layout/insidelayout': { id: '/(group)/_layout/insidelayout' @@ -1843,22 +1829,6 @@ const groupLayoutRouteWithChildren = groupLayoutRoute._addFileChildren( groupLayoutRouteChildren, ) -interface groupRouteChildren { - groupLayoutRoute: typeof groupLayoutRouteWithChildren - groupInsideRoute: typeof groupInsideRoute - groupLazyinsideRoute: typeof groupLazyinsideRoute - groupSubfolderInsideRoute: typeof groupSubfolderInsideRoute -} - -const groupRouteChildren: groupRouteChildren = { - groupLayoutRoute: groupLayoutRouteWithChildren, - groupInsideRoute: groupInsideRoute, - groupLazyinsideRoute: groupLazyinsideRoute, - groupSubfolderInsideRoute: groupSubfolderInsideRoute, -} - -const groupRouteWithChildren = groupRoute._addFileChildren(groupRouteChildren) - interface RedirectTargetRouteChildren { RedirectTargetViaBeforeLoadRoute: typeof RedirectTargetViaBeforeLoadRoute RedirectTargetViaLoaderRoute: typeof RedirectTargetViaLoaderRoute @@ -1918,12 +1888,15 @@ const rootRouteChildren: RootRouteChildren = { RelativeLinkRouteRoute: RelativeLinkRouteRouteWithChildren, RelativeUseNavigateRouteRoute: RelativeUseNavigateRouteRouteWithChildren, anotherGroupOnlyrouteinsideRoute: anotherGroupOnlyrouteinsideRoute, - groupRoute: groupRouteWithChildren, + groupLayoutRoute: groupLayoutRouteWithChildren, + groupInsideRoute: groupInsideRoute, + groupLazyinsideRoute: groupLazyinsideRoute, RedirectTargetRoute: RedirectTargetRouteWithChildren, ParamsPsIndexRoute: ParamsPsIndexRoute, RedirectIndexRoute: RedirectIndexRoute, RelativeIndexRoute: RelativeIndexRoute, ParamsPsNamedFooRouteRoute: ParamsPsNamedFooRouteRouteWithChildren, + groupSubfolderInsideRoute: groupSubfolderInsideRoute, ParamsSingleValueRoute: ParamsSingleValueRoute, PostsPostIdEditRoute: PostsPostIdEditRoute, RedirectPreloadFirstRoute: RedirectPreloadFirstRoute, diff --git a/packages/router-generator/src/generator.ts b/packages/router-generator/src/generator.ts index 956b1f7a4ec..13e483b5365 100644 --- a/packages/router-generator/src/generator.ts +++ b/packages/router-generator/src/generator.ts @@ -33,6 +33,7 @@ import { removeGroups, removeLastSegmentFromPath, removeLayoutSegments, + removeTrailingSlash, removeUnderscores, replaceBackslash, resetRegex, @@ -1223,6 +1224,13 @@ ${acc.routeTree.map((child) => `${child.variableName}Route: typeof ${getResolved removeUnderscores(removeLayoutSegments(node.path)) ?? '', ) + if ( + node._fsRouteType === 'layout' || + node._fsRouteType === 'pathless_layout' + ) { + node.cleanedPath = removeTrailingSlash(node.cleanedPath) + } + if ( !node.isVirtual && ( diff --git a/packages/router-generator/tests/generator/nested-route-groups-with-layouts-before-physical/routeTree.snapshot.ts b/packages/router-generator/tests/generator/nested-route-groups-with-layouts-before-physical/routeTree.snapshot.ts index a3b5c3f72fa..6c5c9950b22 100644 --- a/packages/router-generator/tests/generator/nested-route-groups-with-layouts-before-physical/routeTree.snapshot.ts +++ b/packages/router-generator/tests/generator/nested-route-groups-with-layouts-before-physical/routeTree.snapshot.ts @@ -8,8 +8,6 @@ // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. -import { createFileRoute } from '@tanstack/react-router' - import { Route as rootRouteImport } from './routes/__root' import { Route as groupCLayoutCRouteImport } from './routes/(group-c)/_layout-c' import { Route as groupBLayoutBRouteImport } from './routes/(group-b)/_layout-b' @@ -19,33 +17,17 @@ import { Route as groupBLayoutBDashboardRouteImport } from './routes/(group-b)/_ import { Route as groupALayoutASignupRouteImport } from './routes/(group-a)/_layout-a/signup' import { Route as groupALayoutALoginRouteImport } from './routes/(group-a)/_layout-a/login' -const groupCRouteImport = createFileRoute('/(group-c)')() -const groupBRouteImport = createFileRoute('/(group-b)')() -const groupARouteImport = createFileRoute('/(group-a)')() - -const groupCRoute = groupCRouteImport.update({ - id: '/(group-c)', - getParentRoute: () => rootRouteImport, -} as any) -const groupBRoute = groupBRouteImport.update({ - id: '/(group-b)', - getParentRoute: () => rootRouteImport, -} as any) -const groupARoute = groupARouteImport.update({ - id: '/(group-a)', - getParentRoute: () => rootRouteImport, -} as any) const groupCLayoutCRoute = groupCLayoutCRouteImport.update({ - id: '/_layout-c', - getParentRoute: () => groupCRoute, + id: '/(group-c)/_layout-c', + getParentRoute: () => rootRouteImport, } as any) const groupBLayoutBRoute = groupBLayoutBRouteImport.update({ - id: '/_layout-b', - getParentRoute: () => groupBRoute, + id: '/(group-b)/_layout-b', + getParentRoute: () => rootRouteImport, } as any) const groupALayoutARoute = groupALayoutARouteImport.update({ - id: '/_layout-a', - getParentRoute: () => groupARoute, + id: '/(group-a)/_layout-a', + getParentRoute: () => rootRouteImport, } as any) const groupCLayoutCIndexRoute = groupCLayoutCIndexRouteImport.update({ id: '/', @@ -69,24 +51,21 @@ const groupALayoutALoginRoute = groupALayoutALoginRouteImport.update({ } as any) export interface FileRoutesByFullPath { - '/': typeof groupCLayoutCIndexRoute '/login': typeof groupALayoutALoginRoute '/signup': typeof groupALayoutASignupRoute '/dashboard': typeof groupBLayoutBDashboardRoute + '/': typeof groupCLayoutCIndexRoute } export interface FileRoutesByTo { - '/': typeof groupCLayoutCIndexRoute '/login': typeof groupALayoutALoginRoute '/signup': typeof groupALayoutASignupRoute '/dashboard': typeof groupBLayoutBDashboardRoute + '/': typeof groupCLayoutCIndexRoute } export interface FileRoutesById { __root__: typeof rootRouteImport - '/(group-a)': typeof groupARouteWithChildren '/(group-a)/_layout-a': typeof groupALayoutARouteWithChildren - '/(group-b)': typeof groupBRouteWithChildren '/(group-b)/_layout-b': typeof groupBLayoutBRouteWithChildren - '/(group-c)': typeof groupCRouteWithChildren '/(group-c)/_layout-c': typeof groupCLayoutCRouteWithChildren '/(group-a)/_layout-a/login': typeof groupALayoutALoginRoute '/(group-a)/_layout-a/signup': typeof groupALayoutASignupRoute @@ -95,16 +74,13 @@ export interface FileRoutesById { } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: '/' | '/login' | '/signup' | '/dashboard' + fullPaths: '/login' | '/signup' | '/dashboard' | '/' fileRoutesByTo: FileRoutesByTo - to: '/' | '/login' | '/signup' | '/dashboard' + to: '/login' | '/signup' | '/dashboard' | '/' id: | '__root__' - | '/(group-a)' | '/(group-a)/_layout-a' - | '/(group-b)' | '/(group-b)/_layout-b' - | '/(group-c)' | '/(group-c)/_layout-c' | '/(group-a)/_layout-a/login' | '/(group-a)/_layout-a/signup' @@ -113,54 +89,33 @@ export interface FileRouteTypes { fileRoutesById: FileRoutesById } export interface RootRouteChildren { - groupARoute: typeof groupARouteWithChildren - groupBRoute: typeof groupBRouteWithChildren - groupCRoute: typeof groupCRouteWithChildren + groupALayoutARoute: typeof groupALayoutARouteWithChildren + groupBLayoutBRoute: typeof groupBLayoutBRouteWithChildren + groupCLayoutCRoute: typeof groupCLayoutCRouteWithChildren } declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/(group-c)': { - id: '/(group-c)' - path: '/' - fullPath: '/' - preLoaderRoute: typeof groupCRouteImport - parentRoute: typeof rootRouteImport - } - '/(group-b)': { - id: '/(group-b)' - path: '/' - fullPath: '/' - preLoaderRoute: typeof groupBRouteImport - parentRoute: typeof rootRouteImport - } - '/(group-a)': { - id: '/(group-a)' - path: '/' - fullPath: '/' - preLoaderRoute: typeof groupARouteImport - parentRoute: typeof rootRouteImport - } '/(group-c)/_layout-c': { id: '/(group-c)/_layout-c' - path: '/' - fullPath: '/' + path: '' + fullPath: '' preLoaderRoute: typeof groupCLayoutCRouteImport - parentRoute: typeof groupCRoute + parentRoute: typeof rootRouteImport } '/(group-b)/_layout-b': { id: '/(group-b)/_layout-b' - path: '/' - fullPath: '/' + path: '' + fullPath: '' preLoaderRoute: typeof groupBLayoutBRouteImport - parentRoute: typeof groupBRoute + parentRoute: typeof rootRouteImport } '/(group-a)/_layout-a': { id: '/(group-a)/_layout-a' - path: '/' - fullPath: '/' + path: '' + fullPath: '' preLoaderRoute: typeof groupALayoutARouteImport - parentRoute: typeof groupARoute + parentRoute: typeof rootRouteImport } '/(group-c)/_layout-c/': { id: '/(group-c)/_layout-c/' @@ -207,17 +162,6 @@ const groupALayoutARouteWithChildren = groupALayoutARoute._addFileChildren( groupALayoutARouteChildren, ) -interface groupARouteChildren { - groupALayoutARoute: typeof groupALayoutARouteWithChildren -} - -const groupARouteChildren: groupARouteChildren = { - groupALayoutARoute: groupALayoutARouteWithChildren, -} - -const groupARouteWithChildren = - groupARoute._addFileChildren(groupARouteChildren) - interface groupBLayoutBRouteChildren { groupBLayoutBDashboardRoute: typeof groupBLayoutBDashboardRoute } @@ -230,17 +174,6 @@ const groupBLayoutBRouteWithChildren = groupBLayoutBRoute._addFileChildren( groupBLayoutBRouteChildren, ) -interface groupBRouteChildren { - groupBLayoutBRoute: typeof groupBLayoutBRouteWithChildren -} - -const groupBRouteChildren: groupBRouteChildren = { - groupBLayoutBRoute: groupBLayoutBRouteWithChildren, -} - -const groupBRouteWithChildren = - groupBRoute._addFileChildren(groupBRouteChildren) - interface groupCLayoutCRouteChildren { groupCLayoutCIndexRoute: typeof groupCLayoutCIndexRoute } @@ -253,21 +186,10 @@ const groupCLayoutCRouteWithChildren = groupCLayoutCRoute._addFileChildren( groupCLayoutCRouteChildren, ) -interface groupCRouteChildren { - groupCLayoutCRoute: typeof groupCLayoutCRouteWithChildren -} - -const groupCRouteChildren: groupCRouteChildren = { - groupCLayoutCRoute: groupCLayoutCRouteWithChildren, -} - -const groupCRouteWithChildren = - groupCRoute._addFileChildren(groupCRouteChildren) - const rootRouteChildren: RootRouteChildren = { - groupARoute: groupARouteWithChildren, - groupBRoute: groupBRouteWithChildren, - groupCRoute: groupCRouteWithChildren, + groupALayoutARoute: groupALayoutARouteWithChildren, + groupBLayoutBRoute: groupBLayoutBRouteWithChildren, + groupCLayoutCRoute: groupCLayoutCRouteWithChildren, } export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) diff --git a/packages/router-generator/tests/generator/path-above-route-in-group/routeTree.snapshot.ts b/packages/router-generator/tests/generator/path-above-route-in-group/routeTree.snapshot.ts index 1c216c5bcd4..c937f95ba87 100644 --- a/packages/router-generator/tests/generator/path-above-route-in-group/routeTree.snapshot.ts +++ b/packages/router-generator/tests/generator/path-above-route-in-group/routeTree.snapshot.ts @@ -10,13 +10,19 @@ import { Route as rootRouteImport } from './routes/__root' import { Route as ABcRouteRouteImport } from './routes/a/$b/(c)/route' +import { Route as ABcIndexRouteImport } from './routes/a/$b/(c)/index' import { Route as ABcDEIndexRouteImport } from './routes/a/$b/(c)/d/e/index' const ABcRouteRoute = ABcRouteRouteImport.update({ id: '/a/$b/(c)', - path: '/a/$b/', + path: '/a/$b', getParentRoute: () => rootRouteImport, } as any) +const ABcIndexRoute = ABcIndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => ABcRouteRoute, +} as any) const ABcDEIndexRoute = ABcDEIndexRouteImport.update({ id: '/d/e/', path: '/d/e/', @@ -25,23 +31,25 @@ const ABcDEIndexRoute = ABcDEIndexRouteImport.update({ export interface FileRoutesByFullPath { '/a/$b': typeof ABcRouteRouteWithChildren + '/a/$b/': typeof ABcIndexRoute '/a/$b/d/e': typeof ABcDEIndexRoute } export interface FileRoutesByTo { - '/a/$b': typeof ABcRouteRouteWithChildren + '/a/$b': typeof ABcIndexRoute '/a/$b/d/e': typeof ABcDEIndexRoute } export interface FileRoutesById { __root__: typeof rootRouteImport '/a/$b/(c)': typeof ABcRouteRouteWithChildren + '/a/$b/(c)/': typeof ABcIndexRoute '/a/$b/(c)/d/e/': typeof ABcDEIndexRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: '/a/$b' | '/a/$b/d/e' + fullPaths: '/a/$b' | '/a/$b/' | '/a/$b/d/e' fileRoutesByTo: FileRoutesByTo to: '/a/$b' | '/a/$b/d/e' - id: '__root__' | '/a/$b/(c)' | '/a/$b/(c)/d/e/' + id: '__root__' | '/a/$b/(c)' | '/a/$b/(c)/' | '/a/$b/(c)/d/e/' fileRoutesById: FileRoutesById } export interface RootRouteChildren { @@ -57,6 +65,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ABcRouteRouteImport parentRoute: typeof rootRouteImport } + '/a/$b/(c)/': { + id: '/a/$b/(c)/' + path: '/' + fullPath: '/a/$b/' + preLoaderRoute: typeof ABcIndexRouteImport + parentRoute: typeof ABcRouteRoute + } '/a/$b/(c)/d/e/': { id: '/a/$b/(c)/d/e/' path: '/d/e' @@ -68,10 +83,12 @@ declare module '@tanstack/react-router' { } interface ABcRouteRouteChildren { + ABcIndexRoute: typeof ABcIndexRoute ABcDEIndexRoute: typeof ABcDEIndexRoute } const ABcRouteRouteChildren: ABcRouteRouteChildren = { + ABcIndexRoute: ABcIndexRoute, ABcDEIndexRoute: ABcDEIndexRoute, } diff --git a/packages/router-generator/tests/generator/path-above-route-in-group/routes/a/$b/(c)/index.tsx b/packages/router-generator/tests/generator/path-above-route-in-group/routes/a/$b/(c)/index.tsx new file mode 100644 index 00000000000..8fdf4681aef --- /dev/null +++ b/packages/router-generator/tests/generator/path-above-route-in-group/routes/a/$b/(c)/index.tsx @@ -0,0 +1,5 @@ +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/a/$b/(c)/')({ + component: () =>
Hello /a/$b/(c) index
, +}) diff --git a/packages/router-generator/tests/generator/route-groups/routeTree.snapshot.ts b/packages/router-generator/tests/generator/route-groups/routeTree.snapshot.ts index bf4addbd35f..f1d7057fd68 100644 --- a/packages/router-generator/tests/generator/route-groups/routeTree.snapshot.ts +++ b/packages/router-generator/tests/generator/route-groups/routeTree.snapshot.ts @@ -20,31 +20,19 @@ import { Route as fooAsdfanotherGroupLayoutRouteImport } from './routes/(foo)/as import { Route as fooAsdfbarLayoutAboutRouteImport } from './routes/(foo)/asdf/(bar)/_layout.about' import { Route as fooAsdfanotherGroupLayoutBazRouteImport } from './routes/(foo)/asdf/(another-group)/_layout.baz' -const barRouteImport = createFileRoute('/(bar)')() const fooAsdfRouteImport = createFileRoute('/(foo)/asdf')() -const fooAsdfanotherGroupRouteImport = createFileRoute( - '/(foo)/asdf/(another-group)', -)() const fooAsdfbarLayoutXyzLazyRouteImport = createFileRoute( '/(foo)/asdf/(bar)/_layout/xyz', )() -const barRoute = barRouteImport.update({ - id: '/(bar)', - getParentRoute: () => rootRouteImport, -} as any) const fooAsdfRoute = fooAsdfRouteImport.update({ id: '/(foo)/asdf', path: '/asdf', getParentRoute: () => rootRouteImport, } as any) const barBarRoute = barBarRouteImport.update({ - id: '/_bar', - getParentRoute: () => barRoute, -} as any) -const fooAsdfanotherGroupRoute = fooAsdfanotherGroupRouteImport.update({ - id: '/(another-group)', - getParentRoute: () => fooAsdfRoute, + id: '/(bar)/_bar', + getParentRoute: () => rootRouteImport, } as any) const fooAsdfLayoutRoute = fooAsdfLayoutRouteImport.update({ id: '/_layout', @@ -67,8 +55,8 @@ const fooAsdfbarIdRoute = fooAsdfbarIdRouteImport.update({ } as any) const fooAsdfanotherGroupLayoutRoute = fooAsdfanotherGroupLayoutRouteImport.update({ - id: '/_layout', - getParentRoute: () => fooAsdfanotherGroupRoute, + id: '/(another-group)/_layout', + getParentRoute: () => fooAsdfRoute, } as any) const fooAsdfbarLayoutXyzLazyRoute = fooAsdfbarLayoutXyzLazyRouteImport .update({ @@ -92,10 +80,8 @@ const fooAsdfanotherGroupLayoutBazRoute = } as any) export interface FileRoutesByFullPath { - '/': typeof barBarRouteWithChildren '/hello': typeof barBarHelloRoute - '/asdf': typeof fooAsdfLayoutRouteWithChildren - '/asdf/': typeof fooAsdfanotherGroupLayoutRouteWithChildren + '/asdf': typeof fooAsdfanotherGroupLayoutRouteWithChildren '/asdf/$id': typeof fooAsdfbarIdRoute '/asdf/foo': typeof fooAsdfLayoutFooRoute '/asdf/baz': typeof fooAsdfanotherGroupLayoutBazRoute @@ -103,7 +89,6 @@ export interface FileRoutesByFullPath { '/asdf/xyz': typeof fooAsdfbarLayoutXyzLazyRoute } export interface FileRoutesByTo { - '/': typeof barBarRouteWithChildren '/hello': typeof barBarHelloRoute '/asdf': typeof fooAsdfanotherGroupLayoutRouteWithChildren '/asdf/$id': typeof fooAsdfbarIdRoute @@ -114,12 +99,10 @@ export interface FileRoutesByTo { } export interface FileRoutesById { __root__: typeof rootRouteImport - '/(bar)': typeof barRouteWithChildren '/(bar)/_bar': typeof barBarRouteWithChildren '/(bar)/_bar/hello': typeof barBarHelloRoute '/(foo)/asdf': typeof fooAsdfRouteWithChildren '/(foo)/asdf/_layout': typeof fooAsdfLayoutRouteWithChildren - '/(foo)/asdf/(another-group)': typeof fooAsdfanotherGroupRouteWithChildren '/(foo)/asdf/(another-group)/_layout': typeof fooAsdfanotherGroupLayoutRouteWithChildren '/(foo)/asdf/(bar)/$id': typeof fooAsdfbarIdRoute '/(foo)/asdf/_layout/foo': typeof fooAsdfLayoutFooRoute @@ -130,10 +113,8 @@ export interface FileRoutesById { export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath fullPaths: - | '/' | '/hello' | '/asdf' - | '/asdf/' | '/asdf/$id' | '/asdf/foo' | '/asdf/baz' @@ -141,7 +122,6 @@ export interface FileRouteTypes { | '/asdf/xyz' fileRoutesByTo: FileRoutesByTo to: - | '/' | '/hello' | '/asdf' | '/asdf/$id' @@ -151,12 +131,10 @@ export interface FileRouteTypes { | '/asdf/xyz' id: | '__root__' - | '/(bar)' | '/(bar)/_bar' | '/(bar)/_bar/hello' | '/(foo)/asdf' | '/(foo)/asdf/_layout' - | '/(foo)/asdf/(another-group)' | '/(foo)/asdf/(another-group)/_layout' | '/(foo)/asdf/(bar)/$id' | '/(foo)/asdf/_layout/foo' @@ -166,19 +144,12 @@ export interface FileRouteTypes { fileRoutesById: FileRoutesById } export interface RootRouteChildren { - barRoute: typeof barRouteWithChildren + barBarRoute: typeof barBarRouteWithChildren fooAsdfRoute: typeof fooAsdfRouteWithChildren } declare module '@tanstack/react-router' { interface FileRoutesByPath { - '/(bar)': { - id: '/(bar)' - path: '/' - fullPath: '/' - preLoaderRoute: typeof barRouteImport - parentRoute: typeof rootRouteImport - } '/(foo)/asdf': { id: '/(foo)/asdf' path: '/asdf' @@ -188,17 +159,10 @@ declare module '@tanstack/react-router' { } '/(bar)/_bar': { id: '/(bar)/_bar' - path: '/' - fullPath: '/' + path: '' + fullPath: '' preLoaderRoute: typeof barBarRouteImport - parentRoute: typeof barRoute - } - '/(foo)/asdf/(another-group)': { - id: '/(foo)/asdf/(another-group)' - path: '/' - fullPath: '/asdf/' - preLoaderRoute: typeof fooAsdfanotherGroupRouteImport - parentRoute: typeof fooAsdfRoute + parentRoute: typeof rootRouteImport } '/(foo)/asdf/_layout': { id: '/(foo)/asdf/_layout' @@ -230,10 +194,10 @@ declare module '@tanstack/react-router' { } '/(foo)/asdf/(another-group)/_layout': { id: '/(foo)/asdf/(another-group)/_layout' - path: '/' - fullPath: '/asdf/' + path: '' + fullPath: '/asdf' preLoaderRoute: typeof fooAsdfanotherGroupLayoutRouteImport - parentRoute: typeof fooAsdfanotherGroupRoute + parentRoute: typeof fooAsdfRoute } '/(foo)/asdf/(bar)/_layout/xyz': { id: '/(foo)/asdf/(bar)/_layout/xyz' @@ -270,16 +234,6 @@ const barBarRouteChildren: barBarRouteChildren = { const barBarRouteWithChildren = barBarRoute._addFileChildren(barBarRouteChildren) -interface barRouteChildren { - barBarRoute: typeof barBarRouteWithChildren -} - -const barRouteChildren: barRouteChildren = { - barBarRoute: barBarRouteWithChildren, -} - -const barRouteWithChildren = barRoute._addFileChildren(barRouteChildren) - interface fooAsdfLayoutRouteChildren { fooAsdfLayoutFooRoute: typeof fooAsdfLayoutFooRoute } @@ -306,20 +260,9 @@ const fooAsdfanotherGroupLayoutRouteWithChildren = fooAsdfanotherGroupLayoutRouteChildren, ) -interface fooAsdfanotherGroupRouteChildren { - fooAsdfanotherGroupLayoutRoute: typeof fooAsdfanotherGroupLayoutRouteWithChildren -} - -const fooAsdfanotherGroupRouteChildren: fooAsdfanotherGroupRouteChildren = { - fooAsdfanotherGroupLayoutRoute: fooAsdfanotherGroupLayoutRouteWithChildren, -} - -const fooAsdfanotherGroupRouteWithChildren = - fooAsdfanotherGroupRoute._addFileChildren(fooAsdfanotherGroupRouteChildren) - interface fooAsdfRouteChildren { fooAsdfLayoutRoute: typeof fooAsdfLayoutRouteWithChildren - fooAsdfanotherGroupRoute: typeof fooAsdfanotherGroupRouteWithChildren + fooAsdfanotherGroupLayoutRoute: typeof fooAsdfanotherGroupLayoutRouteWithChildren fooAsdfbarIdRoute: typeof fooAsdfbarIdRoute fooAsdfbarLayoutAboutRoute: typeof fooAsdfbarLayoutAboutRoute fooAsdfbarLayoutXyzLazyRoute: typeof fooAsdfbarLayoutXyzLazyRoute @@ -327,7 +270,7 @@ interface fooAsdfRouteChildren { const fooAsdfRouteChildren: fooAsdfRouteChildren = { fooAsdfLayoutRoute: fooAsdfLayoutRouteWithChildren, - fooAsdfanotherGroupRoute: fooAsdfanotherGroupRouteWithChildren, + fooAsdfanotherGroupLayoutRoute: fooAsdfanotherGroupLayoutRouteWithChildren, fooAsdfbarIdRoute: fooAsdfbarIdRoute, fooAsdfbarLayoutAboutRoute: fooAsdfbarLayoutAboutRoute, fooAsdfbarLayoutXyzLazyRoute: fooAsdfbarLayoutXyzLazyRoute, @@ -337,7 +280,7 @@ const fooAsdfRouteWithChildren = fooAsdfRoute._addFileChildren(fooAsdfRouteChildren) const rootRouteChildren: RootRouteChildren = { - barRoute: barRouteWithChildren, + barBarRoute: barBarRouteWithChildren, fooAsdfRoute: fooAsdfRouteWithChildren, } export const routeTree = rootRouteImport