How can I redirect to an absolute path with react-router v4?

Viewed 22027

I have a huge Django web app, with one of it's modules (a 'dashboard') written with node and react. User login is handled by a Django module.

The user should be logged into the main app in order to access the react dashboard, and this works partially - the code gets the user session from the browser and only renders stuff if there is one.

I would like now to redirect the user to the main app login page if there is no session, but I don't know how to do it with my current structure (and this bloody v4 router).

I am using a basename in the BrowserRouter component to use routes relative to the dashboard path in the django app.

This is what I came up with for the JSX for app.jsx:

<BrowserRouter basename='/en/dashboard'>
    {this.state.isAuthenticated ? (
        <Paper zDepth={0} style={{ height: '100%', backgroundColor: grey900 }}>
            <div style={{height: '100%'}}>
                <Header />
                <Switch>
                    <Route exact={true} path='/' component={FirstSection}/>
                    <Route path='/first' component={FirstSection}/>
                    <Route path='/second' component={SecondSection}/>
                </Switch>
            </div>
        </Paper>
    ) : (
        <Redirect to="/en/login"/>
    )}
</BrowserRouter>

However, it actually redirects to en/dashboard/en/login. I believe I could remove the 'basename' property from the BrowserRouter and add it to each subsequent Route, but if this module eventually grows bigger, it would make routing harder. Is there a better way to do this?

3 Answers

As mentioned in Kyle's answer, there is no way to have to use absolute urls or to ignore the basename; however, if you want or "need" to run the redirection from the render method of your component you can create your own ultra-light "absolute redirect" component, here's mine:

import React from 'react'

class AbsoluteRedirect extends React.Component {

    constructor(props){
        super(props)
    }

    componentDidMount(){
        window.location = this.props.to
    }

    render(){
        return null
    }

}

export default AbsoluteRedirect

And then use it other components with a condition so it only gets mounted when your validation is true.

render(){ 

    if( shouldRedirect )
        return <AbsoluteRedirect to={ anotherWebsiteURL } />

    ...

}

Hope this helps :)

You can do it without react router:

window.location.pathname = '/en/login';

Navigating away to a different site is using:

window.location.href = 'https://stackoverflow.com';
Related