Is there a way to modify the page title with React-Router v4+?
<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> )}/>
In your componentDidMount()
method do this for every page
componentDidMount() { document.title = 'Your page title here';}
This will change your page title, do the above mentioned for every route.
Also if it is more then just the title part, check react-helmet It is a very neat library for this, and handles some nice edge cases as well.
Picking up from the excellent answer of phen0menon, why not extend Route
instead of React.Component
?
import React, { useEffect } from 'react';import { Route } from 'react-router-dom';import PropTypes from 'prop-types';const Page = ({ title, ...rest }) => { useEffect(() => { document.title = title; }, [title]); return <Route {...rest} />;};Page.propTypes = { title: PropTypes.string.isRequired,};export { Page };
This will remove overhead code as seen below:
// old:( <Route exact path="/" render={props => ( <Page {...props} component={Index} title="Index Page" /> )} />);// improvement:( <Page exact path="/" component={Index} title="Index Page" />);
Update: another way to do it is with a custom hook:
import { useEffect } from 'react';/** Hook for changing title */export const useTitle = title => { useEffect(() => { title && (document.title = title); }, [title]);};