Como você define o título do documento no React?


105

Gostaria de definir o título do documento (na barra de título do navegador) para meu aplicativo React. Eu tentei usar o react-document-title (parece desatualizado) e configurar document.titleno constructore componentDidMount()- nenhuma dessas soluções funciona.


desatualizado? @DanAbramov Acho que o react-document-title funciona bem com o React16 também.
— Vishal Gulati

Eu confirmo, react-document-title funciona muito bem com react 16.5
— Jo-Go

Respostas:


81

Você pode usar o Capacete 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>
        ...
      </>
    )
  }
}

isso irá 'piscar' o conteúdo do index.html no primeiro segundo, certo?
— nxmohamad

3
Esta deve ser definitivamente a melhor resposta. É uma excelente forma declarativa de gerenciar o título e outros atributos meta
— Ryall

111
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')
);

Isso funciona para mim.

Edit: Se você estiver usando webpack-dev-server definido inline como true


4
Isso funciona, mas o título do documento ainda é "React App" enquanto a página está carregando - alguma ideia de como consertar isso?
— eli

7
Altere o conteúdo da tag de título em seu index.html
— AlexVestin

4
Melhor fazê-lo declarativamente como na resposta de @ quotesBro
— Ryall

1
Essa forma é adequada para SEO?
— Davidm176

@AlexVestin Não é uma boa ideia se você precisa de títulos diferentes para visualizações diferentes em seu aplicativo React
— Kevin

48

Para React 16.8, você pode fazer isso com um componente funcional usando useEffect .

Por exemplo:

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

Ter o segundo argumento como uma matriz chama useEffect apenas uma vez, tornando-o semelhante a componentDidMount.


Como isso pode ser testado com gracejos e enzimas?
— nickstaroba

16

Como já foi mencionado, você pode usar document.title = 'My new title'e Reagir Capacete para atualizar o título da página. Ambas as soluções ainda renderizarão o título 'React App' inicial antes de os scripts serem carregados.

Se você estiver usando, create-react-appo título do documento inicial é definido no arquivo de <title>tag /public/index.html.

Você pode editar isso diretamente ou usar um marcador que será preenchido com as variáveis ​​ambientais:

/.env:

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

Se por algum motivo eu quisesse um título diferente em meu ambiente de desenvolvimento -

/.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>

Essa abordagem também significa que posso ler a variável de ambiente do título do site em meu aplicativo usando o process.envobjeto global , o que é bom:

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

Veja: Adicionando Variáveis ​​de Ambiente Personalizadas


Certifique-se de colocar os arquivos .env no mesmo nível do seu arquivo package.json. :)
— Ian Smith

10

você deve definir o título do documento no ciclo de vida de 'componentWillMount':

componentWillMount() {
    document.title = 'your title name'
  },

7
componentWillMount () está obsoleto na última versão
— react

3
Neste caso, como na maioria dos casos, quando você tiver que remover o componentWillMount obsoleto, mova seu código para componentDidMount
— Jo-Go

9

Os portais React permitem renderizar para elementos fora do nó React raiz (como em <title>), como se fossem nós React reais. Agora você pode definir o título de maneira limpa e sem dependências adicionais:

Aqui está um exemplo:

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;

Basta colocar o componente na página e definir pageTitle:

<Title pageTitle="Dashboard" />
<Title pageTitle={item.name} />

Uau, parece tão promissor, React Helmet e document.title funcionam, mas isso é incrível :) Obrigado
— mamsoudi

Adorei essa solução até perceber que ela apenas acrescenta fullTitleao conteúdo já encontrado em index.html's <title>Default Title</title>.
— JWess

Apenas remova o título padrão de seu módulo (não constructor!) `` `Import React de 'react'; importar PropTypes de 'prop-types'; importar ReactDOM de 'react-dom'; const titleNode = document.getElementsByTagName ("title") [0]; titleNode.innerText = ''; exportar a classe padrão Title extends React.PureComponent {static propTypes = {children: PropTypes.node,}; construtor (adereços) {super (adereços); this.el = titleNode; } render () {return ReactDOM.createPortal (this.props.children, this.el,); }} `` `
— Anatoliy Litinskiy

8

No React 16.13, você pode configurá-lo diretamente na função de renderização:

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')
)

Para componente de função:

function App() {
    document.title = 'wow'
    return <p>Hello</p>
}

1
Este é um erro típico que aparece em muitas bases de código reac: NÃO FAÇA ISSO! Todos os métodos de renderização devem ser funções puras (sem efeitos colaterais), se você precisar realizar um efeito colateral: useEffect para componentes funcionais ou eventos de componentes em classes (mais informações: reddit.com/r/reactjs/comments/8avfej/… )
— Elias Platek

6

Simplesmente você pode criar uma função em um arquivo js e exportá-la para uso em componentes

como abaixo:

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

e usá-lo em qualquer componente como este:

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

2

Você pode usar o seguinte abaixo com 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 você pode usar este pacote 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')
);

Happy Coding !!!


2

Não testei muito bem, mas parece funcionar. Escrito em 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;
    }
}

Uso:

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

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

Não sei por que os outros estão interessados ​​em colocar seu aplicativo inteiro dentro de seu <Title>componente, isso parece estranho para mim.

Ao atualizar o document.titleinterior, render()ele atualizará / permanecerá atualizado se você quiser um título dinâmico. Deve reverter o título quando desmontado também. Portais são bonitos, mas parecem desnecessários; realmente não precisamos manipular nenhum nó DOM aqui.


2

Você pode usar ReactDOM e alterar a <title>tag

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

0

Eu uso esse método, que descobri porque é mais fácil para mim. Eu o uso em combinação com o componente de função. Só faça isso se você não se importar que ele não exiba nenhum título se o usuário desabilitar o Javascript em sua página.

Existem duas coisas que você precisa fazer.

1. Vá para seu index.html e exclua esta linha aqui

<title>React App</title>

2. Vá para a função mainapp e retorne isso, que é apenas uma estrutura html normal, você pode copiar e colar o conteúdo principal do seu site entre as tags do corpo:

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

Você pode substituir o título como desejar.


-7

Se você é um iniciante, você pode apenas se salvar de tudo isso indo para a pasta pública de sua pasta do projeto react e editar o título em "index.html" e colocar o seu. Não se esqueça de salvar para que reflita.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.