How To Setup Automatic Redirects In Your React Application
Tags: programming, react, javascript, webdev
Published: 2023-01-20 09:36:06

In today's article, I will show you how you can set up an automatic redirect to a secured/restricted page in your react application after the user is authenticated.

## INTRODUCTION

Let's assume that in your app, you have a page that needs authentication before a user will be able to access it, for example, the dashboard. This means that before a user is allowed to access the dashboard, he must be logged in.

Now, What if for any reason (session timeout, expired cookie, etc.), the user logs out of the app, but needs to revisit that same page on the dashboard? Or maybe he tries to visit information on the dashboard by clicking on the link from an email sent to him? How would you redirect this user back to the link he tried to visit after authentication?

This question will immediately make you understand that it is not enough to ask a user to log in before he can access a restricted page. But you should also redirect the user to the restricted page immediately after he is authenticated.

## STILL CONFUSED? LET ME EXPLAIN BETTER

So I have this page `http://my-website.com/dashboard/update-profile` that needs the user to be authenticated before he is allowed to visit it. Whenever a user that is not authenticated tries to visit it, he will be redirected to `http://my-website.com/login`

Now the goal is to preserve this URL `http://my-website.com/dashboard/update-profile` so that when the user is authenticated successfully, he will be redirected back to it.

I will show you how you can achieve this in your React App, and if you should understand the logic, you can implement it anywhere!

## USING A QUERY PARAMETER

In this approach, I will check if the user is not logged in, then retrieve the URL he is trying to visit, store it in the query parameter next, and then redirect him to the login page. If authentication is successful, I will redirect him back to the URL in the next query parameter.

> Place this code on a secured/restricted page (a page that requires authentication) 

To achieve this, the first thing that I need to do is to check if the user is not logged in.

```jsx
useEffect(() => {
    isAuthenticated().then(res => {
        //check if user is not logged in
        if(!res){
            //----
        }
    }
}, []) //make the function run only once when the component mounts
```
Now we need to create a new URL object with the link that this user will be redirected to in order to get authenticated. 

In my case, it will be the /login page and the reason why I am creating a new URL object with it is that I am going to manipulate the link by adding a query parameter later on.

```jsx
useEffect(() => {
    isAuthenticated().then(res => {
        //check if user is not logged in
        if(!res){
            //create a URL object with the Login Link
            const loginUrl = new URL('http://my-website.com/login');
        }
    }
}, []) //make the function run only once when the component mounts
```

Now before we continue, we need to make sure that the user is trying to visit a restricted page in the dashboard. We can do that by checking if the current URL contains `/dashboard`. 

I will use a regular expression inside the `match` method to perform this search on the current URL.

```jsx
useEffect(() => {
    isAuthenticated().then(res => {
        //check if user is not logged in
        if(!res){
            //create a URL object with the Login Link
            const loginUrl = new URL('http://my-website.com/login');
            //check if user is trying to access dashboard without logging in
            if(window.location.href.match(new RegExp('/dashboard', 'i'))){
                //---
            }
        }
    }
}, []) //make the function run only once when the component mounts
```
Now we need to append the link the user tried to visit as a query parameter to the URL object we created earlier, and then redirect the user to the full URL from this URL object.

```jsx
useEffect(() => {
    isAuthenticated().then(res => {
        //check if user is not logged in
        if(!res){
            //create a URL object with the Login Link
            const loginUrl = new URL('http://my-website.com/login');
            //check if user is trying to access dashboard without logging in
            if(window.location.href.match(new RegExp('/dashboard', 'i'))){
                //Get the url he wanted to visit
                const next = window.location.href
                //append it to the URL object
                loginUrl.searchParams.append('next', next);
            }
            //redirect the user to the full URL from the URL Object
            window.location.href = loginUrl.href.toString()
        }
    }
}, []) //make the function run only once when the component mounts
```

Here's what we have done so far.

When a user that is not authenticated tries to visit any page in the dashboard for example `http://my-website.com/dashboard/update-profile`, he will be redirected to `http://my-website.com/login?next=http://my-website.com/dashboard/update-profile`.

Now, here's something to have in mind.

The browser will try to encode the value in the next query parameter because it is a URL and before we access this value, we need to decode it.

On my end, here's what my address bar looks like

![My address bar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yy1fwetmz1zyc4ecgnmv.png)

It is time for us to handle the redirect if the user becomes authenticated.

## HANDLING THE REDIRECT

Now on your login page, we will create a variable that will store the default link the user will be redirected to if authentication is successful. 

We will also import `useLocation` from `react-router-dom` so that we can be able to read the current URL and check if it contains a search (query) parameter.

```jsx
import {useLocation} from 'react-router-dom';

export default function Login(){
  //invoke the function
  const location = useLocation();
  //default page to redirect user after login
  let redirect = 'http://my-website.com/dashboard/home';
  //check if there's search param in the URL
  if(location.search){
    //---
  }
}
```

If you don't want to use the `useLocation` module to read the current URL, you can equally access the current URL directly using JavaScript.

```jsx
export default function Login(){
    //default page to redirect user after login
    let redirect = 'http://my-website.com/dashboard/home';
    //create a URL object using the current url
    const url = new URL(window.location.href)
    //check if url contains a search parameter
    if(url.search){
        //---
    }
}
```

Whichever method you choose to use, the next thing to do is to read the search parameters and check if it contains `next`. 

If it contains `next`, we will decode the value and reassign the value of the redirect variable to this URL.

You can also perform a search to check if the decoded value contains `/dashboard`.

```jsx
export default function Login(){
    //default page to redirect user after login
    let redirect = 'http://my-website.com/dashboard/home';
    //create a URL object using the current url
    const url = new URL(window.location.href)
    //check if url contains a search parameter
    if(url.search){
        //read the search parameters
        const search = new URLSearchParams(url.search)
        //check if next parameter is present
        if(search?.get('next')){
            //decode it
            const next = decodeURIComponent(search.get('next'))
            //check if dashboard is present in the URL
            if(next.match(new RegExp('/dashboard', 'i'))){
                redirect = next;
            }
        }
    }
    //after authentication, redirect users to the redirect variable
    //window.location.href = redirect;
}
```

So after authentication, you should redirect your users to the value of the redirect variable, which is the decoded URL!

Watch my implementation below

{% embed https://www.youtube.com/watch?v=YKMF_7QDw8w %}

## A LITTLE TIP

If you want to make your redirects cleaner, you can store the URL in the browser's `sessionStorage` and when you validate it, you can go ahead and delete it from the session storage, then redirect the user to the URL. 

Thank you for reading.

> Psst! I'm open to gigs on web development and Technical Writing!

## EXTRA

I built a JavaScript Library that is capable of validating your front-end forms using regular expressions, validation rules, and form input attributes.

Check out this library on GitHub

{% embed https://github.com/Octagon-simon/octaValidate %}

Check out the Documentation

{% embed https://octagon-simon.github.io/projects/octavalidate/ %}

Photo Credit: Hal Gatewood On Unsplash