Support absolute paths in descendant <Routes>
#9841
Replies: 42 comments 8 replies
-
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 |
Beta Was this translation helpful? Give feedback.
-
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 👍 |
Beta Was this translation helpful? Give feedback.
-
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 |
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
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 |
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
Any news on this? |
Beta Was this translation helpful? Give feedback.
-
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 |
Beta Was this translation helpful? Give feedback.
-
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 |
Beta Was this translation helpful? Give feedback.
-
@jampy Support for absolute paths in nested Edit: To make this more clear, by "should" I mean "when implemented" rather than "currently". |
Beta Was this translation helpful? Give feedback.
-
@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? |
Beta Was this translation helpful? Give feedback.
-
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}; |
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
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! |
Beta Was this translation helpful? Give feedback.
-
This is such a crucial feature which is currently missing by many. Hope you get this implemented soon. In the meantime we are going to use the RootRoutes workaround. |
Beta Was this translation helpful? Give feedback.
-
I've just wanted to define a routes config for our project routes and found this issue. I have this config for example: const routes = {
AUTH: {
path: '/auth',
children: { LOGIN: '/auth/login', OTP: '/auth/otp' }
},
};
function App() {
return (
<Routes>
<Route path={`${routes.AUTH.path}/*`} element={<Auth />} />
<Routes>
)
}
function Auth() {
return (
<Routes>
<Route element={<Layout />}>
<Route index element={<Welcome />} />
<Route path={routes.AUTH.children.LOGIN} element={<Login />} />
<Route path={routes.AUTH.children.OTP} element={<OTP />} />
</Route>
</Routes>
)
} Absolute paths doesn't work in nested |
Beta Was this translation helpful? Give feedback.
-
Spent a lot of time debugging this. You won't convince me that "it's by design" if it makes it more costly to write and maintain the code while providing no benefits. It can't be by design. That's just a bug. Please fix it if it's possible |
Beta Was this translation helpful? Give feedback.
-
9 months since my last reply saying that "almost a year had gone by", and still no progress. Please, either mark this as "will not do" or give us some meaningful update. It's mesmerizing that:
|
Beta Was this translation helpful? Give feedback.
-
I read the migration guide in the React Router docs from v5 to v6 a couple of times, but I never figured out that nesting of |
Beta Was this translation helpful? Give feedback.
-
Well, it passed the 2-years-milestone since the last time I commented on this issue. It's also been a while since I used The overall ideas of v6 just made sense to me when I first read and tried it. But it's such a shame absolute paths are not supported.
My point is that this
I'm not so free myself but I think I'm willing to challenge myself adding support for absolute paths. |
Beta Was this translation helpful? Give feedback.
-
Not tested thouroughly though seems to work?, just decided to try out the hack provided above. Its awesome that it works, but kinda weird since theres warnings in development. I tried doing something like this, since I have no basename set things are defaulted to "/", but in case it assists anyone else.
Codesandbox so you can play with it: https://codesandbox.io/p/sandbox/react-router-v6-forked-nkmr2w |
Beta Was this translation helpful? Give feedback.
-
This issue seems to be still ongoing in v6.20.1. This is one of the most used React libs out there, and the most popular routing lib, and we're not given any kind of addressing from the maintainers? really? |
Beta Was this translation helpful? Give feedback.
-
I found this passage in the FAQ.
It seems to work the same as edit: |
Beta Was this translation helpful? Give feedback.
-
I am trying to move over to v6 from v5 and I have faced the same issue. In our case we are keeping every URL of the project in a static object, eg export const paths = {
home: () => '/home',
admin: () => '/admin',
adminPage1: () => paths.admin() + '/page1',
adminPage2: () => paths.admin() + '/page2',
} This is a very useful pattern because we can use these paths for links or as As you can see, these are absolute paths and this does not mix well with how descendant For example we have a specific function AdminRoutes() {
return (
<Routes>
<Route path={paths.adminPage1()} element={...} />
</Routes>
);
} Which we then render inside our main function Routes() {
return (
<Routes>
<Route path={paths.admin() + '/*'} element={<AdminRoutes />} />
</Routes>
);
} With the way things work right now the The way we have setup our project we cannot be working with relative paths, so an official way to match paths as absolute would be nice. @timdorr @ryanflorence EDIT: |
Beta Was this translation helpful? Give feedback.
-
Upgrading an app from v5 to v6 and faced this issue too. I know the team is hard at work pushing out v7 but we just need some clarification from the maintainers
I believe supporting absolute paths in descendent routes should continue to be supported as per the rationale in this issue thread Just to be clear I'd be willing to work on a PR to implement this. But what we need is some clarification from the team on what the next steps should be and whether support for this feature is also expected in v7. If this feature will not be supported in v7 then there is no point implementing support for absolute paths anyways and what we should be doing is to migrate our entire codebase to use relative paths instead. |
Beta Was this translation helpful? Give feedback.
-
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>
.Beta Was this translation helpful? Give feedback.
All reactions