I'm building a website based on reactjs, redux and react-router (redux-simple-router), and I'm kind of stuck in figuring out how to share the root path according if the user is authenticated or not.
I was looking this example https://github.com/reactjs/react-router/tree/master/examples/auth-with-shared-root, but to be honest I couldn't get it works.
I have two different layout. The first one is the public layout and it is shown when the user is not authenticated. From here you can access to the login page and the registration.
After the user gets authenticated, I want to show him the internal app, which is a complete different layout, but do it in the same root URL.
For example: http://example.com/
When the user is not authenticated:
<Route path='/' name='homepage' component={SiteLayout}>
<IndexRoute component={HomeView} />
<Route path='/login' name='login' component={LoginView} />
<Route path='/join' name='join' component={RegistrationView} />
<Route path='/404' component={NotFoundView} />
<Redirect from='*' to='/404' />
</Route>
And after the authentication, keep the same root URL.
<Route path='/' name='feeds' component={InternalLayout}>
<IndexRoute component={FeedsView} />
<Route path='/profile' name='login' component={ProfileView} />
<Route path='/settings' name='join' component={SettingsView} />
<Route path='/search' name='join' component={SearchView} />
</Route>
It is just like Facebook does.
My question is (and If you can provide an example it would be great): How can I render different layouts under the same URL, according to the authentication status?
PD: I have a Token class, where I store the authentication status (JWT), with a method hasToken.
In the example I'm using the JSX syntax, I don't know if I have to switch to the config syntax to achieve the desired results.
Any help is appreciated.
One way to approach this is using the object literal form. You'll need to create an extra component that will incase your root routes. It doesn't need to be anything fancy, a
<div>{this.props.children}</div>
will do (e.g. App) and then the route could look something like this:
const redirectToLogin = (nextState, replace) => {
if (isLoggedIn()) {
replace('/login')
}
}
const routes = {
component: App,
childRoutes: [
{
path: '/',
getComponent(location, cb) {
return isLoggedIn() ? cb(null, InternalLayout) : cb(null, SiteLayout);
},
indexRoute: {
getComponent: (location, cb) => {
return isLoggedIn() ? cb(null, FeedsView) : cb(null, HomeView);
}
},
childRoutes: [
// Your not authenticated views under SiteLayout
{ path: '/login', component: 'LoginView'},
{ path: '/join', component: 'RegistrationView'},
// etc.
{
// if not logged in, redirect to login page, once the user logs in, they'll be redirected to the childroute
onEnter: redirectToLogin,
childRoutes: [
// Your authenticated views under FreedsView
{ path: '/profile', component: 'ProfileView'},
{ path: '/settings', component: 'SettingsView' },
// etc.
]
}
]
}
]
}
I hope this helps.