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 JS 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"
}
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 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.
Works both on React Router 3 and 4.
I actually ended up building my own Component. <Redirect>
It takes info 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 incase-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;
EDIT -- NOTE:
This is with react-router: 3.0.5
, it is not so simple in 4.x
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
class RedirectPage extends React.Component {
componentDidMount(){
window.location.replace('http://www.google.com')
}
}
Using some of the info 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 should be fairly straight-forward 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'}
/>
I had luck with this:
<Route
path="/example"
component={() => {
global.window && (global.window.location.href = 'https://example.com');
return null;
}}
/>
FOR V3, although it may work for V4. Going off of Relic'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 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;
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
}}/>
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
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.
There is no need to use <Link />
component from react-router.
If you want to go to external link use an anchor tag.
<a target="_blank" href="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies">Policies</a>
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
using '//' before url seems to do the trick
<button onClick={() => {
let win = window.open('')
win.location.replace('//http://www.google.com')
}} >external link</button>
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 everytime 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 thats the redirect you are looking for. then just redirect through the server. ctx.redirect('https://example/com')
.
With Link component of react-router you can do that. In the "to" prop you can specify 3 types of data:
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.
©2020 All rights reserved.