Declarative, nested, stateful, isomorphic document.title for React

Last update: Jun 17, 2022

React Document Title

Provides a declarative way to specify document.title in a single-page app.
This component can be used on server side as well.

Built with React Side Effect.

Installation

npm install --save react-document-title

Dependencies: React >= 0.13.0

Features

  • Does not emit DOM, not even a <noscript>;
  • Like a normal React compoment, can use its parent's props and state;
  • Can be defined in many places throughout the application;
  • Supports arbitrary levels of nesting, so you can define app-wide and page-specific titles;
  • Works just as well with isomorphic apps.

Example

Assuming you use something like react-router:

function App() {
  // Use "My Web App" if no child overrides this
  return (
    <DocumentTitle title='My Web App'>
      <SomeRouter />
    </DocumentTitle>
  );
}

function HomePage() {
  // Use "Home" while this component is mounted
  return (
    <DocumentTitle title='Home'>
      <h1>Home, sweet home.</h1>
    </DocumentTitle>
  );
}

class NewArticlePage extends React.Component {
  constructor(props) {
    super(props);
    this.state = { title: 'Untitled' };
  }

  render() {
    // Update using value from state while this component is mounted
    return (
      <DocumentTitle title={this.state.title}>
        <div>
          <h1>New Article</h1>
          <input
            value={this.state.title}
            onChange={(e) => this.setState({ title: e.target.value })}
          />
        </div>
      </DocumentTitle>
    );
  }
}

Server Usage

If you use it on server, call DocumentTitle.rewind() after rendering components to string to retrieve the title given to the innermost DocumentTitle. You can then embed this title into HTML page template.

Because this component keeps track of mounted instances, you have to make sure to call rewind on server, or you'll get a memory leak.

But What About Meta Tags?

Looking for something more powerful? Check out React Helmet!

GitHub

https://github.com/gaearon/react-document-title
Comments
  • 1. Expand support and rename project

    I've been using react-document-title for an isomorphic project and quickly discovered that most of the pages that are being rendered on the server could use generated metadata such as description and Open Graph.

    I'm proposing renaming the project to react-document-metadata and expand usage to arbitrary props in addition to title:

    <Metadata
      title="My fine page"
      opengraph={{image: this.state.image.url}}
      description={this.getDescription()} />
    

    Naturally only title would be read by the browser for updating window.title but it could also be expanded to support things like dynamic favicons.

    Thoughts?

    Reviewed by simenbrekken at 2014-11-20 12:41
  • 2. Race conditions

    Since 'mountedInstances' is a static property on DocumentTitle it's shared state across all requests. Doesn't this cause race conditions? I'm not sure I totally get how it works yet (i'm new to nodejs and react too).

    Reviewed by qamil at 2015-01-06 16:30
  • 3. Node compatibility (fixes #1)

    I've taken the liberty to add a couple of tests to make sure the component behaves as it should.

    You were right about the life cycle implications of componentDidMount, apparently componentDidMount bubbles up while componentWillMount trickles down. I'm guessing this is because componentDidMount expects the component's children to be fully initialized and this is the only way to accomplish that.

    Instead I've just added a simple typeof check to bail out when document is not defined. As this is a global variable, typeof is the only way to determine its existence without causing a reference error.

    I wasn't able to reproduce the issue with addons.Children.only, so I've not touched that code.

    I've also added a lint script so you can run jshint with npm run lint without having to install it globally.

    Emulating a browser via the global module is probably not the most reliable way to test the browser behaviour, but adding a browser test runner as dependency seems overkill.

    Reviewed by pluma at 2014-10-23 11:53
  • 4. Check if title should be updated

    This change prevents the document.title of being updated regardless if it had changed or not.

    When using DocumentTitle today, any time some child component updates, the current document.title updates as well, and it shouldn't.

    Reviewed by buzinas at 2016-05-26 17:35
  • 5. Node compatibility

    According to React's component reference, componentWillMount will also be run on the server. This means bad things will happen (namely, it will attempt to access document on the server, which likely throws an exception).

    ~~I don't see any reason not to use componentDidMount instead.~~

    EDIT: See PR #2 for why we can't use componentDidMount for this component.

    Reviewed by pluma at 2014-10-22 15:44
  • 6. Want to use this module in server, and want to ask

    according to this line https://github.com/gaearon/react-document-title/blob/master/index.js#L6

    It seems to me that the _serverTitle is singleton for whole server. isn't it?

    Reviewed by ericfong at 2015-06-02 09:39
  • 7. Use packages to prevent React v15.5.0 and up from complaining about deprecated API's

    To prevent React>=15.5.0 from throwing warnings we can't use React.createClass or React.PropTypes directly. For both there are now separate packages on npm. In case of createClass the recommendation is to convert to a ES6 class, however that's a bit more of an involved change. Instead, I reckon we can get this version out and silence those warnings first and then tackle a conversion to ES6 class separately.

    Note: linter and all tests pass, but a warning is thrown by React during tests about calling a used PropType directly. However, I can't seem to figure out why, so it's probably caused by react-side-effect?

    Reviewed by JaapRood at 2017-04-10 03:03
  • 8. As high order component

    Initial idea:

    @title(props => `${props.user.name}'s page`)
    class SomeComponent extends Component {
    }
    

    Has its downsides. One obvious example:

    // works
    class SomeComponent extends Component {
      render() {
        return (
          <DocumentTitle title={`{this.state.user}'s profile`}>
            ..
          </DocumentTitle>
        );
      }
    }
    
    // won't work in the proposed api
    @title(...)
    class SomeComponent extends Component {
      render() {
        return (
          ..
        );
      }
    }
    

    But this doesn't happen very happen often, and I don't think it should. See Smart and Dumb Components.

    Would send a PR if this is okay.


    Awesome work by the way, @gaearon!

    Reviewed by srph at 2015-09-09 04:29
  • 9. How to get started?

    Sorry for the newbie question, but I'm having trouble getting this running.

    I've run npm install --save react-document-title

    Then I tried require('../../node_modules/react-document-title/index.js') from my main.js file, then use webpack or browserify to create a bundle.js and link that in instead of the main.js file, but it says Uncaught ReferenceError: DocumentTitle is not defined in my JSX file.

    I see that the bundle is loaded in the browser, and I can see the react-document-title code in the bundle, but it's not available to my JSX for some reason. It's probably a rookie mistake, but I'm stumped. Hope you can give any pointers.

    Cheers

    Example source code:

    index.html

        <script src="https://fb.me/react-with-addons-0.13.3.js"></script>
        <script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/0.13.3/ReactRouter.min.js"></script>
        <script src="~/src/js/bundle.js"></script>
        <script type="text/jsx" src="~/Content/lib/jsx/main.jsx"></script>
    

    main.js

    'use strict'
    
    var DocumentTitle = require('../../node_modules/react-document-title/index.js');
    

    main.jsx

    var Router = ReactRouter;
    var DefaultRoute = Router.DefaultRoute;
    var Link = Router.Link;
    var Route = Router.Route;
    var RouteHandler = Router.RouteHandler;
    
    var App = React.createClass({
        render: function() {
            return (
                <DocumentTitle title='Home'>
                    <this.props.activeRouteHandler />
                    <div id="wrapper">
                    </div>
                </DocumentTitle>
            );
        }
    });
    
    Reviewed by angularsen at 2015-05-18 23:25
  • 10. emitting '' to DOM

    React = require('react'),
    DocumentTitle = require('react-document-title');
    var Component = React.createClass({
          render: function () {
            return React.createElement(DocumentTitle, {title: 'irrelevant'} );
          }
    });
    
    var markup = React.renderToStaticMarkup(React.createElement(Component));
    

    this is a slightly modified logic of https://github.com/gaearon/react-document-title/blob/master/test/common.js#L9.

    it is emitting '' as its markup.

    I assume it is a bug since we are claiming in README.md that it doesn't emit anything to DOM

    Reviewed by goldensunliu at 2015-07-13 17:23
  • 11. Allow 0.13 beta

    I think this works, with inspiration from Omniscient: https://github.com/omniscientjs/omniscient/blob/b6ab57f7fa64886370b2a8ef5e64ff91eac30ad2/package.json

    Reviewed by natew at 2015-02-22 06:16
  • 12. When I use it.Why components has been an empty object at this.props?

    May be can't use it like this?

    <Route path="/path"
         render={() => (
          <DocumentTitle title="title">
                  <Component/>
          </DocumentTitle>
     )} />
    
    Reviewed by lujdong at 2019-07-25 05:55
  • 13. Issues with importing when using TypeScript

    Using TypeScript and @types/react-document-title.

    I'm trying to do import * as DocumentTitle from 'react-document-title'; but in my render() I get [ts] JSX element type 'DocumentTitle' does not have any construct or call signatures.

    I tried import DocumentTitle from 'react-document-title'; and the page won't load properly.

    export class Test extends React.Component<{}, {}> {
      render() {
        return (
          <DocumentTitle title="Hey">
            Test
          </DocumentTitle>
        );
      }
    }
    
    Reviewed by julianguyen at 2018-07-18 23:55
  • 14. Only set prop types in non-production builds.

    This will enable a bundler to omit the prop-types import. I don't think any tool is set up to actually do this (recognize the import is unused and eliminate it before bundling) but it'll save a few bytes either way.

    Reviewed by realityking at 2018-06-17 20:09
  • 15. DocumentTitle is undefined when running tests

    When using this library with TypeScript, I am encountering errors when running tests:

    import DocumentTitle from 'react-document-title';
    
    // ...
    
    renderToString(
                        <DocumentTitle title="Hello World">
                            <AppComponen/>
                        </DocumentTitle>
    );
    

    My typings file:

    // @types/react-document-title.d.ts
    
    declare module 'react-document-title' {
        import * as React from 'react';
    
        interface DocumentTitleProps {
            title: string;
        }
    
        export default class DocumentTitle extends React.Component<DocumentTitleProps, any> {
            public static rewind(): string;
            public static peek(): string;
        }
    }
    
    

    This code runs perfectly fine when executed on the server, but during testing it fails:

    Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

    Debugging shows that the import of react-document-title simply returns undefined when using jest, but the proper class when running the server.

    Does anybody know what might be the cause of this?

    Reviewed by Birne94 at 2018-06-11 10:03
  • 16. Readme file Reservations

    I'm a bit confused by Readme of this library.

    Can be defined in many places throughout the application

    I'm surprised because though the document title can change many times, at any given time there is only one title. Isn't using DocumentTitle component in various places throught the application, splitting the logic of the aplication?

    Reviewed by carpben at 2018-05-24 08:09
A document head manager for React
A document head manager for React

React Helmet This reusable React component will manage all of your changes to the document head. Helmet takes plain HTML tags and outputs plain HTML t

Jun 22, 2022
🎯 React component for transportation of modals, lightboxes, loading bars... to document.body or else.

React-portal Struggling with modals, lightboxes or loading bars in React? React-portal creates a new top-level React tree and injects its children int

Jun 24, 2022
Complete token authentication system for react + redux that supports isomorphic rendering.
Complete token authentication system for react + redux that supports isomorphic rendering.

Simple, secure authentication for react + redux TL;DR - View the Live Demo You can see a complete working example here. The code for the demo is here.

May 27, 2022
Isomorphic application written in React
Isomorphic application written in React

Isomorphic "Quiz Wall" for itsquiz.com Motivation There are a lot of tutorials and boilerplates showing how to write isomorphic ReactJs applications.

Jun 9, 2022
Appends a new DOM node to the end of the `document.body` and renders it's child React tree into it.

@react-lit/portal Appends a new DOM node to the end of the document.body and renders it's child React tree into it. Useful to break out of the DOM hie

Dec 9, 2021
Document Management System API Backend

Document Management System View on Pivotal Tracker The system manages documents, users and roles. Each document defines access rights i.e. which roles

Oct 1, 2021
Simple declarative and universal A/B testing component for React.
Simple declarative and universal A/B testing component for React.

react-ab Simple declarative and universal A/B testing component for React. Demo Install npm install react-ab --save or bower install react-ab --save E

May 22, 2022
:tada: React Universal Hooks : just use****** everywhere (Functional or Class Component). Support React DevTools!
:tada: React Universal Hooks : just use****** everywhere (Functional or Class Component). Support React DevTools!

react-universal-hooks React Universal Hooks : just use****** everywhere. Support React >= 16.8.0 Installation Using npm: $ npm install --save react-un

Jun 12, 2022
React ESI: Blazing-fast Server-Side Rendering for React and Next.js
React ESI: Blazing-fast Server-Side Rendering for React and Next.js

React ESI: Blazing-fast Server-Side Rendering for React and Next.js React ESI is a super powerful cache library for vanilla React and Next.js applicat

Jun 18, 2022
30 Days of React challenge is a step by step guide to learn React in 30 days
30 Days of  React challenge is a step by step guide to learn React in 30 days

30 Days of React challenge is a step by step guide to learn React in 30 days. It requires HTML, CSS, and JavaScript knowledge. You should be comfortable with JavaScript before you start to React. If you are not comfortable with JavaScript check out 30DaysOfJavaScript. This is a continuation of 30 Days Of JS. This challenge may take up to 100 days, follow your own pace.

Jun 27, 2022
React Navigation for React js that tries to ensure that the elements of the navigators display correctly on devices with notches and UI elements which may overlap the app content.
React Navigation for React js that tries to ensure that the elements of the navigators display correctly on devices with notches and UI elements which may overlap the app content.

React Navigation for React js that tries to ensure that the elements of the navigators display correctly on devices with notches (e.g. iPhone X) and UI elements which may overlap the app content.

Dec 7, 2021
React People lists and connects React developers around the world.

React People React People lists and connects React developers around the world. Progress View the Project page for details on what's planned and what'

Jun 14, 2022
React Backbone Binding that works with React 16

WithBackbone React Higher Order Component which will bind Backbone Data that works with React Fiber (v.16) Why did we make it There are already a coup

Mar 19, 2021
A description of React's new core algorithm, React Fiber

React Fiber Architecture Introduction React Fiber is an ongoing reimplementation of React's core algorithm. It is the culmination of over two years of

Jun 22, 2022
React Clone - How React Works: An In-Depth Guide
React Clone - How React Works: An In-Depth Guide

Как работает React: подробное руководство Привет, друзья! В этой статье я покажу вам, с чего начинается React. Что это означает? Это означает, что мы

Nov 25, 2021
A drum machine built with React using the Create React App toolchain.

drum-machine A simple drum machine built with React using the Create React App toolchain. Getting Started Clone or download the repository. Open a com

Dec 30, 2021
React-Login-app - Create a Login and Registration Page with React Router
React-Login-app - Create a Login and Registration Page with React Router

About In this repo I was given a Task to create a Login and Registration page wh

Dec 31, 2021
Insomnia-react-app - A react app that will help you relax and sleep better
Insomnia-react-app - A react app that will help you relax and sleep better

insomnia - a sleep inducer app An app that will help you relax and sleep better.

May 30, 2022
React-three-ts-bp - [TS] Stable version for React-Three + Spring & Tailwind bp

React-three-ts-bp - [TS] Stable version for React-Three + Spring & Tailwind bp

Jan 3, 2022