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.