I built a bit on Thierry Prosts solution and ended up with the following:
UPDATE January 2020: I've now updated my component to be in Typescript as well:
UPDATE August 2021: I've added my private route in TypeScript
import React, { FunctionComponent, useEffect } from 'react';
import { Route, RouteProps } from 'react-router-dom';
interface IPageProps extends RouteProps {
title: string;
}
const Page: FunctionComponent<IPageProps> = props => {
useEffect(() => {
document.title = "Website name | " + props.title;
});
const { title, ...rest } = props;
return <Route {...rest} />;
};
export default Page;
UPDATE: My Page.jsx component is now a functional component and with useEffect hook:
import React, { useEffect } from 'react';
import { Route } from 'react-router-dom';
const Page = (props) => {
useEffect(() => {
document.title = "Website name | " + props.title;
});
const { title, ...rest } = props;
return <Route {...rest} />;
}
export default Page;
Below you can find my initial solution:
// Page.jsx
import React from 'react';
import { Route } from 'react-router-dom';
class Page extends Route {
componentDidMount() {
document.title = "Website name | " + this.props.title;
}
componentDidUpdate() {
document.title = "Website name | " + this.props.title;
}
render() {
const { title, ...rest } = this.props;
return <Route {...rest} />;
}
}
export default Page;
And my Router implementation looked like this:
// App.js / Index.js
<Router>
<App>
<Switch>
<Page path="/" component={Index} title="Index" />
<PrivateRoute path="/secure" component={SecurePage} title="Secure" />
</Switch>
</App>
</Router>
Private route setup:
// PrivateRoute
function PrivateRoute({ component: Component, ...rest }) {
return (
<Page
{...rest}
render={props =>
isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/",
state: { from: props.location }
}}
/>
)
}
/>
);
}
Private Route in TypeScript:
export const PrivateRoute = ({ Component, ...rest }: IRouteProps): JSX.Element => {
return (
<Page
{...rest}
render={(props) =>
userIsAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: Paths.login,
state: { from: props.location },
}}
/>
)
}
/>
);
};
This enabled me to have both public areas update with a new title and private areas also update.
react-helmet
, it makes this sort of thing really easy – Cocksureconnected-react-router
. – Alexandra