Can we get an example of the suggest way to implement authorization/redirecting on routes? I'm used to React Router, where you can create custom Route components to do this, but since Reach Router uses the component itself (instead of a Route component), I'm not sure what the right/suggested way is to accomplish this.
Would you create your own <AuthorizedRoute /> component like you would with React Router? Then pass your component in as a property? Then in your router you'd end up with something like this (that basically mimic's what you'd do with React Router)?
import { Home } from './home';
import { Profile } from './profile';
...
<Router>
<Home path="/" />
<AuthorizedRoute path="/profile" component="Profile" />
</Router>
For the record, I haven't tried this, but I'm using hooks with nested routers and it looks like that method might be problematic for those anyway.
+1
In my projects, i use this custom Route component to provide additional context, like current_role, or meta data for SEO purpose:
import React, { FunctionComponent } from "react";
import { RouteComponentProps } from "@reach/router";
import withPageContext from "utils/hocs/withPageContext";
import withLayout from "utils/hocs/withLayout";
import withMeta from 'utils/hocs/withMeta'
import { Skeleton } from "antd";
type Props = {
component: any;
tags?: string[];
page?: string;
role?: string;
title?: string;
meta?: any;
} & RouteComponentProps;
const Route: FunctionComponent<Props> = ({ component, path, ...rest }) => {
const { title = '', meta = [], role = 'anonymous' } = rest
const Component = withMeta({ title, tags: meta })(withPageContext(withLayout(component)));
return <Component fallback={<Skeleton />} path={path} {...rest} />;
};
export default Route;
For example usage, this is how to render the Login route component:
<Router>
<Route
component={Login}
path={"/login"}
page="login"
title="Login page"
meta={[{ name: "description", content: "My system" }]}
/>
</Router>
@revskill10 i see no auth checks or anything in above code. where do you apply context checks and redirect to other page , if those checks aren't successful.?
@vamshi9666 In my case, if role is anonymous it'll be treated as unauthenticated. I don't separete authenticated vs unauthenticated routes. I just provide role to routes, the rest is each route's job to render based on current provided role.
If any of you like this syntax, I made a PR here.
const Routes = () => {
const { user } = useAuth()
const handlePrivateRoute = navigate => {
if (!user) navigate('/login')
}
return (
<Router onPrivateRoute={handlePrivateRoute}>
<SettingsPage path="/settings" private />
<LoginPage path="/login" default />
</Router>
);
}
Most helpful comment
If any of you like this syntax, I made a PR here.