Artigo original: https://www.freecodecamp.org/news/deploy-a-react-app-to-github-pages/

Quando criamos projetos, queremos que eles possam ser acessados através da Internet. Ao invés de comprar um domínio e gastar tempo para configurá-lo, é mais fácil hospedá-lo no GitHub Pages.

Um projeto que usa JavaScript, HTML e CSS é simples de ser hospedado no GitHub Pages. No entanto, projetos que são construídos usando React, Vue ou Angular, precisam de configurações adicionais. O ideal seria que qualquer pessoa, ao acessar sua aplicação, tivesse a mesma experiência se o projeto fosse executado localmente.

Neste artigo, mostrarei como criar uma simples aplicação com React, usando roteamento e aprenderemos a fazer o upload dela no GitHub Pages. Daremos uma atenção especial para a parte de roteamento, pois ela é importante de ser entendida e implementada.

⚠️ Este artigo pressupõe que você tenha conhecimentos de React e Git.

Pré-requisitos

Você precisa do Node, do yarn e do npm instalados na sua máquina. Para verificar se estão instalados, abra um terminal e digite o seguinte:

npm -v
yarn -v
node -v

Se esses comandos retornaram o número de suas respectivas versões, você está pronto para continuar. Caso contrário, é necessário instalar os seguintes itens:

Precisaremos também de um repositório no GitHub. Acesse sua conta e crie um repositório. Escolha o nome que você achar adequado para esse projeto. Porém, eu usarei o nome starter-project até o fim deste artigo.

Para criar nosso projeto, usaremos o create-react-app, um pacote que facilita a criação de uma single-page application (aplicação de página única). Para criar um projeto, você precisa digitar o seguinte comando no terminal:

npx create-react-app starter-project

Assim que todas as operações finalizarem, você terá um boilerplate (modelo inicial) de um projeto do React para você seguir com o desenvolvimento. A fim de verificar se tudo está funcionando corretamente, acesse o repositório do projeto (no nosso exemplo, usamos starter-project) e execute o seguinte comando:

yarn start

Se tudo funcionar corretamente, você verá uma mensagem no terminal dizendo que a aplicação está rodando no seguinte endereço: http://localhost:3000

Se acessarmos esse endereço no navegador, devemos ver o seguinte:

IB8uRE3cjN

Como fazer o deploy do projeto no GitHub

Você deve ter notado que não criamos nenhum repositório no GitHub. Então, antes de seguirmos em frente, devemos fazer o upload do nosso projeto. Acesse a sua conta no GitHub e crie um repositório com o mesmo nome do projeto do React.

☝️ Garanta que o seu repositório esteja marcado como público. Se ele estiver marcado como privado, você não poderá utilizar o GitHub Pages.

Vamos adicionar um apontamento para nosso repositório remoto em nosso repositório local. Para fazer isso, digite o seguinte no terminal:

git remote add <nome-do-repositorio-remoto> <url-do-repositorio>

Então, no nosso caso, o comando será parecido com:

git remote add origin https://github.com/TomerPacific/starter-project
É importante chamar o remote origin, pois ele será necessário para fazer o nosso deploy.

Depois de executar o comando acima, ainda não podemos subir o nosso código. Inicialmente, precisamos configurar uma branch e defini-la como origin.

 git push --set-upstream origin master

Agora, podemos fazer o upload do nosso projeto para o repositório.

Para que possamos fazer o upload da nossa aplicação, também, precisamos instalar o pacote gh-pages:

yarn add gh-pages

Esse pacote nos ajudará com o deploy do nosso código para a branch gh-pages, que será utilizada para hospedar a nossa aplicação no GitHub Pages.

Para que possamos usar o pacote gh-pages, precisamos adicionar duas chaves aos nossos scripts do arquivo package.json:

"scripts": {
    "start": "react-scripts start",
    "predeploy": "npm run build", <----------- #1
    "deploy": "gh-pages -d build", <---------- #2
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

Em seguida, precisamos modificar o nosso arquivo package.json adicionando o campo homepage. Esse campo é utilizado pelo React para encontrar o URL principal do arquivo HTML. Nele, colocaremos o URL do nosso repositório no GitHub:

{
  "name": "starter-project",
  "homepage": "https://tomerpacific.github.io/starter-project/", <----
  "version": "0.1.0",
  /....
}

Para fazer o deploy da aplicação, digite o seguinte no terminal:

npm run deploy

A execução do comando acima realiza a build da aplicação e a envia para uma branch chamada gh-pages, que o GitHub usa para vincular nosso projeto ao GitHub Pages.

🚧 Se você não nomeou sua branch como origin, você receberá um erro durante essa fase: Falha em acessar remote.origin.url (a tarefa deve ser executada em um repositório git com uma branch origin configurada ou deve ser configurada com a opção "repo").

Você saberá que o processo foi bem-sucedido se, no final dele, for exibida a palavra Published (em português, publicado). Agora podemos ir ao nosso repositório do GitHub, acessar as configurações e depois clicar na seção do GitHub Pages.

chrome_egdTtIso1X

Se você vir uma mensagem similar a exibida acima, significa que sua aplicação agora está hospedada no GitHub Pages.

Roteamento no React

Até agora, tudo bem:

  1. Temos uma aplicação do React que está hospedada no GitHub Pages
  2. Também temos um processo simplificado para fazer o deploy sempre que quisermos fazer alterações

Como o objetivo deste artigo, no entanto, é mostrar uma aplicação mais complexa do que a que criamos inicialmente, discutiremos o roteamento a seguir.

Um componente que está ausente em nossa aplicação é a navegação. Nossa aplicação não terá apenas uma página, mas diversas. Então, como os usuários poderão navegar entre elas?

Roteamento é a prática de selecionar um caminho para seguir. Em termos mais básicos, o que deve acontecer quando você clica em um link dentro de uma página.

React é uma biblioteca e ela não contém tudo o que você precisa para sua aplicação (no nosso caso, o roteamento). Portanto, instalaremos o react router.

O React Router tem componentes diferentes para aplicações para a web e para aplicações nativas. Como estamos construindo uma aplicação para web, utilizaremos o react-router-dom.

yarn add react-router-dom

Para usar o roteamento em nossa aplicação, vamos criar um elemento de navegação que ficará visível na parte superior da tela. Adicionaremos esse trecho de código no nosso arquivo App.js substituindo o HTML que já existe lá.

 <div>
     <nav>
         <ul id="navigation">
             <li>
                 <Link to="/">Home</Link>
             </li>
             <li>
                 <Link to="/about">About</Link>
             </li>
             <li>
                 <Link to="/contact">Contact</Link>
             </li>
         </ul>
     </nav>
</div>

Normalmente, em projetos que não utilizam o React, usamos um caminho relativo para as páginas em HTML em cada seção. Dessa maneira, o navegador sabe de onde ele deve buscar os dados.

Entretanto, no nosso projeto, não temos diferentes arquivos HTML para cada seção. Nós apenas faremos o carregamento de diferentes componentes. O conteúdo que estava no App.js será agora encontrado dentro de um componente chamado Home.

import './App.css';
import React from 'react';
import logo from './logo.svg';

class Home extends React.Component {
    render() {
        return (
            <div className="App">
                <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p>
                    Edit <code>src/App.js</code> and save to reload.
                </p>
                <a
                    className="App-link"
                    href="https://reactjs.org"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    Learn React
                </a>
                </header>
            </div>
            
        );
    }

}

export default Home;
Home.jsx

Como criamos três seções em nossa navegação e como já criamos a parte referente a Home, vamos criar um outro exemplo usando a seção Sobre.

Criaremos um novo arquivo chamado About.jsx, que conterá nosso código para a seção Sobre.

import React from 'react';

const divStyle = {
    color:'white'
};

class About extends React.Component {
    
    render() {
        return (
            <div style={divStyle}>
                <h2>About Page</h2>
                <main>
                    <p>This section contains information about...</p>
                </main>
            </div>
        )
    }
}



export default About;

Você pode estar se perguntando, como a aplicação vai saber para onde ir quando clicarem no link sobre? Para tal, utilizaremos um componente chamado Route.

O Route é um dos componentes mais importantes do react-router, pois permite renderizar componentes diferentes com base no caminho do URL. Para o nosso projeto, usaremos o código a seguir dentro do App.js logo abaixo da parte de navegação.

<Switch>
    <Route exact path="/">
    <Home />
    </Route>
    <Route path="/about">
    <About />
    </Route>
</Switch>

Você pode ver que nós criamos duas rotas para os componentes Home e Sobre. O componente Switch nos permite agrupar componentes de rota e ele "escolherá" apenas um deles.

Nosso App.js fica assim:

import './App.css';
import React from 'react';
import { Route, Switch, Link } from "react-router-dom";
import About from './About';
import Home from './Home';

class App extends React.Component {
  render() {
      return (
        <div className="App">
          <div>
            <nav>
              <ul id="navigation">
                <li>
                  <Link to="/">Home</Link>
                </li>
                <li>
                <Link to="/about">About</Link>
                </li>
                <li>
                <Link to="/contact">Contact</Link>
                </li>
              </ul>
            </nav>
          </div>
            <Switch>
            <Route exact path="/">
              <Home />
            </Route>
            <Route path="/about">
              <About />
            </Route>
          </Switch>
          </div>
            );
  }
}

export default App;

Uma última coisa que precisamos fazer é envolver nosso projeto inteiro em um componente Router. Precisamos fazer isso porque é ele que nos permite usar um roteamento em nossa aplicação. Usaremos o componente BrowserRouter, pois ele usa a API de histórico do HTML5.

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);
index.js

Se executarmos tudo localmente, parece funcionar. Vamos fazer o deploy do nosso projeto melhorado no GitHub Pages e veremos o resultado.

Como lidar com o roteamento usando HashRouter

À primeira vista, tudo parece estar funcionando bem, mas, ao tentar atualizar a página ou navegar pelo próprio navegador, você notará que continuamos recebendo erros 404.

Por que isso acontece? O motivo é que o GitHub Pages não suporta o histórico do navegador como o seu navegador faz por padrão. No nosso caso, a rota https://tomerpacific.github.io/starter-project/about não ajuda o GitHub Pages entender para onde direcionar o usuário (uma vez que é uma rota do front-end).

Para resolver esse problema, precisamos usar o Hash Router ao invés de Browser Router na nossa aplicação. Esse tipo de roteador usa a parte do hash do URL para manter a interface do usuário sincronizada com o URL.

ReactDOM.render(
  <React.StrictMode>
    <HashRouter>
      <App />
    </HashRouter>
  </React.StrictMode>,
  document.getElementById('root')
);
index.js

Você pode ler mais sobre esse assunto aqui (texto em inglês).

Faça o deploy de sua aplicação novamente e teremos um resultado satisfatório. Não teremos mais erros 404.