TanStack / router

🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
https://tanstack.com/router
MIT License
7.27k stars 495 forks source link

Pathless Routes within a Non-Nested Route include the Pathles Route path in the generated path #1064

Closed trainiac closed 2 months ago

trainiac commented 4 months ago

Describe the bug

I'm trying to create a pathless route underneath a non-nested route. The problem is that paths that are generated include the the pathless route path.

Your Example Website or App

https://stackblitz.com/edit/github-kmup2d?file=src%2Froutes%2F__root.tsx

Steps to Reproduce the Bug or Issue

Create the following folder structure

bugs
  index.tsx
bugs_
  _layout
    test
      index.tsx
  _layout.tsx

Expected behavior

Should generate the following links

But actually generates

Screenshots or Videos

No response

Platform

Additional context

No response

tannerlinsley commented 4 months ago

This is a known bug and doesn't really have an answer yet for v1. We have a fix slated internally for v2, but that's a ways off. Thank you for helping us find this!

trainiac commented 4 months ago

react-query is GOAT! Thank you

mattkauffman23 commented 3 months ago

Are pathless layouts inside of non-nested routes unsupported for now? Are there any approaches or workarounds to support a structure like:

- posts_
-- $postId
--- _post_layout
--- _post_layout.tsx
---- index.tsx
- posts
-- index.tsx

My goal here is to have distinct component trees for /posts/ and /posts/$postId/ and for /posts/$postId and its child routes to share a layout component. When I attempt this now the child routes of _post_layout include _post_layout in their URL path.

SeanCassiere commented 2 months ago

@trainiac I think this may have been inadvertently fixed in one of our previous releases since we've been on v1.

I've got a stackblitz box up with the issue you originally described, and it looks to be working: https://stackblitz.com/edit/github-kmup2d-mvdpeq?file=src%2Froutes%2F__root.tsx

If for whatever reason TS isn't playing well in the Stackblitz example, you can run it locally and confirm. Screenshot 2024-03-29 at 14 47 01

SeanCassiere commented 2 months ago

@mattkauffman23 your pathless route structure should be achievable using this structure: https://stackblitz.com/edit/github-dg2qur?file=src%2Froutes%2Fposts%2Findex.tsx

If you are still having trouble with this, please drop a question in our Discord channel.

SeanCassiere commented 2 months ago

I've tested this again and it looks to be working.

I'm closing this for now. If this crops up again, please either ping us for this issue to be reopened or create a new issue linking to this one.

eg-bernardo commented 1 month ago

It seems it doesn't work if a route.tsx file is used inside _layout folder instead of a _layout.tsx file at the same level of the folder. https://stackblitz.com/edit/github-dg2qur?file=src%2Froutes%2Fposts_%2F%24postId%2F_layout%2Froute.tsx

SeanCassiere commented 1 month ago

It seems it doesn't work if a route.tsx file is used inside _layout folder instead of a _layout.tsx file at the same level of the folder.

@eg-bernardo

When at the that's because at the same level,the order of evaluation would always be:

It couldn't be the other way around since you then open it up to the possiblity of having two route.tsx filed for a single route.

As such, the route.tsx couldn't be a child of a layout.

eg-bernardo commented 1 month ago

Sorry, I gave the wrong link: https://stackblitz.com/edit/github-dg2qur-glwfxx?file=src%2Froutes%2F__root.tsx,src%2Froutes%2Fposts_%2F%24postId%2F_layout%2Froute.tsx

The only change is renaming src/routes/posts_/$postId/_layout.tsx to src/routes/posts_/$postId/_layout/route.tsx, which according to this https://tanstack.com/router/latest/docs/framework/react/guide/code-splitting#encapsulating-a-routes-files-into-a-directory should be equivalent.

SeanCassiere commented 1 month ago

The only change is renaming src/routes/posts_/$postId/_layout.tsx to src/routes/posts_/$postId/_layout/route.tsx, which according to this https://tanstack.com/router/latest/docs/framework/react/guide/code-splitting#encapsulating-a-routes-files-into-a-directory should be equivalent.

@eg-bernardo this still applies. For pathless/layout routes, however, the mental model for it needs to be adjusted a bit, because of how routes are evaluated.

Currently, each file in the file-based routing structure maps to a node in the actual route tree. In essence, the files used for file-based routing map to an exact node in the code-based routing tree.

The route.tsx is used for creating a shared configuration that maps to an entire path. For example, src/routes/posts/route.tsx would have its configuration propagated to all its children, like posts/index.tsx, posts/$postId.tsx, posts/$postId/edit.tsx, etc...

What you are proposing on the other hand is to have the route.tsx live inside the _layout/ folder inside the /posts/. On a conceptual level this works, however, it practice it then raises a race condition should there be an actual route.tsx defined for posts.

The problem raised, is that it opens it up to the possibility of having two route.tsx configuration files for a single route. So, instead, we don't allow placing the route.tsx file for a path within the _layout folder.

FIle route Position in the route-tree
/posts/_layout/route.tsx /posts/route.tsx
/posts/route.tsx /posts/route.tsx
eg-bernardo commented 1 month ago

The route.tsx is used for creating a shared configuration that maps to an entire path. For example, src/routes/posts/route.tsx would have its configuration propagated to all its children, like posts/index.tsx, posts/$postId.tsx, posts/$postId/edit.tsx, etc...

The same applies to posts.tsx, that route will match for all the children ( posts/index.tsx, posts/$postId.tsx, posts/$postId/edit.tsx)

What you are proposing on the other hand is to have the route.tsx live inside the _layout/ folder inside the /posts/. On a conceptual level this works, however, it practice it then raises a race condition should there be an actual route.tsx defined for posts.

I'm not proposing, I'm just pointing out that based on my understanding of https://tanstack.com/router/latest/docs/framework/react/guide/code-splitting#encapsulating-a-routes-files-into-a-directory /posts/_layout.tsx and /posts/_layout/route.tsx should behave the same. It's just a different way of organizing the code.

Here's an example where it works as expected: https://stackblitz.com/edit/github-dg2qur-glwfxx?file=src%2Froutes%2F_auth%2Fprofile.tsx,src%2Froutes%2F_auth%2Froute.tsx,src%2Froutes%2F__root.tsx

SeanCassiere commented 1 month ago

I'm not proposing, I'm just pointing out that based on my understanding of https://tanstack.com/router/latest/docs/framework/react/guide/code-splitting#encapsulating-a-routes-files-into-a-directory /posts/_layout.tsx and /posts/_layout/route.tsx should behave the same. It's just a different way of organizing the code.

@eg-bernardo I understand that the documentation is lacking in this aspect.

Just to reiterate, you cannot have the route.tsx configuration for a route as a direct child of layout and is a child of said route.

If you can come up with the correct verbiage for stating this in the docs, I'd be happy to review and merge it in. If not, I'll come around to making this change sometime in the future when I have some bandwidth.

eg-bernardo commented 1 month ago

But my understanding is that _layout/route.tsx is the _layout route, not a child of it. If both _layout/route.tsx and _layout.tsx exist it should be an error.

In https://stackblitz.com/edit/github-dg2qur-glwfxx?file=src%2Froutes%2F_auth%2Fprofile.tsx,src%2Froutes%2F_auth%2Froute.tsx,src%2Froutes%2F__root.tsx _auth/route.tsx works as I expect. Are you saying that shouldn't work?

SeanCassiere commented 1 month ago

But my understanding is that _layout/route.tsx is the _layout route

No the configuration for everything under in the _layout/ directory would be done in _layout.tsx. There is no route.tsx for the _layout, that's entirely handled in the configuration of the layout route.

src/routes
  posts/
    $postId/
      _layout.tsx <- config happens here
      _layout/
        foo.tsx

_auth/route.tsx works as I expect. Are you saying that shouldn't work?

This looks to be bug/side-effect of the way things are set up. Not intended.