-
-
Notifications
You must be signed in to change notification settings - Fork 10.5k
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
Remove trailing slash from match.url #4841
Comments
That is what the |
The |
Relative For the time being I would just use const join = (base, path) => {
return base.charAt(base.length-1) === '/'
? base.slice(0, -1) + path
: base + '/' + path
}
<Route path={join(match.url, '/rest')} component={Rest} /> |
Very unexpected behavior at a first glance. Some guidance would be nice :) We use a lot of this Note: a node path's like join function is totally fine for me :) |
Experiencing the same unpredictable route match.url trailing slashes, especially with nested routes |
I solved this at the parent route level by redirecting to the no-slash-url.
This way the url matched never contains the trailing slash. Just another option. |
Yeah I'd like some guidance. Should I be aiming to have slashes at end or not? Coming from WordPress the answer is yes I'd like a / at the end of everything. As I began to re-work my code to support that I begin to see example.com/bar//foo as well, making me think no trailing slash is the standard with React. |
I struggled for quite some time to get a workaround for this. I also learned about This comment on a strict-related issue worked for me: Our structure ended up like this:
I really suggest there is a configuration on RR that would remove all the trailing slashes on URLs. Hope this comment can help people looking for this. |
@leite08 thanks for the solution, it works for most cases. But when I have top-level |
Having two routes -- the first being
Any thoughts on potential problems/caveats? |
I think trailing slash should be removed from match.url. This behavior is not obvious and should be clarified in documentation |
It is also "Not The Unix Way" of doing things to use /something when it's not at root. |
This is good I will use this double spec approach if my troubles come again. |
I'm facing the same problem,
It's working now but looks a little bit not right! |
I was using @filoxo 's solution, but it recently stopped working in the 5.0.1 release |
Any progress? |
@dylanwulf You can try to use the following code, it works for me with the 5.0.1 release : <Switch>
{/* Removes trailing slashes */}
<Route
path="/:url*(/+)"
exact
strict
render={({ location }) => (
<Redirect to={location.pathname.replace(/\/+$/, "")} />
)}
/>
{/* Removes duplicate slashes in the middle of the URL */}
<Route
path="/:url(.*//+.*)"
exact
strict
render={({ match }) => (
<Redirect to={`/${match.params.url.replace(/\/\/+/, "/")}`} />
)}
/> A little bit hackish but I get correcting routing also with:
|
I used the following code in my main component I define the router, but I'm not sure If this is the best practice for React Router if (props.location.pathname.endsWith('/')) {
props.location.pathname = props.location.pathname.slice(0, -1);
} |
I did a workaround: export const path = url => {
const fixedPath = url.endsWith('/')
? path(url.substring(0, url.length - 1))
: url;
return fixedPath;
}; then: <Redirect to={path('/dashboard/')} />
// returns => /dashboard
<Redirect to={path('/dashboard///')} />
// returns => /dashboard |
I tried the workarounds above that detect the trailing '/' and fix it with a To fix that I used this code instead:
Using replace removed the trailing space without reloading the page. |
@divonelnc, did you check for other browsers? |
@hosseinalipour Tested on Chrome, Firefox, and Edge so far. Any reason why it wouldn't work on some browsers? |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
This issue is not a stale stupid bot |
I am not sure if this is related but I fixed the my trailing slash issues by changing my If I started I started |
My problem is that if my nested routes are in a parent route like My workaround: const { path, url } = useRouteMatch();
<Link to={`${url.endsWith('/') ? url.slice(0, -1) : url}/announcement`} />
<Route path={`${path.endsWith('/') ? path.slice(0, -1) : path}/announcement`} /> |
Adding a
Credit to: https://jasonwatmore.com/post/2020/03/23/react-router-remove-trailing-slash-from-urls |
It is not enough to build
`${url}/announcement` |
Hey just want to let you know that navigating to something like /hello//world with this redirect pattern results in the url being rewritten in an unexpected manner (to /hello in this example). I would not recommend using this solution. |
There is no need to navigate to a url ending in In my case it works perfectly if I have The only solution that works for me is: #4841 (comment) |
For those interested in leveraging redirects, here's a slight improvement on removing all extra slashes:
This handles cases where you have extra slashes at the beginning, middle, or end and makes all replacements at once so you don't have to chain redirects (ie ///hello//world//url -> /hello//world//url -> /hello/world//url -> /hello/world/url). +1 on @jrrdev approach to removing the trailing slash. |
I also did change replace value from export const RemoveTrailingSlash: React.FC = () => {
return (
<Route
path="/:url*(/+)"
exact
strict
render={({ location }) => <Redirect to={location.pathname.replace(/\/+$/, location.search)} />}
/>
);
}; |
Modified this a little to keep the URL same - <Redirect
exact
strict
from="(.*//+.*)"
to={location.pathname.replace(/\/\/+/g, '/') + window.location.search + window.location.hash}
/> This also ends up handling URLs like - |
This comment has been minimized.
This comment has been minimized.
Actually I don't think this is an issue but the intended behavior. The following snippet will always remove the trailing slash and should therefore fix your issue: <Switch>
<Redirect from="/:url*(/+)" to={window.location.pathname.replace(/\/+$/, window.location.search)} />
// Your other routes are probably here
</Switch> Important note: As the routes are probably defined close to the root in the dom tree I would not consider using any react-router hook (that far up in the tree) as It will cause this element to rerender every time (or at least comparing more elements in the virtual dom) the url changes. The provided solution will prevent some unneccessary rerenders. With this solution you should always be able to push a new route like this const {url} = useRouteMatch();
<Link to={`${url}/ADD_SOMETHING`}>A link!</Link>
// or instead
const {url} = useRouteMatch();
const history = useHistory();
history.push(`${url}/ADD_SOMETHING`) |
This would require the "exact" parameter to not redirect all subsequent path that follows |
Maybe I'm missing something here, so feel free to correct me if so, but this feels like it should be solvable with a relatively simple function. function Component() {
let { url } = useRouteMatch();
let { id } = useParams();
return (
<Route path={joinPaths(url, id)} component={View} />
);
}
function joinPaths(...segments) {
return segments.join('/').replace(/\/+/g, '/');
} We could do this internally (unlikely with <= v5 since it's a breaking change) or expose it as a helper, but is this not sufficient? |
@chaance this is a good work-around. But it is a work-around and it should be done without it. Therefore it should be a basic behaviour of RR without the need to think about it. |
I'm not 100% sure that I agree. If trailing slashes aren't important to you, you can always compose our import { useRouteMatch as useRouteMatch_ } from "react-router";
export function useRouteMatch(path) {
return useRouteMatch_(trimTrailingSlashes(path));
} |
Why not add a default behaviour and if this default behaviour doesn't match what a developer wants he/she can disable it? I think in the most cases triming slashes is exactly what you want. |
We could certainly discuss something like that for v6, but at least in v4/v5 changing the default behavior would be a breaking change. @mleister97 is correct that this is currently the intended behavior, so I'd suggest adopting one of the workarounds for now. |
Closing this, but see #8022 to pick up on potential changes for v6. |
There is some nice solutions here posted. I'm happy with these. For me it was more of a spiritual thing - a test of how I felt about React router. These are good enough for me. |
I solved like this:
consume this component inside your BrowserRouter
|
If you do not want to alter your routerConfig ( I was not able to add a You can add this small function on the very beginning of your router component, this will remove every multi slashes
This will do:
|
Version
4.0.0
Test Case
https://reacttraining.com/react-router/web/example/recursive-paths
Steps to reproduce
In the mini browser, put a trailing slash after a resource like:
/3/
Expected Behavior
nested url should look like
/3/2
Actual Behavior
nested url looks like
/3//2
Is this something thats possible?
The text was updated successfully, but these errors were encountered: