Alfrex92
Alfrex92

Reputation: 6778

Restrict Back Button React Router

I would like to restrict access to my router and disabled the back button.

For example, if the user manually types on the browser tab or click in an URL besides event/:eventId, I want to redirect it to event/:eventId

Current:

  1. The user visits event/1234/friends.
  2. It gets redirected to event/1234
  3. The user clicks the back button and is be able to see event/1234/friends. (It should not be able to visit event/1234/friends).

Note: This bug only happens on mobile. You can't reproduce it on desktop.

Desired:

  1. The user visits event/1234/friends.
  2. It gets redirected to event/1234
  3. Disable the back button or if the user clicks the back button, won't be able to visit event/1234/friends

This how my code looks like

 const eventPathname = props.history?.location?.pathname;
  const matches = eventPathname.match(/^\/event\/([^/]+)\/.+$/);
  if (!!matches) {
    const defaultPathname = `/event/${matches[1]}`;
    props.history.length = 1;
    window.location.replace(defaultPathname);
    props.history.push(defaultPathname);
  }

And here is a code sandbox:

https://codesandbox.io/s/keen-silence-47ztr

Remember that you can't reproduce it on desktop, only on mobile.

I checked several threads on StackOverflow like 1, 2, 3, 4 but I couldn't find a proper answer. Any help of how can I achieve this?

Upvotes: 1

Views: 407

Answers (2)

chung
chung

Reputation: 1133

An updated answer in 2024, you can use the useNavigate() function and add the replace: true argument. https://reactrouter.com/en/main/hooks/use-navigate

import { useNavigate } from 'react-router-dom';

const navigate = useNavigate();

navigate(`/event/1234/`, { replace: true });

if you navigate to /event/1234 from /event/1234/friends, but use this function, it'll replace the /event/1234/friends and when you click back, you should go to wherever you were before /event/1234/friends.

Upvotes: 0

gdh
gdh

Reputation: 13682

You can simply use history.replace (not push)

if (!!matches) {
    const defaultPathname = `/event/${matches[1]}`;
    //props.history.length = 1; //<---- probably not required
    //window.location.replace(defaultPathname); //<---- not required
    props.history.replace(defaultPathname); //<---- like this
  }

Edit: Some explanation

The main difference between push and replace is that push will create a new entry in the browser’s history and replace will just replace the current state. This way you will not find the back button enabled.

Some References:

1

2

3

4

Upvotes: 1

Related Questions