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.

eli
fonte
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>
        ...
      </>
    )
  }
}
quoteBro
fonte
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

AlexVestin
fonte
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.

Jordan Daniels
fonte
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

Gruffy
fonte
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'
  },
Alvin
fonte
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} />
Coronel Trinta e Dois
fonte
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>
}
M Imam Pratama
fonte
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
amin msh
fonte
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 !!!

EsterlingAccime Youtuber
fonte
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.

mpen
fonte
2

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

ReactDOM.render(
   "New Title",
   document.getElementsByTagName("title")[0]
);
Reza Moradi
fonte
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.

Makusium
fonte
-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.

Stanleynd
fonte