307

Since I'm using React Router to handle my routes in a React app, I'm curious if there is a way to redirect to an external resource.

Say someone hits:

example.com/privacy-policy

I would like it to redirect to:

example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies

I'm finding exactly zero help in avoiding writing it in plain JavaScript at my index.html loading with something like:

if (window.location.path === "privacy-policy"){
  window.location = "example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies"
}
11
  • 1
    Which React Router are you using? Commented Mar 20, 2017 at 21:55
  • 1
    I'm using version 3.x Commented May 16, 2017 at 0:10
  • 2
    Simply change window.location.href to have a formal redirection. Commented Mar 2, 2019 at 19:02
  • 4
    @AmirhosseinMehrvarzi that doesn't actually mean anything. Could you be more specific or give an example? Also I'm not sure if you've noticed but this question already has an accepted answer dealing with React & React Router which is what the question was about. Commented Mar 4, 2019 at 15:59
  • 1
    @Relic You need to use that as your url in your if condition. I had similar problem a few days ago and found this way simple and effective. It redirects immediately. Accepted answer is a Routing solution (While it violates Route principles, considering that Route architecture is for navigation inside the App not for outside) which doesn't work for any environment like mine Commented Mar 4, 2019 at 19:06

26 Answers 26

309

Here's a one-liner for using React Router to redirect to an external link:

<Route path='/privacy-policy' component={() => {
    window.location.href = 'https://example.com/1234';
    return null;
}}/>

It uses the React pure component concept to reduce the component's code to a single function that, instead of rendering anything, redirects browser to an external URL.

It works both on React Router 3 and 4.

7
  • 4
    This works but I was looking for a more elegant scalable solution. See what I came up with as it allowed me to go even further with redirects for MobileApps etc ( Not ReactNative, truly Native apps ). Now what I'm doing isn't the right way to solve my problem, but to solve this problem I suggest you investigate my solution as well if for nothing else than a different perspective. Commented Jun 16, 2017 at 19:13
  • 2
    This is not really that clean in my mind. I would rather use an anchor tag honestly. Second, hitting the back button on the browser returns you the route that then redirects back to example.zendesk.com/hc/en-us/articles/… Commented Sep 6, 2017 at 19:12
  • 28
    For better back button behavior (verify for your application), use window.location.replace('example.com')
    – MattC
    Commented Jul 17, 2018 at 13:53
  • 1
    None of the answers do, the original post was asking about client redirects only, WHILE being aware that there is no 301 or 302 type true redirect support. Commented Apr 7, 2019 at 19:16
  • 7
    window.location.href is not optimal. If the user clicks the browser 'back' button after being redirected, she will get to the route that will immediately redirect her again. To avoid this, better use window.location.replace(). Source: stackoverflow.com/a/506004/163411
    – targumon
    Commented Dec 17, 2020 at 14:51
171

With Link component of react-router you can do that. In the "to" prop you can specify 3 types of data:

  • a string: A string representation of the Link location, created by concatenating the location’s pathname, search, and hash properties.
  • an object: An object that can have any of the following properties:
    • pathname: A string representing the path to link to.
    • search: A string representation of query parameters.
    • hash: A hash to put in the URL, e.g. #a-hash.
    • state: State to persist to the location.
  • a function: A function to which current location is passed as an argument and which should return location representation as a string or as an object

For your example (external link):

https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies

You can do the following:

<Link to={{ pathname: "https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies" }} target="_blank" />

You can also pass props you’d like to be on the such as a title, id, className, etc.

6
  • 57
    Using pathname will not work, at least in the latest version. It will prepend the current base path anyway Commented Oct 22, 2021 at 6:19
  • @Lorenzo i have used it and it's working!
    – Muteshi
    Commented Nov 2, 2021 at 19:29
  • 10
    This didn't work for me.
    – hasser
    Commented Nov 25, 2021 at 17:13
  • 1
    Didn't worked for me in React-router 5
    – arslion
    Commented Dec 6, 2021 at 8:53
  • 8
    No dice with v6.2.1
    – jonlink
    Commented Mar 18, 2022 at 21:50
149

There isn’t any need to use the <Link /> component from React Router.

If you want to go to external link use an anchor tag.

<a target='_blank'
            rel='noopener noreferrer' href="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies">Policies</a>

Use the rel=”noopener” or rel=”noreferrer” link attributes for every link. The rel=”noreferrer” link attribute also functions the same as the “noopener” link attribute in that it prevents the linked site from taking control of the linking site.

9
  • 54
    The OP was asking how to do it programmatically, not declaratively Commented Oct 31, 2017 at 19:23
  • 49
    Unrelated & misleading answer. Commented May 22, 2019 at 10:58
  • 22
    If you do use this, add rel="noopener noreferrer" to the <a>
    – S..
    Commented Jan 29, 2020 at 16:00
  • 28
    Good answer, not everyone will care as long as they get it work. Commented Jul 8, 2020 at 18:48
  • 14
    Good point! react-router is designed to handle inside-application navigation, so, although it is possible to create a custom element, external links should be made with a simple anchor tag.
    – Shahriar
    Commented Feb 24, 2021 at 17:50
91

It doesn't need to request React Router. This action can be done natively and it is provided by the browser.

Just use window.location.

With React Hooks

const RedirectPage = () => {
  React.useEffect(() => {
    window.location.replace('https://www.google.com')
  }, [])
}

With React Class Component

class RedirectPage extends React.Component {
  componentDidMount(){
    window.location.replace('https://www.google.com')
  }
}

Also, if you want to open it in a new tab:

window.open('https://www.google.com', '_blank');
6
  • 3
    This answer is incomplete, doesn't allow for abstraction or it's relation to the router Commented Dec 3, 2018 at 21:30
  • 27
    This is the goal. It doesn't need to request react router. This action can be done natively and it is provided by the browser.
    – Alan
    Commented Dec 4, 2018 at 23:56
  • 1
    What if we want to pass the URL also dynamically along with HTTP Status code while redirecting to external site. I got some example, but its not clear with my requirement. gist.github.com/arasmussen/f2c01dc858481590f6bffae6b540632c Commented Sep 9, 2020 at 15:11
  • 2
    I think this should be accepted answer. probably the url could be exposed as a prop. Commented Nov 16, 2021 at 14:27
  • 1
    I just used the window.open() way inside an onClick function. Thank you! Commented Aug 29, 2022 at 17:30
52

I actually ended up building my own Component, <Redirect>. It takes information from the react-router element, so I can keep it in my routes. Such as:

<Route
  path="/privacy-policy"
  component={ Redirect }
  loc="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies"
  />

Here is my component in case anyone is curious:

import React, { Component } from "react";

export class Redirect extends Component {
  constructor( props ){
    super();
    this.state = { ...props };
  }
  componentWillMount(){
    window.location = this.state.route.loc;
  }
  render(){
    return (<section>Redirecting...</section>);
  }
}

export default Redirect;

Note: This is with react-router: 3.0.5, it is not so simple in 4.x

5
  • you don't HAVE to do anything, react is a framework, and there is a lot of value in a framework. THIS is how to do it within the react framework. It DOES NOT however take into account the browser history module that could be wrapped in here to, making this even more useful. Also Please note "window.location" is how it was done in 1999. This is just a way to add it to your routes table for client side routing. It's not a "good" solution. Commented Jul 3, 2017 at 17:37
  • in react -router v4 you can use render instead component
    – Irrech
    Commented Feb 22, 2018 at 13:39
  • 4
    @Irrech "render instead component" means nothing. If you have an answer to the question please add it and give some detail of how you would implement. Commented Feb 27, 2018 at 17:16
  • 5
    @MuhammadUmer or you just use an anchor tag. react-router is pretty strictly meant for routing just within your application. you can disagree with that design decision (i know i do), but it's not "done better in 1999", it's just done the same.
    – worc
    Commented Oct 2, 2018 at 18:10
  • What if we want to pass the URL also dynamically along with HTTP Status code while redirecting to external site. I got some example, but its not clear with my requirement gist.github.com/arasmussen/f2c01dc858481590f6bffae6b540632c Commented Sep 9, 2020 at 15:11
9

Using some of the information here, I came up with the following component which you can use within your route declarations. It's compatible with React Router v4.

It's using TypeScript, but it should be fairly straightforward to convert to native JavaScript:

interface Props {
  exact?: boolean;
  link: string;
  path: string;
  sensitive?: boolean;
  strict?: boolean;
}

const ExternalRedirect: React.FC<Props> = (props: Props) => {
  const { link, ...routeProps } = props;

  return (
    <Route
      {...routeProps}
      render={() => {
        window.location.replace(props.link);
        return null;
      }}
    />
  );
};

And use with:

<ExternalRedirect
  exact={true}
  path={'/privacy-policy'}
  link={'https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies'}
/>
8

I went through the same issue. I want my portfolio to redirect to social media handles. Earlier I used {Link} from "react-router-dom". That was redirecting to the sub directory as here,

enter image description here

Link can be used for routing web pages within a website. If we want to redirect to an external link then we should use an anchor tag. Like this,

enter image description here

3
  • 6
    Please use text, not pictures of text for code and any text-based information (like URLs). Commented May 22, 2022 at 20:33
  • Please review Why not upload images of code/errors when asking a question? (e.g., "Images should only be used to illustrate problems that can't be made clear in any other way, such as to provide screenshots of a user interface.") and do the right thing (it covers answers as well). Thanks in advance. Commented Dec 13, 2022 at 1:07
  • This doesn't actually redirect. This creates an HTML tag the needs to be clicked by the user in order for them to be redirected. Commented Mar 21, 2023 at 23:03
8

The simplest solution is to use a render function and change the window.location.

<Route path="/goToGoogle"
       render={() => window.location = "https://www.google.com"} />

If you want a small reusable component, you can just extract it like this:

const ExternalRedirect = ({ to, ...routeProps }) => {
   return <Route {...routeProps} render={() => window.location = to} />;
};

and then use it (e.g. in your router switch) like this:

<Switch>
    ...
    <ExternalRedirect exact path="/goToGoogle" to="https://www.google.com" />
</Switch>
3
  • 1
    will the <Redirect to="google.com" /> work? Commented Nov 17, 2021 at 17:13
  • Is there a reason I don't know of why this is better than <a href=''></a> using the back button from the external destination for example?
    – Andy
    Commented Jan 29, 2022 at 23:22
  • Writing a component might help you some day. If the way you redirect should be changed you only need to change the ExternalRedirect component. E.g. you want to display a confirmation dialog before redirecting: "You will be redirected to ... Continue?"
    – René Link
    Commented Jan 30, 2022 at 9:59
6

I had luck with this:

<Route
    path="/example"
    component={() => {
        global.window && (global.window.location.href = 'https://example.com');
        return null;
    }}
/>
0
6

Complementing Víctor Daniel's answer here: Link's pathname will actually take you to an external link only when there's the 'https://' or 'http://' before the link.

You can do the following:

<Link to={{ pathname:
> "https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies"
> }} target="_blank" />

Or if your URL doesn't come with 'https://', I'd do something like:

<Link to={{pathname:`https://${link}`}} target="_blank" />

Otherwise it will prepend the current base path, as Lorenzo Demattécommented.

2
  • If you remove option - target="_blank", you will get problem. Commented Sep 6, 2022 at 9:44
  • 1
    this is not working for me with "react-router-dom": "^6.4.0",
    – Shamseer
    Commented Sep 25, 2022 at 18:38
6

I solved this on my own (in my web application) by adding an anchor tag and not using anything from React Router, just a plain anchor tag with a link as you can see in the picture screenshot of using anchor tag in a React app without using React Router

Basically, you are not routing your user to another page inside your app, so you must not use the internal router, but use a normal anchor.

Although this is for a non-react-native solution, but you can try.

1
  • funny how React makes you forget HTML/css basics...
    – Andy
    Commented Jan 27, 2023 at 17:06
5

In React Route V6 render props were removed. It should be a redirect component.

RedirectUrl:

const RedirectUrl = ({ url }) => {
  useEffect(() => {
    window.location.href = url;
  }, [url]);

  return <h5>Redirecting...</h5>;
};

Route:

<Routes>
   <Route path="/redirect" element={<RedirectUrl url="https://google.com" />} />
</Routes>
4

In React Router v6, component is unavailable. Instead, now it supports element. Make a component redirecting to the external site and add it as shown.

import * as React from 'react';
import { Routes, Route } from "react-router-dom";

function App() {
  return(
    <Routes>
      // Redirect
      <Route path="/external-link" element={<External />} />
    </Routes>
  );
}

function External() {
  window.location.href = 'https://google.com';
  return null;
}

export default App;
4

I think the best solution is to just use a plain old <a> tag. Everything else seems convoluted. React Router is designed for navigation within single page applications, so using it for anything else doesn't make a whole lot of sense. Making an entire component for something that is already built into the <a> tag seems... silly?

1
  • 2
    React makes you ask questions like 'how do I add an image to Web Page'
    – Andy
    Commented Jan 29, 2022 at 23:21
1

To expand on Alan's answer, you can create a <Route/> that redirects all <Link/>'s with "to" attributes containing 'http:' or 'https:' to the correct external resource.

Below is a working example of this which can be placed directly into your <Router>.

<Route path={['/http:', '/https:']} component={props => {
  window.location.replace(props.location.pathname.substr(1)) // substr(1) removes the preceding '/'
  return null
}}/>
1

I don't think React Router provides this support. The documentation mentions

A < Redirect > sets up a redirect to another route in your application to maintain old URLs.

You could try using something like React-Redirect instead.

1
  • React-Redirect is deprecated
    – Aifoz
    Commented Oct 16, 2020 at 7:05
1

I was facing the same issue and solved it using by http:// or https:// in React.

Like as: <a target="_blank" href="http://www.example.com/" title="example">See detail</a>

1
  • 1
    I guess that we are looking for a solution within react-router
    – felix
    Commented Oct 13, 2021 at 17:47
0

For V3, although it may work for V4. Going off of Eric's answer, I needed to do a little more, like handle local development where 'http' is not present on the URL. I'm also redirecting to another application on the same server.

Added to the router file:

import RedirectOnServer from './components/RedirectOnServer';

<Route path="/somelocalpath"
       component={RedirectOnServer}
       target="/someexternaltargetstring like cnn.com"
/>

And the Component:

import React, { Component } from "react";

export class RedirectOnServer extends Component {

  constructor(props) {
    super();
    // If the prefix is http or https, we add nothing
    let prefix = window.location.host.startsWith("http") ? "" : "http://";
    // Using host here, as I'm redirecting to another location on the same host
    this.target = prefix + window.location.host + props.route.target;
  }
  componentDidMount() {
    window.location.replace(this.target);
  }
  render(){
    return (
      <div>
        <br />
        <span>Redirecting to {this.target}</span>
      </div>
    );
  }
}

export default RedirectOnServer;
0

I am offering an answer relevant to React Router v6 to handle dynamic routing.

I created a generic component called redirect:

export default function Redirect(params) {
  window.location.replace('<Destination URL>' + "/." params.destination);

  return (
    <div />

  )
}

I then called it in my router file:

<Route path='/wheretogo' element={<Redirect destination="wheretogo"/>}/>
0

You can use for your dynamic URL:

<Link to={{pathname:`${link}`}}>View</Link>
2
  • 6
    did not work for me, using react router v6
    – afikri
    Commented Jun 17, 2022 at 6:37
  • can confirm this won't work with react router v5.3 and above
    – Oli C
    Commented Dec 1, 2022 at 13:11
0

Save this html page on your disk with the name ExampleLinkReact.html,

and open it with your browser, say chromium 115.

<!DOCTYPE html>
<html>
  <head>
    <meta charset='UTF-8'>
    <title>ExampleLinkReact</title>
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src='https://unpkg.com/[email protected]/umd/react-router-dom.min.js'></script>
    <script src='https://unpkg.com/[email protected]/babel.js'></script>
    

  </head>
  <body>
    <div id='root'></div>
    <script type='text/babel'>
      const Link = ReactRouterDOM.Link;
      const Route = ReactRouterDOM.Route;

      const ExampleLinkReact = () => (
      
<div style={removeallstyles}> {/*1*/}
 <div style={container100postlist}>         
    
    <p style={style_label}> ExampleLinkReact </p>
    <div style={hspace3}> </div>
    <p> Open every link in new tab</p>

    
  <div style={block1}>  
  <ReactRouterDOM.HashRouter>
     <ul style={ulist_style}>
      <li><Link to="/InnerComponent">InnerComponent</Link></li>
      <li><Link to='/LocalHTMLPage'>LocalHTMLPage</Link></li>
      <li><Link to='/LinkExternalUrl'>LinkExternalUrl</Link></li>
    </ul>


    
    <Route path="/InnerComponent" exact component={InnerComponent} />
    <Route exact path="/LocalHTMLPage" render={() => {window.location.href="LocalHTMLPage.html"}} />
    <Route exact path="/LinkExternalUrl" render={() => {window.location.href="https://example.com/1234"}} />
  </ReactRouterDOM.HashRouter>
    
    
    
    <div style={hspace3}> </div>
  </div> {/*block1 end*/}

  {/*/////////////////////////////////////////////////////////////////////////////////////*/}
  {/*/////////////////////////////////////////////////////////////////////////////////////*/}
    

    
    </div> {/*container100postlist*/}
</div> /*removeallstyles*/
      )

      
      //define InnerComponent
      const InnerComponent = () => <h1>InnerComponent</h1>

      
      
/////////////////////////////////////////////////////////////////////////////////// 
 {/*CSS CODE START. */}
 //This is only elementary css, you can ignore it;

 const removeallstyles = { all: 'revert',}
 const hspace3={height: 0.05*window.innerHeight, backgroundColor: 'transparent', position: 'relative'}; 
 const vhspace1={width: 0.05*window.innerWidth, backgroundColor: 'transparent', position: 'inline-block'};  
 
 
 
    
 
 
 //container100postlist     
 const container100postlist_width =94;
 const container100postlist_border=1;   
 const container100postlist  =
 {
    //margin:'0 auto',    
    //textAlign: 'center',
    position: 'absolute',
    width: container100postlist_width+'vw',
    backgroundColor:'transparent',  
    display: 'block',
    clear: 'both',
 };

 
 
 
 const style_label =
 {
    backgroundColor:'transparent',  
    marginTop: '1vh',
    marginBottom: '1vh',
    textAlign: 'left',
    display: 'block',
    clear: 'both',
    position: 'relative',
    fontWeight: 'bold',   
 };
 
 
    

 var block1 =
  {
    textAlign: 'left',
    float: 'left',
    display: 'block',
    clear: 'both',
    padding: '0.5vw',
    //height: '40%',
    width: '97vw',
    //backgroundColor:'red',    
    border: '0.1vh solid red',    
  };



  
 const ulist_style =
 {
    //listStyle: 'none',
    listStylePosition: 'inside',
    paddingLeft: '1vw',
 }



 {/*CSS CODE END. */}


/////////////////////////////////////////////////////////////////////////////////// 
      
      
      
      ReactDOM.render(<ExampleLinkReact />, document.querySelector('#root'));
    </script>
  </body>
</html> 

-1
import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";

function App() {
  return (
    <Router>
      <Route path="/" exact>
        {window.location.replace("http://agrosys.in")}
      </Route>
    </Router>
  );
}

export default App;
1
  • 2
    Please add some comments, and not only code, so that people will know what is happening
    – Timberman
    Commented Jan 11, 2022 at 23:46
-1

Using React with TypeScript, you get an error as the function must return a React element, not void. So I did it this way using the Route render method (and using React router v4):

redirectToHomePage = (): null => {
    window.location.reload();
    return null;
};

<Route exact path={'/'} render={this.redirectToHomePage} />

Where you could instead also use window.location.assign(), window.location.replace(), etc.

-2

If you are using server-side rending, you can use StaticRouter. With your context as props and then adding <Redirect path="/somewhere" /> component in your app. The idea is every time React Router matches a redirect component it will add something into the context you passed into the static router to let you know your path matches a redirect component.

Now that you know you hit a redirect you just need to check if that’s the redirect you are looking for. then just redirect through the server. ctx.redirect('https://example/com').

2
  • I'm asking for a way to do it in the client. It actually should be done at the DNS level if done correctly. Second would be in the initial server request. Since I'm hosting on S3, there is no server-side. SO I'm stuck for now until our dev-ops guy can do the redirect at the Service Level. Commented Mar 23, 2017 at 22:34
  • what you can do is, <Redirect push={ true } to="/pathtoredirect" />
    – Rei Dien
    Commented Mar 23, 2017 at 22:39
-4

You can now link to an external site using React Link by providing an object to to with the pathname key:

<Link to={ { pathname: '//example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies' } } >

If you find that you need to use JavaScript to generate the link in a callback, you can use window.location.replace() or window.location.assign().

Over using window.location.replace(), as other good answers suggest, try using window.location.assign().

window.location.replace() will replace the location history without preserving the current page.

window.location.assign() will transition to the URL specified, but will save the previous page in the browser history, allowing proper back-button functionality.

location.replace()

location.assign()

Also, if you are using a window.location = url method as mentioned in other answers, I highly suggest switching to window.location.href = url.

There is a heavy argument about it, where many users seem to adamantly want to revert the newer object type window.location to its original implementation as string merely because they can (and they egregiously attack anyone who says otherwise), but you could theoretically interrupt other library functionality accessing the window.location object.

Check out this conversation. It's terrible. JavaScript: Setting location.href versus location

0
-5

I was able to achieve a redirect in react-router-dom using the following

<Route exact path="/" component={() => <Redirect to={{ pathname: '/YourRoute' }} />} />

For my case, I was looking for a way to redirect users whenever they visit the root URL http://myapp.com to somewhere else within the app http://myapp.com/newplace. so the above helped.

4
  • 3
    The OP clearly states that he's trying to redirect to an external resource, not to a route inside the same app.
    – Neets
    Commented Mar 14, 2019 at 17:00
  • Clearly, I was specific about my use case and dropped that if he could apply it to his. my solution says within my app, he could use that as an example.
    – walecloud
    Commented Mar 19, 2019 at 3:11
  • 2
    If you want to showcase your use case to people, please write a blog about it. Stackoverflow is for answering the query that people have, not your use-case. Also, the right way to implement your use case is - <Redirect from="/" to={{ pathname: '/YourRoute' }} />
    – Abhas
    Commented Aug 5, 2020 at 21:16
  • I found this very helpful in understanding that react-routers <Redirect component probably won't work well when redirecting to an external url. Thank you for sharing @walecloud - I may not have found this if it was in a blog post. Commented Jul 14, 2021 at 16:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.