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] Link with absolute path doesn't respect basename #7216
Comments
If this is a bug indeed, then as a possible solution idea - should |
Please let me know if I can help on this. I'll be happy to fix it. |
Yes, this also happens in React Router 5. It renders to wrong href, though it behaves correctly when clicked. |
MemoryRouter does not support basename. On the other hand, maybe we can strip the leading slash from basename? |
Would anyone be able to confirm whether this is an intentional change or a bug? I'm proactively preparing a very large project for v6 and I'm a bit stuck on this - unsure whether I should expect |
Ìn order to make it work in v6 you should omit the leading slash from basename |
@jeffersonlicet it doesn't work if we're routing inside nested components - it appends basepath to the current path, which results in incorrect URLs |
Yeah it isn't working for me either. Here's the original sandbox with the leading slash removed from |
Seems like an intentional change to me, did you read latest docs about migrating, especially section about relative routes and trailing slash? |
@malyzeli Yeah I've been through the migration docs. They don't mention anything about the behaviour of Just to clarify with the most concise example I can conjure up:
The If this is intentional then perhaps |
I would add to @levymetal example above that from my understanding, the intent behind In v5 one could define appropriate In v6 the only workable approach so far seems to be passing basepath down to all components in the app, and prefixing all relevant routes/link like I'm happy to PR a fix, but I was hoping to get some confirmation from react-router team here that this is indeed a bug, and/or an thumbs up on the approach to the fix outlined in my comment above |
@levymetal my fault - somehow I missed @morhekil is talking about Configured |
Bumping this since there's been two releases since and it seems to still not be addressed. Old basename would automatically prepend it to Link paths. Preferable that would stay the same IMO. |
Just confirming that this issue is still valid in v6.0.0-alpha.5: https://codesandbox.io/s/react-router-v6-basepath-1dcnm |
This is still a problem in the recent beta |
The same issue is present with the <Routes basename={process.env.PUBLIC_URL}>
<Route path="/" element={<Navigate to="/home" replace />} />
<Route path="/home/*" element={<Home />} />
</Routes> When directly opening |
waiting for basepath fix: remix-run/react-router#7216
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
a bump to keep the stale bot away |
Ran into this issue as well. Any thoughts on merging fix #7462? |
It would certainly be great to hear the devs' thoughts regarding this issue.
Some additional examples using the latest versions: |
I'm trying understand what is the reason for providing I would like to know what is the recommended solution/workaround when we need to deploy React app under non-root path on the server? Explicitly prefixing all |
what you mean with non-root paths @malyzeli? like navigating to external domains? 🤔 |
@renatobenks They mean in a subdirectory, eg It seems the overwhelming majority prefer the behaviour of previous versions because they're much easier to set up with subdirectories, which a lot of people are doing. Also, it doesn't make sense how I'm only repeating what has already been discussed so apologies to all who have notifications turned on. |
Seems to me that for now the best workaround would be cloning the source, manually applying fix from PR here, then keep using this custom patched version until it's either resolved in official package or until we get some explanation from maintainers - possibly suggesting alternative solutions if |
Currently, the migration guide says that we merely need to move the Is this true? If true, this is minimally disruptive. But from all the upheaval in this thread/issue, the migration guide might be glossing over some nasty details. |
I confirm the problem. In a micro front architecture it is very annoying |
I don't know yet if I like this change, basically if I've a route with a link to another route with react-router@5 you'd just: <BrowserRouter basename="/app">
<Switch>
<Route path="/foo" exact render={() => <>foo! <Link to="/bar"></Link></>}>
<Route path="/bar" exact render={()=>'bar!'} />
</Switch>
</BrowserRouter> and the link to "/bar" would translate to "/app/bar" as expected now with react-router@6 it seems you need to do: <BrowserRouter>
<Route path="/app">
<Route path="/foo" element={<>foo! <Link to="../bar"></Link></>}>
<Route path="/bar" element={'bar!'} />
</Route>
</BrowserRouter> where you need to play with relative paths all the way This is super annoying if a component is reused and displayed from different path levels, and simply impractical overall, I prefer dealing with absolute paths, they're more explicit I could try to make my own So 👍 for this issue description |
#7462 has a fix for this but is awaiting merge approval. |
While we await PR merge, I suggest we consider using custom example: import React from 'react'
import { To } from 'history'
import { Link as RLink, LinkProps, Navigate as RNavigate } from 'react-router-dom'
import { NavigateProps } from 'react-router'
const basename = process.env.PUBLIC_URL
function removeLeadingSlash(path: string) {
return path.replace(/^\//, '')
}
function getAbsolutePath(path: string) {
// skip relative paths
if (!path.startsWith('/')) return path
return ['/', removeLeadingSlash(basename), '/', removeLeadingSlash(path)].join('')
}
function convertTo(to: To): To {
if (typeof to === 'string') return getAbsolutePath(to)
return { ...to, pathname: to.pathname ? getAbsolutePath(to.pathname) : to.pathname }
}
export const Link: React.FC<LinkProps & React.RefAttributes<HTMLAnchorElement>> = props => {
const to = convertTo(props.to)
return <RLink {...props} to={to} />
}
export const Navigate: React.FC<NavigateProps> = props => {
const to = convertTo(props.to)
return <RNavigate {...props} to={to} />
} |
BTW You can use the patch-package to patch the |
Fixed in #7462. New beta release coming this week! |
Heck yes! |
❤️ |
Unless I am misunderstanding it, I think this fix causes a different issue. In an app with multiple deeply nested routes that are built via the We see something like this: Nested I do agree that, in general, navigation being relative to the basename (for the purposes discussed above) is a good thing but how would you approach this scenario as it seems like a trap? |
I've already experienced this issue before the beta.1 I believe, the only way to break out of the nested route when using I haven't seen any reasoning in the documentation so far that would explain why we shouldn't have "really" absolute routes in nested routes (or if so, a proper way to then deal with the trap you described). This seems silly. It's nice to have "absolute" links in nested routes, but not being able to navigate out of the nested route is something that doesn't make any sense to me at all. I don't understand how anyone is currently using nested routes in v6 with this behavior... Note: I used a hook because I accessed the basename from my AppContext, so this isn't strictly necessary |
I took a similar approach that I can use unless I am missing a more proper solution. I have a usePathNavigate() which makes |
Hmm, I like using the That would result in all my links differing from v6's approach (absolute links starting with I might go with |
Issue still occurs in react router dom latest version! |
Version
6.0.0-alpha.2
Test Case
https://codesandbox.io/s/react-router-v6-basepath-1dcnm
Steps to reproduce
Set up
<Routes basename="/something">
, and inside its component tree use a link with absolute path<Link to="/path">path</Link>
Expected Behavior
Link respects
basename
specified in its parentRoutes
, and generates URL<a href="/something/path">
Actual Behavior
Link ignores
basename
, and generates absolute URL from website root<a href="/path">
Comment
This is the expected behaviour of
basename
as described in v5 docs - e.g. here, unless it was an intentional change in v6 - was it?Looking at the code, I suspect the problem is these two lines of
resolveLocation
:https://github.com/ReactTraining/react-router/blob/dev/packages/react-router/index.js#L766-L767
If
toPathname
starts with a slash (like in a codesandbox example above) -resolveLocation
ignoresfromPathname
, and as the result - losesbasename
value that it may have contained.The text was updated successfully, but these errors were encountered: