How to create Private Route with React Router v6

A. Kürşat Uzun
Frontend Weekly
Published in
2 min readSep 29, 2021

--

Update: I’ve upgraded article from beta version to latest version.
React Router v6 has plenty of new changes if you aren’t familiar with reach/router before. Let’s look at how we can create a Private Route in this article with an example.

We’ll create a “Private Route” that will be accessible only who have authorization and necessary permission.

You can find the source code of the demo and code sandbox link end of the article.

This example covers the below scenarios;

* Without logged in, the user can’t access the pages that require authorization.
* The user can’t access the pages that don’t have permission even if logged in.
* Without logged in, the user can’t make an authenticated request.

In this example, I’ve defined two different roles. The users who have the ”Admin” role can access all pages. On the other hand, the users who have the “User” role only access public pages and “Users” pages.

pages/Login.tsx      ← All users can access 
pages/Dashboard.tsx ← The users with "Admin" role can access
pages/Users.tsx ← The users with "User" or "Admin" role can access
pages/AccessDenied ← Authenticated users that don't have permission will be redirected to this page
pages/NotFound ← If the user try to navigate a page that doesn't exist will be redirected to this page

PrivateRoute with React Router v6

We’re checking is user authenticated with “isAuthenticated” variable and is user permission to view this page with “userHasRequiredRole” variable. If these conditions do not match, we’re redirecting the user to “/” root.

Now, you can use the PrivateRoute component under Routes like below:

Additionally, I’ve used “RTK Query” to manage requests:

If there is a token in store we’re adding this token to the header. If the user is not logged in there will be no token in store so, protected requests will fail. (In this demo msw.js used to back-end requests)

Lastly, let’s see how login and logout reducers look like:

When a login request is successfully fulfilled we’re storing response to the state. In the logout reducer, we’re clearing the store.

Demo

Sources:

1- https://github.com/akursat/react-router-example
2- https://github.com/remix-run/react-router/releases/tag/v6.0.2
3- https://redux-toolkit.js.org/
4- https://adarshaacharya.com.np/blog/role-based-auth-with-react-router-v6

--

--

A. Kürşat Uzun
Frontend Weekly

Frontend developer and designer, science fiction enthusiast, practicing minimalism, and stoic in search of flow. Writing about design and code.