I start to use react-router in my application and I am noting that when it has a trailing slash at end of URL (/url/
) it does not work. I searched more about it, read all documentation and react-router issues and tried to use <Redirect from='/*/' to="/*" />
, however it was not a good solution, cause it did not work too. So, reading more I found out a suggestion to insert /?
at end of URL, but it still not worked.
The code of routes.js:
export default (
<Route path="/" component={App}>
<IndexRoute component={ProfileFillComponents} />
<Route path="/seguro-residencia" handler={require('./components/Forms/Residencial/ProfileFill/profileFillComponents')} />
<Route path="/seguro-residencia/informacoes-pessoais" component={CotationNumber} />
</Route>
)
The code of index.js:
render((<Router history={browserHistory} routes={routes} />), document.getElementById('root'));
Searching more, I found a guy who made a function to force trailing slash at URLs and I resolved to make the opposite of that, forcing to not have it.
Update routes.js code with function No trailing slash function:
export default (
<Route onEnter={forceTrailingSlash} onChange={forceTrailingSlashOnChange}>
<Route path="/" component={App}>
<IndexRoute component={ProfileFillComponents} />
<Route path="/seguro-residencia" handler={require('./components/Forms/Residencial/ProfileFill/profileFillComponents')} />
<Route path="/seguro-residencia/informacoes-pessoais" component={CotationNumber} />
</Route>
</Route>
)
function forceNoTrailingSlash(nextState, replace) {
const path = nextState.location.pathname;
if (path.slice(-1) === '/') {
replace({
...nextState.location,
pathname: path.slice(1,path.lastIndexOf('/')-1)
});
}
}
function forceNoTrailingSlashOnChange(prevState, nextState, replace) {
forceNoTrailingSlash(nextState, replace);
}
And again this did not work! I need to make this URLs more friendly as possible and I would like that URLs do not have any trailing slash at the end. Any suggestion how can I make this? And why Redirect
did not work in this case?
I start to use react-router in my application and I am noting that when it has a trailing slash at end of URL (/url/
) it does not work. I searched more about it, read all documentation and react-router issues and tried to use <Redirect from='/*/' to="/*" />
, however it was not a good solution, cause it did not work too. So, reading more I found out a suggestion to insert /?
at end of URL, but it still not worked.
The code of routes.js:
export default (
<Route path="/" component={App}>
<IndexRoute component={ProfileFillComponents} />
<Route path="/seguro-residencia" handler={require('./components/Forms/Residencial/ProfileFill/profileFillComponents')} />
<Route path="/seguro-residencia/informacoes-pessoais" component={CotationNumber} />
</Route>
)
The code of index.js:
render((<Router history={browserHistory} routes={routes} />), document.getElementById('root'));
Searching more, I found a guy who made a function to force trailing slash at URLs and I resolved to make the opposite of that, forcing to not have it.
Update routes.js code with function No trailing slash function:
export default (
<Route onEnter={forceTrailingSlash} onChange={forceTrailingSlashOnChange}>
<Route path="/" component={App}>
<IndexRoute component={ProfileFillComponents} />
<Route path="/seguro-residencia" handler={require('./components/Forms/Residencial/ProfileFill/profileFillComponents')} />
<Route path="/seguro-residencia/informacoes-pessoais" component={CotationNumber} />
</Route>
</Route>
)
function forceNoTrailingSlash(nextState, replace) {
const path = nextState.location.pathname;
if (path.slice(-1) === '/') {
replace({
...nextState.location,
pathname: path.slice(1,path.lastIndexOf('/')-1)
});
}
}
function forceNoTrailingSlashOnChange(prevState, nextState, replace) {
forceNoTrailingSlash(nextState, replace);
}
And again this did not work! I need to make this URLs more friendly as possible and I would like that URLs do not have any trailing slash at the end. Any suggestion how can I make this? And why Redirect
did not work in this case?
3 Answers
Reset to default 9React Router v6 solution
RemoveTrailingSlash.tsx
import React from "react";
import {Navigate, useLocation} from "react-router-dom";
export const RemoveTrailingSlash = ({...rest}) => {
const location = useLocation()
// If the last character of the url is '/'
if (location.pathname.match('/.*/$')) {
return <Navigate replace {...rest} to={{
pathname: location.pathname.replace(/\/+$/, ""),
search: location.search
}}/>
} else return null
}
AppRoutes.tsx
const AppRoutes: React.FC = () => {
return (
<React.Fragment>
<RemoveTrailingSlash/>
<Routes>
{/* All your routes go here */}
</Routes>
</React.Fragment>
)
}
I found a good option to make this redirect. Below is the code which I am using:
app.use(function(req, res, next) {
if (req.path.length > 1 && /\/$/.test(req.path)) {
var query = req.url.slice(req.path.length)
res.redirect(301, req.path.slice(0, -1) + query)
} else {
next()
}
});
The explanation is basicly it:
- In this function, I verify if the URL is grand then one and if it has a trailing slash.
- If true, I get this URL without trailing slash and make a 301 redirect to this page without the trailing slash.
- Else, I jump to next method to send a value.
Simple solution using the new Routes from v6.4
<Route // remove trailing slash
path="*(/+)"
loader={({ params }) => redirect(params['*'] || '/')}
/>
This basically replaces the route matched with the one without trailing slashes. I would nest it under your main route, so like this:
<Route path="/" element={<App />}>
<Route // remove trailing slash
path="*(/+)"
loader={({ params }) => redirect(params['*'] || '/')}
/>
</Route>