T
TanStack2y ago
tame-yellow

File System Routing: Multiple levels of nesting in a single directory

Hi, I have an application that for most urls has three levels of path params. Something like this: myapp.com/project/$projectName/environment/$environmentName/build/$buildVersion/... the rest of the url here Most of the application's pages go under this structure. Is there a way to specify multiple levels of nesting in a single file system directory? What I'd like is something like (where the : is equivalent to / in the url): -- __root.tsx -- project:$projectName:environment:$environmentName:build:$buildName ---- page1.tsx ---- page2.tsx etc. Currently, if I want to do this I am needing to create a bunch of nested folders and it gets kind of messy quickly. We need to include all this in the path so that it's human readable, and links can be shared between users etc. Thanks!
14 Replies
tame-yellow
tame-yellowOP2y ago
We may have to bite the bullet and switch to search params, but it feels like a UX concession bc the urls get less readable and ordered. After careful reading of the search params area of the docs, it does seem like the search params feature will be much better suited to handling this. Especially when it comes to dealing with missing or empty parameters.
tame-yellow
tame-yellowOP2y ago
Search Params | TanStack Router Docs
Similar to how TanStack Query made handling server-state in your React applications a breeze, TanStack Router aims to unlock the power of URL search params in your applications. Why not just use URLSearchParams?
tame-yellow
tame-yellowOP2y ago
I am still wishing there was a clean way to do this in the path though, as that's the URL UX we want to keep.
inland-turquoise
inland-turquoise2y ago
not sure I understand the initial question, but you can use dots in file/folder names like this project.$projectId to express nesting
tame-yellow
tame-yellowOP2y ago
oh nice! i didn't realize that applied to folders as well so, would this be a valid folder name:
project.$projectName.environment.$environmentName.build.$buildVersion
project.$projectName.environment.$environmentName.build.$buildVersion
inland-turquoise
inland-turquoise2y ago
it should. if it does not work, let me know please
inland-turquoise
inland-turquoise2y ago
works as expected
tame-yellow
tame-yellowOP2y ago
Ok that did work! So, one follow up Q... So this url works great:
/project/$projectName/environment/$environmentName/build/$buildVersion/wow
/project/$projectName/environment/$environmentName/build/$buildVersion/wow
But how would I handle something like this?
/project/$projectName/environment/$environmentName/wow
/project/$projectName/environment/$environmentName/wow
It seems like I'd need two distinct Route components that both render the same UI component and the UI component would probably need to have some kind of handling built in to deal with that missing param. Does that sound right?
inland-turquoise
inland-turquoise2y ago
sorry not clear what "wow" would do in comparison to the other one
tame-yellow
tame-yellowOP2y ago
So, the buildVersion is essentially an optional path in the URL
inland-turquoise
inland-turquoise2y ago
and what should be the render difference if it is specified ?
tame-yellow
tame-yellowOP2y ago
In our react-router implementation, when that parameter is missing we either: 1. Figure out the most recent build, and then redirect the user to the same path but with that path param added 2. If there's no builds, then we leave the path as is, and childen of that path evaluate the parameter and can determine what to do based on their specific UI So, for example, we have a menu component that shows a list of the user's builds and highlights the current build (whatever is in the path param). If it's not there, we either know 1. no build is selected and the ui shows that, 2. no builds are created and the ui shows that Since this single parameter is kind of variable, I'm wondering if it makes sense to move it to a search param.
inland-turquoise
inland-turquoise2y ago
sure you can move it to a search param especially if it is optional

Did you find this page helpful?