Skip to content

Repository files navigation

React Title Component

Nested document title management for React.

Installation

Using npm:

$ npm install react-title-component

Then with a module bundler like webpack that supports either CommonJS or ES2015 modules, use as you would anything else:

// using an ES6 transpiler, like babelimportTitle,{flushTitle}from'react-title-component'// not using an ES6 transpilervarReactTitle=require('react-title-component')varTitle=ReactTitle.defaultvarflushTitle=ReactTitle.flushTitle

The UMD build is also available on npmcdn:

<scriptsrc="https://npmcdn.com/react-title-component/umd/ReactTitleComponent.min.js"></script>

You can find the library on window.ReactTitle.

Usage

<Titlerender="My Title"/>// `document.title` will now be "My Title"

That's nice, but the idea is that you don't want just one component participating in the title of the document. As nested components come in and out of the UI, you often want to append (or prepend) to the current title.

// First instance of `Title`<Titlerender="My Title"/>// Lower in the view hierarchy, another `Title` is rendered.// If you pass it a function you'll get the previous title's value,// so you can append, prepend, or ignore it.<Titlerender={previousTitle=>`${previousTitle} - More Title`}/>// the title, if both of those are rendered, will be:// "My Title - More Title"

It ends up looking something like this:

importReactfrom'react'import{render}from'react-dom'importTitlefrom'react-title-component'constApp=React.createClass({render(){return(<div><Titlerender="Awesome Website"/><DeeperPage/>{/* ... */}</div>)}})constDeeperPage=React.createClass({getInitialState(){return{profile: null}},componentDidMount(){fetchProfile(profile=>this.setState({ profile }))},render(){// because it's a component, it gets to participate in the render// lifecycle, updating the title as state changes...const{ profile }=this.stateconsttitle=profile ? 'Loading...' : profile.fullNamereturn(<div><Titlerender={parentTitle=>`More Stuff | ${title}`}/>{/* ... */}</div>)}})

If you're using React Router, you probably want all of your route components to add something to the title.

Server Rendering

import{flushTitle}from'react-title-component'import{renderToString}from'react-dom/server'constmarkup=renderToString(<App/>)// App has some Titles in it.consttitle=flushTitle()// returns the title and gets ready for the// next requestrenderFullPageHoweverYouDoIt(markup,title)

Caveat

There is one caveat: You can't be removing titles from the middle of the chain. In other words, make sure that if your component renders a Title, it always renders a Title.

// GOODrender(){return(<div><Titlerender={prev=>`${prev} | stuff`}/></div>)}// BADrender(){return(<div>{!this.state.screwUpTheTitleLib&&(<Titlerender={prev=>`${prev} | stuff`}/>)}</div>)}

This could cause a title in the middle of the "title chain" to be removed and then screw everything else up, the code makes assumptions based on the order they get rendered.

This could be worked around, but it seems like a strange use-case that would complicate the code a bit.

Enjoy!

About

Nested document title management for React.js

Resources

Contributing

Stars

119 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages