remix-flat-routes
remix-flat-routes copied to clipboard
Issue with the use of multiple dynamic routes
We have a use case where we have multiple dynamics routes for different parents and want split it into distinct folders. for instance:
/nodes/$nodeId
/schedules/$scheduleId
The problem is that it will render the first one alphabetically (from what we can see) but when navigating to the schedules ID page it will route to the node ID page but still try to render the Schedules ID page and error out. Can someone explain why this would be the case?
It works when we use the flat structure: schedules_.$scheduleId but when splitting into the folder structure below we get the problems stated.
Our folder structure is as so:
Hmm... this route structure seems odd.
Remember, with hybrid routes, the /+
is replaced with .
to the equivalent flat-files convention.
_nodes+/$nodeId+/$nodeId.tsx => _nodes.$nodeId.$nodeId.tsx
_schedules+/$scheduleId+/$scheduleId.tsx => _schedules.$scheduleId.$scheduleId.tsx
I'm guessing your intention here, but this is how I think the routes should be.
❯ tree app/routes
app/routes
├── nodes+
│ ├── $nodeId.tsx /nodes/:nodeId (with _layout)
│ ├── _.$nodeId.calls.tsx /nodes/:nodeId/calls (without _layout)
│ ├── _.add.tsx /nodes/add (without _layout)
│ └── _layout.tsx layout for /nodes/*
└── schedules+
├── $scheduleId.tsx /schedules/:scheduleId (with _layout)
├── _layout.tsx layout for /schedules/*
├── delete.tsx /schedules/delete (with _layout)
├── history.tsx /schedules/history (with _layout)
└── new.tsx /schedules/new (with _layout)
<Routes>
<Route file="root.tsx">
<Route path="nodes/:nodeId/calls" file="routes/nodes+/_.$nodeId.calls.tsx" />
<Route path="nodes/add" file="routes/nodes+/_.add.tsx" />
<Route path="nodes" file="routes/nodes+/_layout.tsx">
<Route path=":nodeId" file="routes/nodes+/$nodeId.tsx" />
</Route>
<Route path="schedules" file="routes/schedules+/_layout.tsx">
<Route path=":scheduleId" file="routes/schedules+/$scheduleId.tsx" />
<Route path="delete" file="routes/schedules+/delete.tsx" />
<Route path="history" file="routes/schedules+/history.tsx" />
<Route path="new" file="routes/schedules+/new.tsx" />
</Route>
</Route>
</Routes>
Notes:
The _
prefix is a pathless route, so will not be included in the URL. But your examples show you want /nodes
and /schedules
, so I removed the leading _
.
Your example also had routes with duplicate params. $nodeId+/$nodeId
is treated as :nodeId/:nodeId
which doesn't make sense. I'm surprised Remix doesn't throw an error as this is technically an invalid route. Remember, with params, Remix will match any text for that segment. Since you technically had 2 routes with :param/:param
, Remix matched any URL that was /anything/something
to the :nodeId/:nodeId
route (the first defined route).
nodes+/_layout.tsx
is equivalent to nodes.tsx
and is the parent layout for all /nodes/*
routes.
The nodes+/_.
prefix is like adding the _
suffix to the parent layout to opt out. nodes+/_.add.tsx
is equivalent to nodes_.add.tsx
Thanks for your help! Has cleared some misunderstandings we were having.
No problem. Reach out if you need further assistance.