2

I've recently had to change a path in my app, but I would like to preserve the validity of old deep links by redirecting them. Here's an example of a changed path:

Original: /foo/users/12345

Updated: /bar/users/12345

I tried to implement this using a redirect:

<Route path='/bar' component={MyComponent} />
<Route path='/foo'>
  <Redirect to='/bar' />
</Route>

However, the latter part of the request is lost in a redirect. So a request to /foo/users/12345 redirects to /bar.

Is there a declarative way to pass the /users/12345 portion of my path along in the redirect?

djfdev
  • 5,747
  • 3
  • 19
  • 38
  • I did not understand your question. Can you rephrase? do you want to change the path in the url but render a specific component for a different path? – Matthew Barbara Oct 09 '19 at 16:45
  • No, I basically want to redirect `/foo*` to `/bar*` where the portion matched by the splat is preserved. – djfdev Oct 09 '19 at 16:51
  • Having same issue with @djfdev, I'm not sure if there is another way than using replace by RegExp. I expect react-router should return the unmatch portion then I can use it to append to the redirect url – Quoc Van Tang Nov 24 '22 at 16:13

2 Answers2

2

I was looking into the documentation and I did not find any out of the box solution for this scenario what you were explaining in the question.

Instead of trying to use Redirect I have build a functional component which has been set as the component of the original route. This helps in redirect and can be used for this purpose like below:

<Route path='/foo/:users?/:id?' component={RedirectHelper}/>
<Route path='/bar/:users?/:id?' component={MyComponent}/>

The RedirectHelper looks like this:

const RedirectHelper = (props) => {
  const {history} = props;
  const path = history.location.pathname.replace('/foo', '');
  history.push(`/bar${path}`);
  return null;
}

So technically the RedirectHelper component picks up the value from the history.location.pathname property for the original ~foo/users/12345 URL and builds the new one. At the end it simply redirects to ~bar/users/12345 URL. The validity of the original one has been kept. I have tested out this solution and worked like charm.

Hope this helps!

norbitrial
  • 14,716
  • 7
  • 32
  • 59
  • Interesting ... this works exactly how I had hoped. Can you explain why I need to return an empty div? I notice that if I return undefined it doubles the new path segment and doesn't work correctly. – djfdev Oct 09 '19 at 17:42
  • @djfdev The `RedirectHelper` is still a component which needs to return either a valid HTML or `null`. The solution is just a workaround to make your requirement work. Good catch, let me update to `null`, I like that one better. I did additional test with `null` value, that worked as well. If the solution works and answers your question, feel free to accept as an answer, thanks. – norbitrial Oct 09 '19 at 17:57
1

What if you put a regex in your path

<Route path='/(bar|foo)/' component={MyComponent} />

As answered here

Matthew Barbara
  • 3,792
  • 2
  • 21
  • 32