I'm looking for a way to modify the page title when React-Router v4+ changes locations. I used to listen for a location change action in Redux and check that route against a metaData
object.
When using React-Router v4+, there's no fixed routes list. In fact, various components around the site could use Route
with the same path string. That means old method I used won't work anymore.
Is there a way I can update the page title by calling actions when certain major routes are changed or is there a better a better method to update the site's metadata?
<Route />
components have render property. So you can modify the page title when location changes by declaring your routes like that:
<Route
exact
path="/"
render={props => (
<Page {...props} component={Index} title="Index Page" />
)}
/>
<Route
path="/about"
render={props => (
<Page {...props} component={About} title="About Page" />
)}
/>
In Page
component you can set the route title:
import React from "react"
/*
* Component which serves the purpose of a "root route component".
*/
class Page extends React.Component {
/**
* Here, we define a react lifecycle method that gets executed each time
* our component is mounted to the DOM, which is exactly what we want in this case
*/
componentDidMount() {
document.title = this.props.title
}
/**
* Here, we use a component prop to render
* a component, as specified in route configuration
*/
render() {
const PageComponent = this.props.component
return (
<PageComponent />
)
}
}
export default Page
Update 1 Aug 2019. This only works with react-router >= 4.x. Thanks to @supremebeing7
Updated answer using React Hooks:
You can specify the title of any route using the component below, which is built by using useEffect
.
import { useEffect } from "react";
const Page = (props) => {
useEffect(() => {
document.title = props.title || "";
}, [props.title]);
return props.children;
};
export default Page;
And then use Page
in the render
prop of a route:
<Route
path="/about"
render={(props) => (
<Page title="Index">
<Index {...props} />
</Page>
)}
/>
<Route
path="/profile"
render={(props) => (
<Page title="Profile">
<Profile {...props} />
</Page>
)}
/>