Skip to content

Commit 25d33a5

Browse files
Merge pull request #5427 from topcoder-platform/route-redirects
Route redirects
2 parents 5e4a4ef + e92c162 commit 25d33a5

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ workflows:
283283
filters:
284284
branches:
285285
only:
286-
- gigwork-updates
286+
- route-redirects
287287
# This is alternate dev env for parallel testing
288288
- "build-qa":
289289
context : org-global

src/shared/components/Contentful/Route.jsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import LoadingIndicator from 'components/LoadingIndicator';
1010
import MetaTags from 'components/MetaTags';
1111
import PT from 'prop-types';
1212
import React from 'react';
13-
import { Route, Switch } from 'react-router-dom';
13+
import { Route, Switch, Redirect } from 'react-router-dom';
1414
import Viewport from 'components/Contentful/Viewport';
1515
import PasswordScreen from 'components/Contentful/PasswordScreen';
16+
import { isomorphy } from 'topcoder-react-utils';
1617

1718
// Concatenates a base and segment and handles optional trailing slashes
1819
const buildUrl = (base, segment) => `${_.trimEnd(base, '/')}/${_.trim(segment, '/')}`;
@@ -117,6 +118,29 @@ ChildRoutesLoader.propTypes = {
117118
url: PT.string.isRequired,
118119
};
119120

121+
function RedirectWithStatus({ from, to, status }) {
122+
return (
123+
<Route
124+
render={({ staticContext }) => {
125+
if (to[0] !== '/' && isomorphy.isClientSide()) {
126+
window.location.href = to;
127+
return null;
128+
}
129+
// there is no `staticContext` on the client, so
130+
// we need to guard against that here
131+
if (staticContext) staticContext.status = status;
132+
return <Redirect from={from} to={to} />;
133+
}}
134+
/>
135+
);
136+
}
137+
138+
RedirectWithStatus.propTypes = {
139+
from: PT.string.isRequired,
140+
to: PT.string.isRequired,
141+
status: PT.number.isRequired,
142+
};
143+
120144
export default function ContentfulRoute(props) {
121145
const {
122146
baseUrl,
@@ -145,7 +169,10 @@ export default function ContentfulRoute(props) {
145169
render={(data) => {
146170
const { fields } = Object.values(data.entries.items)[0];
147171
const url = path || buildUrl(baseUrl, fields.url);
148-
return (
172+
const redirectToUrl = _.trim(fields.redirectToUrl);
173+
return redirectToUrl ? (
174+
<RedirectWithStatus status={301} from={url} to={redirectToUrl} />
175+
) : (
149176
<Route
150177
/* This route prevents fetching data about child routes and their
151178
* rendering, if they already known to not match. */

src/shared/routes/index.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ function Routes({ communityId }) {
9797
path="/community/(competitive-programming|data-science|design|development|qa)/how-to-compete"
9898
/>
9999
<Redirect
100+
exact
100101
from="/community/gigs"
101102
to="/gigs"
102103
/>

0 commit comments

Comments
 (0)