Comment définir le titre du document dans React?

107

Je souhaite définir le titre du document (dans la barre de titre du navigateur) pour mon application React. J'ai essayé d'utiliser react-document-title (semble obsolète) et de définir document.titledans constructoret componentDidMount()- aucune de ces solutions ne fonctionne.

eli
la source
périmé? @DanAbramov Je suppose que react-document-title fonctionne également bien avec React16.
JS dev
Je confirme, react-document-title fonctionne très bien avec react 16.5
Jo-Go

Réponses:

81

Vous pouvez utiliser le casque React :

import React from 'react'
import { Helmet } from 'react-helmet'

const TITLE = 'My Page Title'

class MyComponent extends React.PureComponent {
  render () {
    return (
      <>
        <Helmet>
          <title>{ TITLE }</title>
        </Helmet>
        ...
      </>
    )
  }
}
citationsBro
la source
cela va «flasher» le contenu de l'index.html dans la première seconde, non?
nxmohamad
3
Cela devrait certainement être la meilleure réponse. C'est un excellent moyen déclaratif de gérer le titre et d'autres méta-attributs
Ryall
113
import React from 'react'
import ReactDOM from 'react-dom'


class Doc extends React.Component{
  componentDidMount(){
    document.title = "dfsdfsdfsd"
  }

  render(){
    return(
      <b> test </b>
    )
  }
}

ReactDOM.render(
  <Doc />,
  document.getElementById('container')
);

Cela fonctionne pour moi.

Edit: Si vous utilisez webpack-dev-server, définissez inline sur true

AlexVestin
la source
4
Cela fonctionne mais le titre du document est toujours "React App" pendant le chargement de la page - une idée de comment résoudre ce problème?
eli
7
Changez le contenu de la balise de titre dans votre index.html
AlexVestin
4
Mieux vaut le faire de manière déclarative comme dans la réponse de @ quotesBro
Ryall
1
Est-ce que cela convient pour le référencement?
Davidm176
@AlexVestin Ce n'est pas une bonne idée si vous avez besoin de différents titres pour différentes vues dans votre application React
Kevin
51

Pour React 16.8, vous pouvez le faire avec un composant fonctionnel utilisant useEffect .

Par exemple:

useEffect(() => {
   document.title = "new title"
}, []);

Le fait d'avoir le deuxième argument en tant que tableau n'appelle useEffect qu'une seule fois, ce qui le rend similaire à componentDidMount.

Jordan Daniels
la source
Comment cela peut-il être testé avec plaisanterie et enzyme?
nickstaroba le
16

Comme d'autres l'ont mentionné, vous pouvez utiliser document.title = 'My new title'et React Helmet pour mettre à jour le titre de la page. Ces deux solutions afficheront toujours le titre initial 'React App' avant le chargement des scripts.

Si vous utilisez create-react-apple titre initial du document est défini dans le fichier de <title>balise /public/index.html.

Vous pouvez le modifier directement ou utiliser un espace réservé qui sera rempli à partir de variables d'environnement:

/.env:

REACT_APP_SITE_TITLE='My Title!'
SOME_OTHER_VARS=...

Si pour une raison quelconque je voulais un titre différent dans mon environnement de développement -

/.env.development:

REACT_APP_SITE_TITLE='**DEVELOPMENT** My TITLE! **DEVELOPMENT**'
SOME_OTHER_VARS=...

/public/index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
         ...
         <title>%REACT_APP_SITE_TITLE%</title>
         ...
     </head>
     <body>
         ...
     </body>
</html>

Cette approche signifie également que je peux lire la variable d'environnement du titre du site depuis mon application à l'aide de l' process.envobjet global , ce qui est bien:

console.log(process.env.REACT_APP_SITE_TITLE_URL);
// My Title!

Voir: Ajouter des variables d'environnement personnalisées

Gruffy
la source
Assurez-vous de placer les fichiers .env au même niveau que votre fichier package.json. :)
Ian Smith
10

vous devez définir le titre du document dans le cycle de vie de 'componentWillMount':

componentWillMount() {
    document.title = 'your title name'
  },
Alvin
la source
7
componentWillMount () est obsolète dans la dernière version de
React
3
Dans ce cas, comme dans la plupart des cas, lorsque vous devez supprimer le composant obsolèteWillMount, déplacez votre code vers componentDidMount
Jo-Go
9

Les portails React peuvent vous permettre de rendre des éléments en dehors du nœud racine React (comme at <title>), comme s'il s'agissait de nœuds React réels. Alors maintenant, vous pouvez définir le titre proprement et sans aucune dépendance supplémentaire:

Voici un exemple:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Title extends Component {
    constructor(props) {
        super(props);
        this.titleEl = document.getElementsByTagName("title")[0];
    }

    render() {
        let fullTitle;
        if(this.props.pageTitle) {
            fullTitle = this.props.pageTitle + " - " + this.props.siteTitle;
        } else {
            fullTitle = this.props.siteTitle;
        }

        return ReactDOM.createPortal(
            fullTitle || "",
            this.titleEl
        );
    }
}
Title.defaultProps = {
    pageTitle: null,
    siteTitle: "Your Site Name Here",
};

export default Title;

Mettez simplement le composant dans la page et définissez pageTitle:

<Title pageTitle="Dashboard" />
<Title pageTitle={item.name} />
Colonel trente-deux
la source
Wow, ça a l'air si prometteur, React Helmet et document.title fonctionnent tous les deux, mais c'est génial :) Merci
mamsoudi
J'ai adoré cette solution jusqu'à ce que je réalise qu'elle s'ajoute simplement fullTitleau contenu déjà trouvé dans index.html <title>Default Title</title>.
JWess
Supprimez simplement le titre par défaut dans votre module (pas dans constructor!) `` Import React from 'react'; importer des PropTypes depuis 'prop-types'; importer ReactDOM depuis 'react-dom'; const titleNode = document.getElementsByTagName ("titre") [0]; titleNode.innerText = ''; Exporter la classe par défaut Titre étend React.PureComponent {statique propTypes = {enfants: PropTypes.node,}; constructeur (props) {super (props); this.el = titleNode; } render () {return ReactDOM.createPortal (this.props.children, this.el,); }} `` ``
Anatoliy Litinskiy
9

Dans React 16.13, vous pouvez le définir directement dans la fonction de rendu:

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
    render() {
        document.title = 'wow'
        return <p>Hello</p>
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('root')
)

Pour le composant de fonction:

function App() {
    document.title = 'wow'
    return <p>Hello</p>
}
M Imam Pratama
la source
1
C'est une erreur typique qui apparaît dans de nombreuses bases de code de réaction: NE FAITES PAS CELA! Toutes les méthodes de rendu doivent être des fonctions pures (pas d'effets secondaires), si vous devez effectuer un effet secondaire: useEffect pour les composants fonctionnels, ou les événements de composants dans les classes (plus d'infos: reddit.com/r/reactjs/comments/8avfej/… )
Elias Platek le
6

Vous pouvez simplement créer une fonction dans un fichier js et l'exporter pour une utilisation dans les composants

comme ci-dessous:

export default function setTitle(title) {
  if (typeof title !== "string") {
     throw new Error("Title should be an string");
  }
  document.title = title;
}

et utilisez-le dans n'importe quel composant comme celui-ci:

import React, { Component } from 'react';
import setTitle from './setTitle.js' // no need to js extension at the end

class App extends Component {
  componentDidMount() {
    setTitle("i am a new title");
  }

  render() {
    return (
      <div>
        see the title
      </div>
    );
  }
}

export default App
amin msh
la source
3

Vous pouvez utiliser les éléments suivants ci-dessous avec document.title = 'Home Page'

import React from 'react'
import { Component } from 'react-dom'


class App extends Component{
  componentDidMount(){
    document.title = "Home Page"
  }

  render(){
    return(
      <p> Title is now equal to Home Page </p>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

ou Vous pouvez utiliser ce package npm npm i react-document-title

import React from 'react'
import { Component } from 'react-dom'
import DocumentTitle from 'react-document-title';


class App extends Component{


  render(){
    return(
      <DocumentTitle title='Home'>
        <h1>Home, sweet home.</h1>
      </DocumentTitle>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

Bon codage !!!

EsterlingAccime Youtuber
la source
2

Je n'ai pas testé cela de manière trop approfondie, mais cela semble fonctionner. Écrit en TypeScript.

interface Props {
    children: string|number|Array<string|number>,
}

export default class DocumentTitle extends React.Component<Props> {

    private oldTitle: string = document.title;

    componentWillUnmount(): void {
        document.title = this.oldTitle;
    }

    render() {
        document.title = Array.isArray(this.props.children) ? this.props.children.join('') : this.props.children;
        return null;
    }
}

Usage:

export default class App extends React.Component<Props, State> {

    render() {
        return <>
            <DocumentTitle>{this.state.files.length} Gallery</DocumentTitle>
            <Container>
                Lorem ipsum
            </Container>
        </>
    }
}

Je ne sais pas pourquoi les autres souhaitent insérer l'intégralité de leur application dans leur<Title> composant, cela me semble étrange.

En mettant document.titleà jour l' intérieur, render()il rafraîchira / restera à jour si vous voulez un titre dynamique. Il devrait également revenir au titre une fois démonté. Les portails sont mignons, mais semblent inutiles; nous n'avons pas vraiment besoin de manipuler les nœuds DOM ici.

mpen
la source
2

Vous pouvez utiliser ReactDOM et modifier la <title>balise

ReactDOM.render(
   "New Title",
   document.getElementsByTagName("title")[0]
);
reza moradi
la source
0

J'utilise cette méthode, que j'ai découverte car c'est plus facile pour moi. Je l'utilise en combinaison avec un composant de fonction. Ne faites cela que si vous ne vous souciez pas qu'il n'affiche aucun titre si l'utilisateur désactive Javascript sur votre page.

Vous devez faire deux choses.

1. allez dans votre index.html et supprimez cette ligne ici

<title>React App</title>

2. allez dans votre fonction mainapp et renvoyez ceci qui n'est qu'une structure html normale, vous pouvez copier et coller votre contenu principal de votre site Web entre les balises body:

return (
        <html>
          <head>
            <title>hi</title>
          </head>
          <body></body>
        </html>
      );

Vous pouvez remplacer le titre à votre guise.

Makusium
la source
-7

Si vous êtes un débutant, vous pouvez simplement vous sauver de tout cela en allant dans le dossier public de votre dossier de projet react et éditer le titre dans "index.html" et mettre le vôtre. N'oubliez pas de sauvegarder pour qu'il reflète.

Stanleynd
la source