-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[V6] [Feature]: Support absolute paths in descendant <Routes>
#8035
Comments
I'm not sure if this makes sense. If you want to use your Users routes in multiple places, you wouldn't be able to. Not to mention Links/NavLinks would be harder to reason about. We treat the the route context that you render your Route within as a "basename" of sorts. That enables you to not have to worry about the context you're within when creating your Routes tree. It's easy enough to reason about absolute routes when they're all being rendered within the same component. But if you spread that out over different files or modules (or heck, even different repos), it becomes harder to keep track of it all. Realistically, this is less about the Users component and more about the App component. How does the App component know the Users routes aren't going to escape the path App thinks they are nested under? That might be surprising at best and error-inducing at worst. I could understand some sort of escape hatch API, such as an |
I agree that isolating each routing context will make the components more reusable and should probably be the preferred way of doing things. But I also see the use of having routes specified in one place which then can be used by both If this is not at all desired then I agree that an escape hatch might at least be a way ease the migration from v5 -> v6. Like stated here its somewhat common and quite a painful rewrite to do, but perhaps its necessary. Thank you for the great work that's being done here 👍 |
I've already been posting about this in #7972, but I agree, that this was probably the wrong place to mention this. Hopefully now I'm on the spot. The feature which @Patrik-Lundqvist is asking for, already existed in version Steps to reproduce:
With the branch |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
<Routes>
<Routes>
I agree that this is a necessary feature. Giving a If we want to use absolute paths, we have to do everything in the same component:
and we can't break it down into sub-routes components like this:
The use cases are: (1) We use constants for pathnames, to always guarantee a (2) In a large application, if a developer is told there's a bug in /some/old/obsucre/page, a simple text search for (3) We organise our app in modules, and code-split by module, and don't want to put everything in an enormous top-level |
It's exciting to see React Router reach v6. But...
I went all the way to upgrade my project to v6, but absolute path wouldn't work. |
I would love to get started to work on this. It would help me a lot if somebody can outline a broad idea how and where to implement this. |
We justified supporting absolute paths in nested route configs, seems like the same reasoning applies here. It would also help migration from v5. Unless @mjackson wants to talk me out of it, I'm all for it. |
Any news on this? |
What about extendeding the Implementation in react-routes should be easy, I think, as it simply means to ignore parent matches. Upgrading from v5 would be much easier (just add another prop):
Children BTW, I would strongly suggest to add a |
Here is a similar, hacky solution.
import { UNSAFE_RouteContext as RouteContext } from 'react-router';
function RootRoutes(props) {
const ctx = useContext(RouteContext);
const value = useMemo(
() => ({
...ctx,
matches: []
}),
[ ctx ]
);
return <RouteContext.Provider
value={value}
>
<Routes {...props}/>
</RouteContext.Provider>;
} But please note this makes use of "undocumented" I still plead for a dedicated parameter for standard |
@jampy Support for absolute paths in nested Edit: To make this more clear, by "should" I mean "when implemented" rather than "currently". |
@henrywoody thanks for your reply! Good to know. I've checked the PR and also the documentation, but I fail to understand how this is supposed to work. Do I need to specify something special to make nested absolute paths work? My base component looks something like this: function Application() {
return <Routes>
<Route path="/info/*" element={<InfoModule/>} />
/* ... */
<Route path="*" element={<Navigate to="/"/>} />
</Routes>;
} and the nested routes look basically like this: function InfoModule() {
return <Routes>
<Route path="/info/" element={<WelcomePage/>} />
<Route path="/info/docs/*" element={<DocsBrowser/>} />
</Routes>;
} However, neither Logging Swapping What am I doing wrong? |
Same issue here, #7992 only seems to work with nested routes, not descendant |
I went with @jampy 's hack and migration was mostly flawless with almost no code changes required. I've done extensive testing (my app has around 110 routes spread on nested /edit just to add the reason is similar to what has been mentioned above: centralized string constants to handle everything related to routing:
|
Any news on this? Besides @jampy 's hack? I'm using v6.2.2 And the reason I'm looking for this feature is precisely what @nunoleong has mentioned (centralized string constants):
|
@ryanflorence @mjackson Any news on this feature? Is it maybe in progress or should community provide a PR? I believe this is the main blocker for existing apps to upgrade |
@jampy would you please provide a simple example or a working demo of your hack? I am unable to make it work with absolute nested paths. Thanks a lot! Edit: ok I made it work using the hack. Before I only replaced the top Routes with RootRoutes but it's necessary to replace all of them. This however breaks index routes when using the |
You don't need to replace the top Routes. Just use |
I have a use case that, I have 2 "conflicting" routes like:
Since function Entry() {
const {placeholder} = useParams();
if (placeholder === 'tabA' || placeholder === 'tabB') {
return (
<Routes>
<Route path="/users/:tab" element={<UsersPage />} />
</Routes>
);
}
return (
<Routes>
<Route path="/users/:id" element={<UserDetail />} />
</Routes>
);
}
<Routes>
<Route path="/users/:placeholder" element={<Entry />} />
</Routes> Nested |
@jampy thank you so much. You've saved me a hell lot of time <3 |
Any update on this? I have a specific use-case involving module-federated apps where absolute routes are necessary unless I am to refactor an entire project: In App A: - `/my-route/test` -> render App B
- `/my-route/another` -> render App B
- `/my-route/route` -> render App B
- `/my-route/different` -> different component
- `/my-route/*` -> default component or redirect then in App B: - `/my-route/test` -> test component
- `/my-route/another` -> another component
- `/my-route/route` -> route component App A needs to know what sub-routes to send to App B, but because of the way RR6 works, App B can no longer use the sub-routes for routing as they've already been resolved in the path. Without allowing descendent routes to use absolute routing, I don't think there's a way to implement this pattern using RR6 unless I remove real routing from App B entirely and just force it to render different components with some Update: |
I'm a little baffled that this is still an issue with V6. How is any medium to large sized project that uses absolute paths supposed to upgrade? It's unfeasible to completely rebuild my application to support inheriting parent paths. |
We're also waiting for this feature. Although we don't have a problem of migrating an old large project, we still think that hardcoded pieces of routes are hard to work with in the long run — we often need to link from one nested route to another, and the only way to do this now seems to hardcode all the hrefs. dashboard/item/:id/edit/address that is composed of |
Almost a year has gone by since this issue has been opened, a ton of users have presented strong arguments on this as well, and absolutely no answer so far... |
For my use cases I only require matching an absolute import {ReactElement} from 'react';
import {matchPath, useLocation} from 'react-router-dom';
// Allows matching `Route`s against absolute paths when they are nested under another `Route`
// See: https://github.com/remix-run/react-router/issues/8035
const AbsoluteRoutes = ({children}: {children?: readonly ReactElement[]}) => {
const {pathname} = useLocation();
return (
children?.find(
child =>
typeof child.props.path === 'string' &&
matchPath(child.props.path, pathname),
)?.props.element ?? null
);
};
export {AbsoluteRoutes}; |
For the meantime I ended up with these two methods to keep my absolute paths (sort of): export const urlLayout = (url: string): string => `${url}/*`;
export const urlRelative = (url: string, parent: string): string => url.replace(parent, ''); I have created a sample sandbox of how they are used here: codesandbox. |
V6 has conflicting philosophies in its new Path architecture. In one hand, absolute paths are heavily embraced by utilizing the power of TypeScript's Template Literal types, even to the point of removing heavily used features. On the other hand, absolute paths (and template literal types) are discouraged because nested routes simply don't work with them at all. |
I'm going to convert this to a discussion so it can go through our new Open Development process. Please upvote the new Proposal if you'd like to see this considered! |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
What is the new or updated feature that you are suggesting?
Great to see that absolute paths will be supported in V6, I find it very handy to work with.
For it to be fully supported I believe it should work when using nested
<Routes>
as well.Currently (v6.0.0-beta.4) the route definition in the nested
<Routes>
will match on a relative route, even though they start with/
indicating an absolute route.Why should this feature be included?
This way we can use absolute paths throughout our application when we don't specify all routes in the same
<Routes>
component. This will also make the migration from v5 to v6 much easier as this pattern is supported there using<Switch>
.The text was updated successfully, but these errors were encountered: