I'm trying to update the title of the document in a React app. I have very simple needs for this. The title is essentially used to put the Total component on display even when you're on a different tab.
This was my first instinct:
const React = require('react'); export default class Total extends React.Component { shouldComponentUpdate(nextProps) { //otherstuff document.title = this.props.total.toString(); console.log("Document title: ", document.title); return true; } render() { document.title = this.props.total; return ( <div className="text-center"> <h1>{this.props.total}</h1> </div> ); } } I thought this would just update the document.title every time this component was rendered, but it doesn't appear to do anything.
Not sure what I'm missing here. Probably something to do with how React runs this function - maybe somewhere that the document variable isn't available?
EDIT:
I'm starting a bounty for this question, as I still haven't found any solution. I've updated my code to a more recent version.
A weird development is that the console.log does print out the title I'm looking for. But for some reason, the actual title in the tab isn't updating. This issue is the same across Chrome, Safari, and Firefox.
6 Answers
I now use react-helmet for this purpose, as it allows to customize different meta tags and links, and it also supports SSR.
import { Helmet } from 'react-helmet' const Total = () => ( <div className="text-center"> <Helmet> <meta charSet="utf-8" /> <title>{this.props.total}</title> </Helmet> <h1>{this.props.total}</h1> </div> ) Original answer: there's actually a package by gaeron for this purpose, but in a declarative way:
import React, { Component } from 'react' import DocumentTitle from 'react-document-title' export default class Total extends Component { render () { return ( <DocumentTitle title={this.props.total}> <div className='text-center'> <h1>{this.props.total}</h1> </div> </DocumentTitle> ) } } 5Inside your componentDidMount() function in App.js (or wherever), simply have:
componentDidMount() { document.title = "Amazing Page"; } The reason this works is anywhere in your react project you have access to the Js global scope. Go ahead and type window in your sites console. Basically everything there you will be able to access in your React project.
I think webpack-dev-server runs in an iframe mode by default:
So that might be why your attempts to set the title are failing. Try setting the inline option to true on webpack-dev-server, if you haven't already.
If the react-document-title package isn't working for you, the quick'n'dirty way to do that would be in a lifecycle method, probably both componentDidMount and componentWillReceiveProps (you can read more about those here):
So you would do something like:
const React = require('react'); export default class Total extends React.Component { // gets called whenever new props are assigned to the component // but NOT during the initial mount/render componentWillReceiveProps(nextProps) { document.title = this.props.total; } // gets called during the initial mount/render componentDidMount() { document.title = this.props.total; } render() { return ( <div className="text-center"> <h1>{this.props.total}</h1> </div> ); } } 1There is a better way of dynamically changing document title with react-helmet package.
As a matter of fact you can dynamically change anything inside <head> tag using react-helmet from inside your component.
const componentA = (props) => { return ( <div> <Helmet> <title>Your dynamic document/page Title</title> <meta name="description" content="Helmet application" /> </Helmet> .....other component content ); } To change title, meta tags and favicon dynamically at run time react-helmet provides a simple solution. You can also do this in componentDidMount using the standard document interface. In the example below I am using the same code for multiple sites, so helmet is looking for favicon and title from an environment variable
import { Helmet } from "react-helmet"; import { getAppStyles } from '../relative-path'; import { env } from '../relative-path'; <Helmet> <meta charSet="utf-8" /> <title>{pageTitle[env.app.NAME].title}</title> <link rel="shortcut icon" href={appStyles.favicon} /> </Helmet>