<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ NextJS - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ NextJS - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 19:22:17 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/tag/nextjs/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Como obter dados do GraphQL no Next.js usando o Apollo GraphQL ]]>
                </title>
                <description>
                    <![CDATA[ O Next.js tem tido um crescimento constante como uma ferramenta obrigatória para desenvolvedores criarem aplicações em React. Parte do que faz ele bom são as suas APIs de obtenção de dados (em inglês, data fetching) que solicitam dados para cada página. Como, porém, podemos usar essa API para fazer queries ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/</link>
                <guid isPermaLink="false">65f8fe03d8ef27040526c98e</guid>
                
                    <category>
                        <![CDATA[ NextJS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Esdras Ferreira da Silva ]]>
                </dc:creator>
                <pubDate>Wed, 05 Jun 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/apollo.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-fetch-graphql-data-in-next-js-with-apollo-graphql/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">https://www.freecodecamp.org/news/how-to-fetch-graphql-data-in-next-js-with-apollo-graphql/</a>
      </p><p>O Next.js tem tido um crescimento constante como uma ferramenta obrigatória para desenvolvedores criarem aplicações em React. Parte do que faz ele bom são as suas APIs de obtenção de dados (em inglês, <em>data fetching</em>) que solicitam dados para cada página. Como, porém, podemos usar essa API para fazer <em>queries</em> do GraphQL para nossa aplicação?</p><ul><li><a href="https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/#o-que-o-graphql">O que é o GraphQL?</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/#o-que-o-apollo-graphql">O que é o Apollo GraphQL?</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/#solicitando-dados-no-next-js">Solicitando dados no Next.js</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/#o-que-vamos-criar">O que vamos criar?</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/#passo-0-criando-a-aplica-o-do-next-js">Passo 0: Criando uma aplicação do Next.js</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/#passo-1-adicionando-o-apollo-graphql-em-uma-aplica-o-do-next-js">Passo 1: Adicionando o Apollo GraphQL em uma aplicação do Next.js</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/#passo-2-adicionando-dados-a-uma-p-gina-do-next-js-com-getstaticprops">Passo 2: Adicionando dados em uma página do Next.js com getStaticProps</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/#passo-3-recuperando-dados-com-uma-query-do-graphql-no-next-js-usando-o-apollo-client">Passo 3: Recuperando dados com uma query do GraphQL em Next.js usando o Apollo Client</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/como-obter-dados-do-graphql-no-next-js-usando-o-apollo-graphql/#passo-4-adicionado-os-dados-de-lan-amento-da-spacex-na-p-gina">Passo 4: Adicionando dados de lançamento da SpaceX na página</a></li></ul><h2 id="o-que-o-graphql">O que é o GraphQL?</h2><p>O <a href="https://graphql.org/">GraphQL</a> é uma <em>query language</em> e <em>runtime</em> que fornece uma maneira de interagir com uma API, diferente daquilo que você esperaria de uma API REST tradicional.</p><p>Quando dados são solicitados, ao invés de fazer uma requisição <a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Methods/GET">GET</a> para uma URL para pegar esse dado, um <em>endpoint </em>do GraphQL recebe uma "<em>query</em>" (consulta). Essa <em>query</em> indica quais dados queremos recuperar, seja um conjunto de dados completo ou apenas uma parte deles.</p><p>Seus dados poder se parecer com isto:</p><pre><code>Movie { "title": "Sunshine", "releaseYear": "2007", "actors": [...], "writers": [...] }</code></pre><p>Pode ser que você queira apenas pegar o título e o ano em que o filme foi lançado. Para isso, você poderia enviar uma query assim:</p><p><code>Movie { title releaseYear }</code>‌</p><p>Isso recuperaria apenas os dados de que você precisa.</p><p>A parte legal é que você também pode criar relações complexas entre dados. Com uma única <em>query</em>, você poderia ainda pedir dados de diferentes partes do banco de dados, o que tradicionalmente levaria a múltiplas solicitações para a API REST.</p><h2 id="o-que-o-apollo-graphql">O que é o Apollo GraphQL?</h2><p>No seu núcleo, o Apollo GraphQL é uma implementação do GraphQL que auxilia a trazer os dados como um grafo.</p><p>O Apollo também oferece e mantém um <em>client</em> de GraphQL, que é o que vamos usar. Ele permite a interação programática com uma API do GraphQL.</p><p>Usando o <em>client</em> do Apollo GraphQL, seremos capazes de fazer solicitações para uma API do GraphQL de modo similar ao que você esperaria de um <em>client</em> para APIs REST.</p><h2 id="solicitando-dados-no-next-js">Solicitando dados no Next.js</h2><p>Quando estamos solicitando dados no Next.js, há algumas formas de se recuperar esses dados.</p><p>Primeiramente, você poderia fazer o <em>client</em> executar a solicitação quando a página carregar. O problema disso é que você está colocando o fardo no <em>client </em>de achar tempo para fazer essas solicitações.</p><p>APIs do Next.js, como <code>getStaticProps</code> e <code>getServerSideProps</code>, permitem que você colete dados em diferentes momentos do ciclo de vida, nos dando a oportunidade de <a href="https://www.youtube.com/watch?v=6ElI2ZJ4Uro">fazer uma aplicação complemente estática</a> (vídeo em inglês) ou que ela seja renderizada do lado do servidor. Essas funções servem os dados que já foram renderizados na página diretamente no navegador.</p><p>Usando um desses métodos, somos capazes de solicitar dados juntamente com nossas páginas e de injetar esses dados como <em>props </em>diretamente na nossa aplicação.</p><h2 id="o-que-vamos-criar">O que vamos criar?</h2><p>Vamos criar uma aplicação do Next.js que mostra os últimos lançamentos da SpaceX.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/spacex-launches-demo.jpg" class="kg-image" alt="spacex-launches-demo" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/spacex-launches-demo.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/spacex-launches-demo.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/spacex-launches-demo.jpg 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/spacex-launches-demo.jpg 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1050" loading="lazy"><figcaption>Demonstração dos lançamentos da SpaceX</figcaption></figure><p>Utilizaremos a API mantida pela <a href="https://spacex.land/">SpaceX Land</a> para fazer uma query do GraphQL que pega os últimos 10 voos. Usando <a href="https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation">getStaticProps</a>, vamos fazer a solicitação na <em>build</em>, o que significa que nossa página será renderizada estaticamente com nossos dados.</p><h2 id="passo-0-criando-a-aplica-o-do-next-js">Passo 0: Criando a aplicação do Next.js</h2><p>Usando <em>Create Next App</em>, podemos rapidamente começar uma nova aplicação do Next.js, que usaremos para navegar no código imediatamente.</p><p>No terminal, execute o comando:</p><pre><code>npx create-next-app my-spacex-launches
</code></pre><blockquote><em>Nota: você não precisa usar <code>my-spacex-app</code>, sinta-se livre para substituir por qualquer nome que você deseje dar para o projeto.</em></blockquote><p>Depois de rodar o script, o Next.js vai configurar um novo projeto e instalar as dependências.</p><p>Uma vez terminado, você pode começar o servidor de desenvolvimento:</p><pre><code>cd my-spacex-launches
npm run dev
</code></pre><p>Esse comando iniciará um novo servidor em <a href="http://localhost:3000">http://localhost:3000</a>, onde você pode visitar a sua nova aplicação!</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/new-nextjs-app-1.jpg" class="kg-image" alt="new-nextjs-app-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/new-nextjs-app-1.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/new-nextjs-app-1.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/new-nextjs-app-1.jpg 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/new-nextjs-app-1.jpg 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="815" loading="lazy"><figcaption>Aplicação do Next.js</figcaption></figure><h2 id="passo-1-adicionando-o-apollo-graphql-em-uma-aplica-o-do-next-js">Passo 1: Adicionando o Apollo GraphQL em uma aplicação do Next.js</h2><p>Para começar a fazer uma <em>query</em> do GraphQL, vamos precisar de um <em>client </em>do GraphQL. Vamos utilizar o <em>client</em> Apollo GraphQL para fazer nossas <em>queries </em>para o servidor do GraphQL da SpaceX.</p><p>Novamente, no terminal, execute o seguinte comando para instalar as nossas novas dependências:</p><p>‌ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <code>npm install @apollo/client graphql </code></p><p>Esse comando vai adicionar o Apollo Client e também o GraphQL, que precisaremos para formar uma <em>query</em> do GraphQL.</p><p>Uma vez que a instalação completar, estaremos prontos para começar a usar o Apollo Client.</p><p><a href="https://github.com/colbyfayock/my-spacex-launches/commit/0fcc3a0141e7bfb795c3c91c355fdfc459a17332">Acompanhe com o <em>commit</em>!</a></p><h2 id="passo-2-adicionando-dados-a-uma-p-gina-do-next-js-com-getstaticprops">Passo 2: Adicionando dados a uma página do Next.js com getStaticProps</h2><p>Antes de solicitarmos dados com o Apollo, vamos configurar nossa página para sermos capazes de requisitar os dados e, então, passar esses dados como <em>props</em> para nossa página na <em>build</em>.</p><p>Vamos definir uma nova função no fim da página, embaixo do nosso componente <code>Home</code>, chamada <code>getStaticProps</code>:</p><pre><code>export async function getStaticProps() {
  // O código vai aqui
}</code></pre><p>Quando o Next.js fizer a <em>build </em>da<em> </em>nossa aplicação, ele saberá onde encontrar essa função. Então, quando a exportamos, estamos informando o Next.js que queremos rodar o código daquela função.</p><p>Dentro da nossa função <code>getStaticProps</code>, vamos, em última instância, retornar as <em>props</em> para a página. Para testar isso, vamos adicionar o seguinte na nossa função:</p><pre><code>export async function getStaticProps() {
  return {
    props: {
      launches: []
    }
  }
}</code></pre><p>Aqui, estamos passando uma nova <em>prop </em>chamada <code>launches</code> e estamos definindo a <em>prop</em> como um array vazio.</p><p>Agora, de volta para o nosso componente <code>Home</code>, vamos adicionar um novo argumento desestruturado que servirá como nossa <em>prop </em>e também vamos utilizar o <code>console.log</code> para testá-la:</p><pre><code>export default function Home({ launches }) {
  console.log('launches', launches);
}</code></pre><p>Se recarregarmos a página, podemos observar que agora estamos imprimindo nossa nova prop <code>launches</code>, que inclui um array vazio da maneira como definimos.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/nextjs-console-log-launches-array.jpg" class="kg-image" alt="nextjs-console-log-launches-array" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/nextjs-console-log-launches-array.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/nextjs-console-log-launches-array.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/nextjs-console-log-launches-array.jpg 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/nextjs-console-log-launches-array.jpg 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="410" loading="lazy"><figcaption>Registrando a <em>prop</em> <code>launches</code></figcaption></figure><p>O interessante disso é que, uma vez que a função <code>getStaticProps</code> que estamos definindo é assíncrona, podemos fazer qualquer solicitação que quisermos (incluindo uma <em>query </em>do GraphQL) e retorná-la como <em>props</em> para a nossa página, que é o que veremos mais adiante.</p><p><a href="https://github.com/colbyfayock/my-spacex-launches/commit/868a4f6b31200cd2407b4aa2fe37a243fc235932">Acompanhe com o <em>commit</em>!</a></p><h2 id="passo-3-recuperando-dados-com-uma-query-do-graphql-no-next-js-usando-o-apollo-client">Passo 3: Recuperando dados com uma query do GraphQL no Next.js usando o Apollo Client</h2><p>Agora que nossa aplicação está preparada para adicionar na nossa página e que temos o Apollo instalado, podemos finalmente fazer uma solicitação para pegar nossos dados da SpaceX.</p><p>Aqui, vamos usar o Apollo Client, que é o que permite nos conectarmos com o servidor do GraphQL da SpaceX. Faremos nossa solicitação para a API usando o método <code>getStaticProps</code> do Next.js, nos permitindo criar <em>props</em> dinamicamente para nossa página quando ela é construída.</p><p>Primeiramente, vamos importar nossas dependências do Apollo no projeto. No topo da página adicione:</p><pre><code>import { ApolloClient, InMemoryCache, gql } from '@apollo/client';</code></pre><p>Isso incluirá o <em>client</em> do Apollo propriamente dito, <code>InMemoryCache</code>, que permite ao Apollo otimizar por meio de leitura de um cache, e <code>gql</code>, que utilizaremos para formar nossa <em>query </em>do GraphQL.</p><p>Agora, vamos utilizar o Apollo Client. Para isso, precisamos configurar uma nova instância dele:</p><p>Dentro da função <code>getStaticProps</code>, adicione:</p><pre><code>const client = new ApolloClient({
  uri: 'https://api.spacex.land/graphql/',
  cache: new InMemoryCache()
});</code></pre><p>Isso cria uma instância do Apollo Client usando o <em>endpoint </em>da API do SpaceX pelo qual faremos a <em>query</em>.</p><p>Com o nosso <em>client</em>, conseguimos finalmente fazer uma <em>query</em>. Adicione o seguinte código abaixo do <em>client</em>:</p><pre><code>const { data } = await client.query({
  query: gql`
    query GetLaunches {
      launchesPast(limit: 10) {
        id
        mission_name
        launch_date_local
        launch_site {
          site_name_long
        }
        links {
          article_link
          video_link
          mission_patch
        }
        rocket {
          rocket_name
        }
      }
    }
  `
});</code></pre><p>Isso faz algumas coisas:</p><ul><li>Cria uma <em>query</em> dentro das tag <code>gql</code></li><li>Cria uma <em>query request</em> usando <code>client.query</code></li><li>Usa <code>await</code> para garantir que ele finalize a requisição antes de continuar</li><li>Por fim, desestrutura <code>data</code> dos resultados, que é onde as informações que precisamos estão armazenadas.</li></ul><p>Dentro da <em>query </em>do GraphQL, estamos informando para a SpaceX que queremos pegar <code>launchesPast</code>, que são os últimos lançamentos da SpaceX, e que queremos os últimos 10 (limite). Dentro disso, definimos os dados que gostaríamos de recuperar.</p><p>Se adicionarmos um novo console log depois disso, podemos observar a aparência de <code>data</code>.</p><p>No entanto, uma vez que você recarregar a página, você notará que você não está vendo nada no console do navegador.</p><p><code>getStaticProps</code> roda durante o processo de <em>build</em>, o que significa que ele roda no <em>node</em>. Portanto, podemos olhar o nosso terminal e veremos os logs: </p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/logging-static-props-terminal.jpg" class="kg-image" alt="logging-static-props-terminal" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/logging-static-props-terminal.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/logging-static-props-terminal.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/logging-static-props-terminal.jpg 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/logging-static-props-terminal.jpg 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="559" loading="lazy"><figcaption>Registro dos dados no terminal</figcaption></figure><p>Depois de ver isso, sabemos que o objeto <code>data</code> tem uma propriedade chamada <code>launchesPast</code>, que inclui um array de detalhes de lançamento.</p><p>Agora, podemos atualizar o retorno para usar <code>launchesPast</code>:</p><pre><code>return {
  props: {
    launches: data.launchesPast
  }
}</code></pre><p>Se adicionarmos nosso <code>console.log</code> de volta no topo da página para ver a aparência da <em>prop</em> <code>launches</code>, podemos observar que nossos dados de lançamento agora estão disponíveis como uma <em>prop</em> na nossa página:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/logging-static-props-web-console.jpg" class="kg-image" alt="logging-static-props-web-console" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/logging-static-props-web-console.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/logging-static-props-web-console.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/logging-static-props-web-console.jpg 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/logging-static-props-web-console.jpg 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="456" loading="lazy"><figcaption>Registro da <em>prop </em>no console da web</figcaption></figure><p><a href="https://github.com/colbyfayock/my-spacex-launches/commit/f273bcde3d2baccd54e4c65930ab499dbe4862ed">Acompanhe com o <em>commit</em>!</a></p><h2 id="passo-4-adicionado-os-dados-de-lan-amento-da-spacex-na-p-gina">Passo 4: Adicionado os dados de lançamento da SpaceX na página</h2><p>Agora, vamos para a parte legal!</p><p>Temos nossos dados de lançamento, que conseguimos recuperar usando o Apollo Client, para solicitar do servidor do GraphQL da SpaceX. Fizemos uma requisição dentro de <code>getStaticProps</code>, de maneira que conseguimos deixar nossos dados disponíveis como a <em>prop</em> <code>launches</code>, que contém os dados de lançamento.</p><p>Navegando na página, vamos começar tirando proveito do que já existe. Por exemplo, podemos começar atualizando a tag <code>h1</code> e o parágrafo abaixo dele para algo que descreva nossa página um pouco:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/updated-page-title.jpg" class="kg-image" alt="updated-page-title" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/updated-page-title.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/updated-page-title.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/updated-page-title.jpg 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/updated-page-title.jpg 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="565" loading="lazy"><figcaption>Título atualizado da página</figcaption></figure><p>Depois, vamos utilizar os <em>cards</em> de link que já existem para incluir todos os nossos dados de lançamento.</p><p>Para fazer isso, vamos, primeiramente, adicionar um <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a> dentro do grid da nossa página, onde o componente que retornamos é um dos <em>cards</em>, com os dados de lançamento preenchidos:</p><pre><code>&lt;div className={styles.grid}&gt;
  {launches.map(launch =&gt; {
    return (
      &lt;a key={launch.id} href={launch.links.video_link} className={styles.card}&gt;
        &lt;h3&gt;{ launch.mission_name }&lt;/h3&gt;
        &lt;p&gt;&lt;strong&gt;Launch Date:&lt;/strong&gt; { new Date(launch.launch_date_local).toLocaleDateString("en-US") }&lt;/p&gt;
      &lt;/a&gt;
    );
  })}</code></pre><p>Podemos também nos livrar do resto dos <em>cards </em>padrão do Next.js, incluindo <em>Documentation</em> e <em>Learn</em>.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/list-of-spacex-launches.jpg" class="kg-image" alt="list-of-spacex-launches" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/list-of-spacex-launches.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/list-of-spacex-launches.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/list-of-spacex-launches.jpg 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/list-of-spacex-launches.jpg 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="768" loading="lazy"><figcaption>Página com os lançamentos da SpaceX</figcaption></figure><p>Nossa página, agora, inclui os últimos 10 lançamentos da SpaceX e a data do lançamento!</p><p>Podemos até mesmo clicar em qualquer um desses <em>cards</em> e, já que vinculamos o link para o vídeo, conseguimos agora ir diretamente para o vídeo ao clicar.</p><p><a href="https://github.com/colbyfayock/my-spacex-launches/commit/e35ed076253e3648fa5d8cd62e993e4e9e436396">Acompanhe com o <em>commit</em>!</a></p><h2 id="pr-ximos-passos">Próximos passos</h2><p>A partir de agora, podemos incluir qualquer dado adicional de dentro do nosso array <code>launches</code> na nossa página. A API até mesmo inclui imagens de emblemas da missão, que podemos usar para mostrar imagens bonitas para cada lançamento.</p><p>Você também pode adicionar qualquer dado na <em>query</em> do GraphQL. Cada lançamento tem muitas informações disponíveis, incluindo a tripulação do lançamento e mais detalhes sobre o foguete.</p><p><a href="https://api.spacex.land/graphql/">https://api.spacex.land/graphql</a></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/jamstack-handbook-banner.jpg" class="kg-image" alt="jamstack-handbook-banner" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/jamstack-handbook-banner.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/jamstack-handbook-banner.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/jamstack-handbook-banner.jpg 1600w" sizes="(min-width: 720px) 720px" width="1600" height="267" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/social-footer-card.jpg" class="kg-image" alt="social-footer-card" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/05/social-footer-card.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2024/05/social-footer-card.jpg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2024/05/social-footer-card.jpg 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/05/social-footer-card.jpg 2000w" sizes="(min-width: 720px) 720px" width="2000" height="400" loading="lazy"></figure><ul><li><a href="https://twitter.com/colbyfayock">🐦 Siga o autor no Twitter</a></li><li><a href="https://youtube.com/colbyfayock">📺 Inscreva-se no canal do autor no YouTube</a></li><li><a href="https://www.colbyfayock.com/newsletter/">📫 Assine a newsletter do autor</a></li><li><a href="https://github.com/sponsors/colbyfayock">💝 Patrocine o autor</a></li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ O manual do Next.js para iniciantes ]]>
                </title>
                <description>
                    <![CDATA[ Escrevi este tutorial para ajudá-lo a aprender Next.js rapidamente e a se familiarizar com o seu funcionamento. Ele é ideal para aqueles que têm zero ou pouco conhecimento sobre o Next.js, que já tenham usado React no passado e que estão ansiosos para mergulhar mais no ecossistema do React, em ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/</link>
                <guid isPermaLink="false">632842f7926c2f06e57d19fe</guid>
                
                    <category>
                        <![CDATA[ NextJS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Elizabete Nakamura ]]>
                </dc:creator>
                <pubDate>Sun, 09 Oct 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/the-next-js-handbook/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Next.js Handbook – Learn Next.js for Beginners</a>
      </p><p>Escrevi este tutorial para ajudá-lo a aprender Next.js rapidamente e a se familiarizar com o seu funcionamento.</p><p>Ele é ideal para aqueles que têm zero ou pouco conhecimento sobre o Next.js, que já tenham usado React no passado e que estão ansiosos para mergulhar mais no ecossistema do React, em especial, na renderização do lado do servidor.</p><p>Acho o Next.js uma ferramenta fantástica para criar aplicações para a web. No final deste artigo, espero que vocês estejam tão entusiasmados sobre isso tanto quanto eu. Também espero que ele o ajude a aprender o Next.js!</p><p><a href="https://flaviocopes.com/page/nextjs-handbook/">Observação: você pode baixar uma versão em PDF/ePub/Mobi deste tutorial para ler off-line!</a></p><h2 id="-ndice">Índice</h2><ol><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#introdu-o">Introdução</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#as-principais-caracter-sticas-fornecidas-pelo-next-js">As principais características fornecidas pelo Next.js</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#next-js-x-gatsby-x-create-react-app">Next.js x Gatsby x <code>create-react-app</code></a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#next-js-x-gatsby-x-create-react-app#como-instalar-o-next-js">Como instalar o Next.js</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#vendo-o-c-digo-fonte-da-p-gina-para-confirmar-que-a-renderiza-o-do-lado-do-servidor-est-funcionando">Vendo o código-fonte da página para confirmar se a renderização do lado do servidor está funcionando</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#os-pacotes-da-aplica-o">Os pacotes da aplicação</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#o-que-esse-cone-no-canto-inferior-direito">O que é esse ícone no canto inferior direito?</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#instalando-as-ferramentas-de-desenvolvedor-do-react">Instalando as ferramentas de desenvolvedor do React</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#outras-t-cnicas-de-depura-o-que-voc-pode-usar">Outras técnicas de depuração que você pode usar</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#adicionando-uma-segunda-p-gina-ao-site">Adicionando uma segunda página ao site</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#ligando-as-duas-p-ginas">Ligando as duas páginas</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#conte-do-din-mico-com-o-roteador">Conteúdo dinâmico com o roteador</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#pr-busca-1">Pré-busca</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#usando-o-roteador-para-detectar-o-link-ativo">Usando o roteador para detectar o link ativo</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#usando-next-router">Usando </a><code>next/router</code></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#enviando-dados-aos-componentes-usando-getinitialprops">Enviando dados aos componentes usando <code>getInitialProps()</code></a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#css">CSS</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#preenchendo-a-tag-head-com-tags-personalizadas">Preenchendo a tag head com tags personalizadas</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#adicionando-um-componente-wrapper">Adicionando um componente wrapper</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#rotas-de-api">Rotas de API</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#executando-o-c-digo-somente-no-lado-do-servidor-ou-do-client">Executando o código somente no lado do servidor ou do <em>client</em></a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#fazendo-o-deploy-da-vers-o-em-produ-o">Fazendo o deploy da versão em produção</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#fazendo-o-deploy-no-now">Fazendo o deploy no Now</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#analisando-os-pacotes-da-aplica-o">Analisando os pacotes da aplicação</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#m-dulos-de-lazy-loading">Módulos de <em>lazy loading</em></a></li><li><a href="https://www.freecodecamp.org/portuguese/news/o-manual-do-next-js-para-iniciantes/#para-onde-ir-a-partir-daqui">Para onde ir a partir daqui</a></li></ol><h2 id="introdu-o"><strong>Introdução</strong></h2><p>Trabalhar em uma aplicação moderna em JavaScript, desenvolvida com React, é fantástico até que você perceba que existem alguns problemas relacionados à renderização de todo o conteúdo no lado do <em>client</em>.</p><p>Primeiro, a página leva mais tempo para ficar visível para o usuário, porque antes de carregar o conteúdo, todo o JavaScript precisa ser carregado. Além disso, sua aplicação precisa ser executada para determinar o que mostrar na página.</p><p>Em segundo, se você está construindo um site publicamente disponível, terá um problema de conteúdo relacionado à SEO. Os motores de busca estão ficando melhores em rodar e indexar aplicações em JavaScript, mas é muito melhor se pudermos enviar para eles o conteúdo em vez de deixá-los descobrir sozinhos.</p><p>A solução para esses dois problemas é a <strong>renderização do lado do servidor</strong>, também chamada de <strong>pré-renderização estática</strong>.</p><p>O <a href="https://nextjs.org/">Next.js</a> é um <em>framework</em> para o React para fazer tudo isso de modo muito simples, mas não é limitada a isso. Ele é anunciado por seus criadores como um <strong>conjunto de ferramentas de comando único que não necessita de configuração para aplicações em React.</strong></p><p>Ele fornece uma estrutura comum, que permite que você construa facilmente uma aplicação para <em>front-end</em> em React, e que trata de modo transparente a renderização do lado do servidor para você.</p><h2 id="as-principais-caracter-sticas-fornecidas-pelo-next-js">As principais características fornecidas pelo<strong> Next.js</strong></h2><p>Aqui temos uma lista não exaustiva das principais características do Next.js :</p><h3 id="recarregamento-r-pido-de-c-digo-hot-code-reloading-">Recarregamento rápido de código (<em>hot code reloading</em>)</h3><p>O Next.js recarrega a página quando detecta qualquer alteração salva em disco.</p><h3 id="roteamento-autom-tico"><strong>Roteamento automático</strong></h3><p>Qualquer URL é mapeado para o sistema de arquivos e para os arquivos colocados na pasta <code>pages</code>. Você não precisa de nenhuma configuração (embora, logicamente, você tenha opções de personalização).</p><h3 id="componentes-de-arquivo-nico"><strong>Componentes de arquivo único</strong></h3><p>Usando o <code>styled-jsx</code>, completamente integrado – já que foi criado pela mesma equipe, é fácil adicionar estilos com escopo definido ao componente.</p><h3 id="renderiza-o-do-lado-do-servidor"><strong>Renderização do lado do servidor</strong></h3><p>Você pode renderizar os componentes do React no lado do servidor antes de enviar o HTML para o <em>client</em>.</p><h3 id="compatibilidade-de-ecossistemas"><strong>Compatibilidade de ecossistemas</strong></h3><p>O Next.js funciona bem com o resto do ecossistema JavaScript, Node e React.</p><h3 id="divis-o-autom-tica-de-c-digos"><strong>Divisão automática de códigos</strong></h3><p>As páginas são renderizadas apenas com as bibliotecas e o JavaScript de que elas precisam, e só. Ao invés de gerar um único arquivo JavaScript contendo todo o código da aplicação, ela é dividida automaticamente pelo Next.js em vários recursos diferentes.</p><p>O carregamento de uma página busca apenas o JavaScript necessário para aquela página específica.</p><p>O Next.js faz isso analisando os recursos importados.</p><p>Se apenas uma de suas páginas importar a biblioteca Axios, por exemplo, essa página específica incluirá a biblioteca em seu pacote.</p><p>Isso garante que sua primeira página seja carregada o mais rápido possível, e somente os carregamentos futuros da página (se forem acionados em algum momento) enviarão o JavaScript necessário para o <em>client</em>.</p><p>Há uma notável exceção. As importações frequentemente usadas são movidas para o pacote principal do JavaScript se forem usadas em, pelo menos, metade das páginas do site.</p><h3 id="pr-busca"><strong>Pré-busca</strong></h3><p>O componente <code>Link</code>, usado para unir páginas diferentes, suporta uma propriedade de <code>prefetch</code>, que automaticamente faz a pré-busca dos recursos de página (incluindo o código faltando devido à divisão do código) em segundo plano.</p><h3 id="componentes-din-micos"><strong>Componentes dinâmicos</strong></h3><p>Você pode importar módulos do JavaScript e componentes do React dinamicamente.</p><h3 id="exporta-es-est-ticas"><strong>Exportações estáticas</strong></h3><p>Usando o comando de <code>next export</code>, o Next.js permite que você exporte um site totalmente estático de sua aplicação.</p><h3 id="suporte-a-typescript"><strong>Suporte a TypeScript</strong></h3><p>O Next.js é escrito em TypeScript e, como tal, vem com um excelente suporte ao TypeScript.</p><h2 id="next-js-x-gatsby-x-create-react-app">Next.js x Gatsby x <code>create-react-app</code></h2><p>O Next.js, o <a href="https://flaviocopes.com/gatsby/">Gatsby</a> e o <a href="https://flaviocopes.com/react-create-react-app/"><code>create-react-app</code></a> são ferramentas incríveis que podemos usar para potencializar as nossas aplicações.</p><p>Vamos primeiro dizer o que eles têm em comum. Todos eles usam o React internamente, potencializando toda a experiência de desenvolvimento. Eles também abstraem o <a href="https://flaviocopes.com/webpack/">webpack</a> e todas aquelas coisas de baixo nível que costumávamos configurar manualmente nos bons e velhos tempos.</p><p>O <code>create-react-app</code> não ajuda a gerar facilmente uma aplicação renderizada do lado do servidor. Tudo que vem com essa renderização (SEO, velocidade...) é fornecido apenas por ferramentas como o Next.js e o Gatsby.</p><h3 id="quando-o-next-js-melhor-que-o-gatsby"><strong>Quando o Next.js é melhor que o Gatsby?</strong></h3><p>Os dois podem ajudar com <strong>a renderização do lado do servidor</strong>, mas de dois modos diferentes.</p><p>O resultado final usando o Gatsby é um gerador de site estático, sem um servidor. Você constrói o site e, então, implanta o resultado do processo de criação estaticamente no Netlify ou em outro site de hospedagem estático.</p><p>O Next.js fornece um <em>back-end</em> que pode dar uma resposta ao pedido do servidor, permitindo que você crie um site dinâmico, o que significa que você o implantará em uma plataforma onde possa rodar o Node.js.</p><p>O Next.js também pode gerar um site estático, mas não diria que é o seu principal caso de uso.</p><p>Se o meu objetivo fosse construir um site estático, eu teria dificuldade para escolher – e talvez o Gatsby tenha um ecossistema melhor de plug-ins, incluindo muitos específicos para blogs.</p><p>O Gatsby também é fortemente baseado em <a href="https://flaviocopes.com/graphql/">GraphQL</a>, algo que você pode gostar ou não gostar, dependendo de suas opiniões e necessidades.</p><h2 id="como-instalar-o-next-js"><strong>Como instalar o Next.js?</strong></h2><p>Para instalar o Next.js, você precisa ter o Node.js instalado.</p><p>Certifique-se de ter a última versão do Node. Verifique isso digitando <code>node -v</code> em seu terminal, e compare sua versão com a última versão LTS listada em <a href="https://nodejs.org/">https://nodejs.org/</a>.</p><p>Após instalar o Node.js, você terá o comando <code>npm</code> disponível em sua linha de comando.</p><p>Se você tiver algum problema nessa fase, recomendo os seguintes tutoriais que escrevi para você (em inglês):</p><ul><li><a href="https://flaviocopes.com/node-installation/">Como instalar o Node.js</a></li><li><a href="https://flaviocopes.com/how-to-update-node/">Como atualizar o Node.js</a></li><li><a href="https://flaviocopes.com/npm/">Uma introdução ao gerenciador de pacotes npm</a></li><li><a href="https://flaviocopes.com/shells/">Tutorial de shells do Unix</a></li><li><a href="https://flaviocopes.com/macos-terminal/">Como usar o terminal do macOS</a></li><li><a href="https://flaviocopes.com/bash/">O shell do Bash</a></li></ul><p>Agora que você tem o Node (atualizado com a última versão) e o <code>npm</code>, estamos prontos!</p><p>Podemos escolher 2 caminhos agora: usar a abordagem do <code>create-next-app</code> ou a abordagem clássica, que envolve a instalação e a configuração manual de uma aplicação do Next.</p><h3 id="usando-o-create-next-app"><strong>Usando o create-next-app</strong></h3><p>Se você está familiarizado com o <code><a href="https://flaviocopes.com/react-create-react-app/">create-react-app</a></code>, o <code>create-next-app</code> é a mesma coisa – exceto pelo fato de ele criar uma aplicação do Next ao invés de uma aplicação do React, como o nome implica.</p><p>Presumo que você já tenha instalado o Node.js, que, a partir da versão 5.2 (há mais de dois anos, no momento em que escrevo), vem com o <a href="https://flaviocopes.com/npx/">comando</a> <code><a href="https://flaviocopes.com/npx/">npx</a></code> integrado (texto em inglês). Essa ferramenta útil nos permite baixar e executar um comando do JavaScript. Nós o usaremos assim:</p><pre><code class="language-bash">npx create-next-app</code></pre><p>O comando pede o nome da aplicação (e cria uma pasta para você com esse nome), depois faz o download de todos os pacotes necessários (<code>react</code>, <code>react-dom</code>, <code>next</code>) e define o <code>package.json</code> deste modo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-14-at-16.46.47.png" class="kg-image" alt="Screen-Shot-2019-11-14-at-16.46.47" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-14-at-16.46.47.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-14-at-16.46.47.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-14-at-16.46.47.png 1209w" sizes="(min-width: 720px) 720px" width="1209" height="853" loading="lazy"></figure><p>Você pode executar imediatamente a aplicação de exemplo, com o comando <code>npm run dev</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-14-at-16.46.32.png" class="kg-image" alt="Screen-Shot-2019-11-14-at-16.46.32" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-14-at-16.46.32.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-14-at-16.46.32.png 830w" sizes="(min-width: 720px) 720px" width="830" height="954" loading="lazy"></figure><p>E aqui está o resultado em <a href="http://localhost:3000">http://localhost:3000</a>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-14-at-16.47.17.png" class="kg-image" alt="Screen-Shot-2019-11-14-at-16.47.17" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-14-at-16.47.17.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-14-at-16.47.17.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-14-at-16.47.17.png 1129w" sizes="(min-width: 720px) 720px" width="1129" height="912" loading="lazy"></figure><p>Esta é a maneira recomendada de se iniciar uma aplicação do Next.js, pois ela oferece a estrutura e o código de exemplo para testarmos. Há mais além dessa aplicação de amostra padrão. Você pode usar qualquer um dos exemplos armazenados em <a href="https://github.com/zeit/next.js/tree/canary/examples">https://github.com/zeit/next.js/tree/canary/examples</a> usando a opção <code>--example</code>. Por exemplo, tente:</p><pre><code class="language-bash">npx create-next-app --example blog-starter</code></pre><p>Isso dá a você uma instância de blog imediatamente utilizável e com destaque de sintaxe:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-14-at-17.13.29.png" class="kg-image" alt="Screen-Shot-2019-11-14-at-17.13.29" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-14-at-17.13.29.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-14-at-17.13.29.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-14-at-17.13.29.png 1392w" sizes="(min-width: 720px) 720px" width="1392" height="1114" loading="lazy"></figure><h3 id="criar-manualmente-uma-aplica-o-do-next-js"><strong>Criar manualmente uma aplicação do Next.js</strong></h3><p>Você pode evitar o <code>create-next-app</code> se tiver vontade de criar uma aplicação do Next a partir do zero. É assim: crie uma pasta vazia em qualquer lugar que desejar (por exemplo, em sua pasta pessoal) e entre nela:</p><pre><code class="language-sh">mkdir nextjs
cd nextjs
</code></pre><p>Depois, crie seu primeiro diretório de projeto Next:</p><pre><code class="language-sh">mkdir firstproject
cd firstproject
</code></pre><p>Agora, use o comando <code>npm</code> &nbsp;para inicializá-lo como um projeto do Node:‌ </p><pre><code class="language-sh">npm init -y
</code></pre><p>A opção <code>-y</code> diz ao <code>npm</code> para usar as configurações padrão de um projeto, preenchendo um arquivo de amostra do <a href="https://www.freecodecamp.org/portuguese/news/p/0a1d3819-cabf-4972-baef-1da55a306967/package.json">package.json</a>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.59.21.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-16.59.21" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-16.59.21.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.59.21.png 918w" sizes="(min-width: 720px) 720px" width="918" height="642" loading="lazy"></figure><p>Agora, instale o Next e o React:</p><pre><code class="language-sh">npm install next react react-dom
</code></pre><p>Sua pasta de projeto agora terá 2 arquivos:</p><ul><li><code>package.json</code> (<a href="https://flaviocopes.com/package-json/">veja meu tutorial sobre isso</a> - em inglês)</li><li><code>package-lock.json</code> (<a href="https://flaviocopes.com/package-lock-json/">veja meu tutorial sobre package-lock</a> - em inglês)</li></ul><p>Ela também terá a pasta <code>node_modules</code>.</p><p>Abra a pasta do projeto usando seu editor favorito. Meu editor preferido é o <a href="https://flaviocopes.com/vscode/">VS Code</a>. Se você tiver o VS Code instalado, pode executar usando <code>code .</code> em seu terminal para abrir a pasta atual no editor (se o comando não funcionar para você, veja <a href="https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line">isso</a> - instruções em inglês)</p><p>Abra o <code>package.json</code>, que agora tem este conteúdo:</p><pre><code class="language-json">{
  "name": "primeiroprojeto",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;&amp; exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies":  {
    "next": "^9.1.2",
    "react": "^16.11.0",
    "react-dom": "^16.11.0"
  }
}</code></pre><p>Substitua a seção de <code>scripts</code> por:</p><pre><code class="language-json">"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "next start"
}
</code></pre><p>Assim, você adicionará os comandos de construção do Next.js, que vamos usar em breve.</p><p>Dica: use <code>"dev": "next -p 3001"</code>, para mudar a porta e executar – neste exemplo, na porta 3001.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-17.01.03.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-17.01.03" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-17.01.03.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-04-at-17.01.03.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-17.01.03.png 1102w" sizes="(min-width: 720px) 720px" width="1102" height="734" loading="lazy"></figure><p>Agora, crie a pasta <code>pages</code> e adicione um arquivo <code>index.js</code>.</p><p>Nesse arquivo, vamos criar nosso primeiro componente do React.</p><p>Vamos usá-lo como a exportação padrão:</p><pre><code class="language-js">const Index = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Home page&lt;/h1&gt;
  &lt;/div&gt;
)

export default Index</code></pre><p>Agora, usando o terminal, execute <code>npm run dev</code> para iniciar o servidor de desenvolvimento do Next.</p><p>Isso tornará a aplicação disponível na porta 3000, no localhost.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-11.24.02.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-11.24.02" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-11.24.02.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-11.24.02.png 951w" sizes="(min-width: 720px) 720px" width="951" height="618" loading="lazy"></figure><p>Abra <a href="http://localhost:3000">http://localhost:3000</a> no seu navegador para vê-lo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2019/11/Screen-Shot-2019-11-04-at-11.24.23.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-11.24.23" width="600" height="400" loading="lazy"></figure><h2 id="vendo-o-c-digo-fonte-da-p-gina-para-confirmar-que-a-renderiza-o-do-lado-do-servidor-est-funcionando"><strong>Vendo o código-fonte da página para confirmar que a renderização do lado do servidor está funcionando</strong></h2><p>Vamos agora verificar se a aplicação está funcionando como esperávamos que funcionasse. É uma aplicação do Next.js. Portanto, deve ser <strong>renderizada do lado do servidor</strong>.</p><p>Esse é um dos principais pontos valorizados do Next.js: se criarmos um site usando o Next.js, as páginas do site serão renderizadas no lado do servidor, que, por sua vez, entrega o HTML para o navegador.</p><p>Isso tem três grandes benefícios:</p><ul><li>O <em>client</em> não precisa instanciar o React para renderizar, o que torna o site mais rápido para os seus usuários.</li><li>Os motores de busca indexarão as páginas sem a necessidade de executar o JavaScript do lado do <em>client</em>, algo que o Google começou a fazer, mas admitiu abertamente ser um processo mais lento (e você deve ajudar o Google tanto quanto possível se quiser ter uma boa classificação).</li><li>Você pode ter metatags de mídia social, úteis para adicionar imagens de visualização, personalizar o título e a descrição para qualquer uma de suas páginas compartilhadas no Facebook, Twitter e assim por diante.</li></ul><p>Vamos ver o código-fonte da aplicação. Usando o Chrome, você pode clicar com o botão direito em qualquer lugar da página e pressionar <strong>View Page Source </strong>(<em>Exibir código-fonte da página</em>, em português).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-11.33.10.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-11.33.10" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-11.33.10.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-11.33.10.png 908w" sizes="(min-width: 720px) 720px" width="908" height="680" loading="lazy"></figure><p>Se você visualizar o código-fonte da página, verá o trecho de código da página inicial, <code>&lt;div&gt;&lt;h1&gt;Home page&lt;/h1&gt;&lt;/div&gt;</code>, no corpo do HTML, juntamente com vários arquivos JavaScript - os pacotes da aplicação.</p><p>Não precisamos configurar nada. A SSR (<em>server-side rendering</em> - ou renderização do lado do servidor) já estará trabalhando para nós.</p><p>A aplicação em React será lançada no <em>client</em> e potencializará as interações, como clicar em um link, utilizando a renderização do lado do <em>client</em>. Recarregar uma página, no entanto, ocorrerá a partir do servidor. Usando o Next.js, não deve haver diferença no resultado dentro do navegador - uma página renderizada no servidor deve ser exatamente igual a uma página renderizada no <em>client</em>.</p><h2 id="os-pacotes-da-aplica-o">Os pacotes da aplicação</h2><p>Quando vimos o código-fonte da página, percebemos vários arquivos do JavaScript sendo carregados:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-11.34.41.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-11.34.41" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-11.34.41.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-11.34.41.png 908w" sizes="(min-width: 720px) 720px" width="908" height="680" loading="lazy"></figure><p>Vamos começar colocando o código em um <a href="https://htmlformatter.com/">formatador de HTML</a> para que ele seja melhor formatado, para que nós humanos possamos ter uma chance de entendê-lo melhor:</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;

&lt;head&gt;
    &lt;meta charSet="utf-8" /&gt;
    &lt;meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1" /&gt;
    &lt;meta name="next-head-count" content="2" /&gt;
    &lt;link rel="preload" href="/_next/static/development/pages/index.js?ts=1572863116051" as="script" /&gt;
    &lt;link rel="preload" href="/_next/static/development/pages/_app.js?ts=1572863116051" as="script" /&gt;
    &lt;link rel="preload" href="/_next/static/runtime/webpack.js?ts=1572863116051" as="script" /&gt;
    &lt;link rel="preload" href="/_next/static/runtime/main.js?ts=1572863116051" as="script" /&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id="__next"&gt;
        &lt;div&gt;
            &lt;h1&gt;Home page&lt;/h1&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;script src="/_next/static/development/dll/dll_01ec57fc9b90d43b98a8.js?ts=1572863116051"&gt;&lt;/script&gt;
    &lt;script id="__NEXT_DATA__" type="application/json"&gt;{"dataManager":"[]","props":{"pageProps":{}},"page":"/","query":{},"buildId":"development","nextExport":true,"autoExport":true}&lt;/script&gt;
    &lt;script async="" data-next-page="/" src="/_next/static/development/pages/index.js?ts=1572863116051"&gt;&lt;/script&gt;
    &lt;script async="" data-next-page="/_app" src="/_next/static/development/pages/_app.js?ts=1572863116051"&gt;&lt;/script&gt;
    &lt;script src="/_next/static/runtime/webpack.js?ts=1572863116051" async=""&gt;&lt;/script&gt;
    &lt;script src="/_next/static/runtime/main.js?ts=1572863116051" async=""&gt;&lt;/script&gt;
&lt;/body&gt;

&lt;/html&gt;
</code></pre><p>Temos quatro arquivos JavaScript sendo declarados como pré-carregados no <code>head</code>, usando <code>rel="preload" as="script"</code>:</p><ul><li><code>/_next/static/development/pages/index.js</code> (96 linhas de código)</li><li><code>/_next/static/development/pages/_app.js</code> (5.900 linhas de código)</li><li><code>/_next/static/runtime/webpack.js</code> (939 linhas de código)</li><li><code>/_next/static/runtime/main.js</code> (12 mil linhas de código)</li></ul><p>Isso diz ao navegador para começar a carregar esses arquivos o mais rápido possível, antes que o fluxo normal de renderização comece. Sem eles, os scripts seriam carregados com um atraso adicional. O carregamento rápido desses arquivos melhora o desempenho de carregamento da página.</p><p>Esses quatro arquivos são, então, carregados ao final do <code>body</code>, juntamente com o <code>/_next/static/development/dll/dll_01ec57fc9b90d43b98a8.js</code> (31 mil linhas de código) e com um trecho de código em JSON, que estabelece alguns padrões para os dados da página:</p><pre><code class="language-html">&lt;script id="__NEXT_DATA__" type="application/json"&gt;
{
  "dataManager": "[]",
  "props": {
    "pageProps":  {}
  },
  "page": "/",
  "query": {},
  "buildId": "development",
  "nextExport": true,
  "autoExport": true
}
&lt;/script&gt;
</code></pre><p>Os quatro pacotes de arquivos carregados já estão implementando um recurso chamado divisão de código. O arquivo <code>index.js</code> fornece o código necessário para o componente <code>index</code>, que serve a rota /. Se tivéssemos mais páginas, teríamos mais pacotes para cada página, que só seriam carregados se necessário - para proporcionar um desempenho mais eficiente para a página.</p><h2 id="o-que-esse-cone-no-canto-inferior-direito"><strong>O que é esse ícone no canto inferior direito?</strong></h2><p>Você viu aquele pequeno ícone no canto inferior direito da página, que parece um relâmpago?</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-13.21.42.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-13.21.42" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-13.21.42.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-13.21.42.png 707w" width="707" height="487" loading="lazy"></figure><p>Se você passar o mouse sobre ele, verá que está dizendo "Prerendered page" (<em>Página pré-renderizada</em>, em português):‌</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-13.21.46.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-13.21.46" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-13.21.46.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-13.21.46.png 707w" width="707" height="487" loading="lazy"></figure><p>Esse ícone, que <em>só é visível</em> <em>no modo de desenvolvimento</em>, é claro, diz que a página se qualifica para a otimização estática automática, o que, basicamente, significa que ela não depende de dados que precisam ser buscados no momento da invocação, podendo ser pré-renderizada e criada como um arquivo HTML estático no momento da <em>build</em> (quando executamos <code>npm run build</code>).</p><p>O Next pode determinar isso pela ausência do método <code>getInitialProps()</code> anexado ao componente da página.</p><p>Quando esse é o caso, a nossa página pode ser ainda mais rápida, pois será servida estaticamente como um arquivo HTML em vez de passar pelo servidor do Node.js, que gera a saída HTML.</p><p>Outro ícone útil que pode aparecer ao lado dele, ou, ao invés dele, em páginas não pré-renderizadas, é um pequeno triângulo animado:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-14-at-14.56.21.png" class="kg-image" alt="Screen-Shot-2019-11-14-at-14.56.21" width="140" height="66" loading="lazy"></figure><p>Esse é um indicador de compilação. Ele aparece quando você salva uma página e o Next.js está compilando a aplicação antes que a recarregamento rápido do código faça efeito no recarregamento da aplicação automaticamente.</p><p>É um modo muito bom de determinar imediatamente se a aplicação já foi compilada. Você também pode testar uma parte dela na qual você estiver trabalhando.</p><h2 id="instalando-as-ferramentas-de-desenvolvedor-do-react">Instalando as ferramentas de desenvolvedor do React</h2><p>O Next.js tem como base o React. Portanto, uma ferramenta muito útil que precisamos instalar com certeza (se você ainda não o fez) são as ferramentas de desenvolvedor do React.</p><p>Disponíveis tanto para o <a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en">Chrome</a> quanto para o <a href="https://addons.mozilla.org/en-US/firefox/addon/react-devtools/">Firefox</a>, as ferramentas de desenvolvedor do React são um instrumento essencial que você pode usar para inspecionar uma aplicação do React.</p><p>As ferramentas de desenvolvedor do React não são específicas para o Next.js, mas eu quero apresentá-las porque você pode não estar 100% familiarizado com todas as ferramentas que o React fornece. É melhor analisar um pouco as ferramentas de depuração do que assumir que você já as conhece.</p><p>Elas fornecem um inspetor que revela a árvore de componentes do React que compõe sua página. Para cada componente, você pode verificar as <em>props</em>, o <em>state</em>, os <em>hooks</em> e muito mais.</p><p>Uma vez instaladas as ferramentas de desenvolvedor do React, você pode abrir as ferramentas de desenvolvedor normais do navegador (no Chrome, clique com o botão direito do mouse na página e depois clique em <code>Inspect</code> – ou Inspecionar, em português) e você encontrará dois novos painéis: <strong>Components</strong> e <strong>Profiler</strong>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.26.12.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-14.26.12" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-14.26.12.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.26.12.png 799w" sizes="(min-width: 720px) 720px" width="799" height="769" loading="lazy"></figure><p>Se você passar o mouse sobre os componentes, verá que, na página, o navegador selecionará as partes que serão renderizadas por aquele componente.</p><p>Se você selecionar qualquer componente na árvore, o painel direito mostrará uma referência ao <strong>componente pai</strong> e às props passadas para ele:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.27.05.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-14.27.05" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-14.27.05.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.27.05.png 799w" sizes="(min-width: 720px) 720px" width="799" height="769" loading="lazy"></figure><p>Você pode navegar facilmente clicando próximo aos nomes dos componentes.</p><p>Você pode clicar no ícone do olho, na barra de ferramentas das Ferramentas do desenvolvedor, para inspecionar um elemento do DOM. Se você usar o primeiro ícone, aquele com o ícone do mouse (que, convenientemente, fica sob o ícone &nbsp;semelhante nas ferramentas do desenvolvedor), você pode passar o mouse sobre um elemento na interface do usuário do navegador para selecionar diretamente o componente do React que o renderiza.</p><p>Você pode usar o ícone do <code>bug</code> para registrar os dados de um componente no console.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.31.25.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-14.31.25" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-14.31.25.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.31.25.png 799w" sizes="(min-width: 720px) 720px" width="799" height="769" loading="lazy"></figure><p>Isso é bastante impressionante, pois, uma vez que você tenha os dados impressos ali, poderá clicar com o botão direito em qualquer elemento e pressionar "Store as a global variable" (Armazenar como uma variável global, em português). Por exemplo, aqui, eu fiz isso com a prop do <code>url</code> e pude inspecioná-la no console usando a variável temporária atribuída a ele, <code>temp1</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.40.22.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-14.40.22" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-14.40.22.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.40.22.png 799w" sizes="(min-width: 720px) 720px" width="799" height="889" loading="lazy"></figure><p>Usando os <strong>Source Maps</strong>, que são carregados automaticamente pelo Next.js em modo de desenvolvimento, a partir do painel <code>Components</code>, podemos clicar no código com <code>&lt;&gt;</code> e as ferramentas do desenvolvedor mudarão para o painel Source, mostrando-nos o código-fonte do componente:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.41.33.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-14.41.33" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-14.41.33.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.41.33.png 799w" sizes="(min-width: 720px) 720px" width="799" height="889" loading="lazy"></figure><p>A aba <strong>Profiler</strong> é ainda mais impressionante. Ela nos permite <strong>registrar uma interação</strong> na aplicação e ver o que acontece. Ainda não posso mostrar um exemplo, porque são necessários pelo menos dois componentes para criar uma interação e, de momento, temos apenas um. Falarei sobre isso mais tarde.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.42.24.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-14.42.24" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-14.42.24.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.42.24.png 799w" sizes="(min-width: 720px) 720px" width="799" height="889" loading="lazy"></figure><p>Todas as capturas de tela que fiz e mostrei acima usam o Chrome, mas as ferramentas de desenvolvedor do React funcionam do mesmo modo no Firefox:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.45.20.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-14.45.20" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-14.45.20.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-14.45.20.png 998w" sizes="(min-width: 720px) 720px" width="998" height="735" loading="lazy"></figure><h2 id="outras-t-cnicas-de-depura-o-que-voc-pode-usar">Outras técnicas de depuração que você pode usar</h2><p>Além das ferramentas de desenvolvedor do React, que são essenciais para construir uma aplicação do Next.js, quero mostrar dois modos de depurar aplicações do Next.js.</p><p>A primeira é, obviamente, usando o <code>console.log()</code> e todas as outras ferramentas da <a href="https://flaviocopes.com/console-api/">API do Console</a> (texto em inglês). O modo como as aplicações do Next funcionam fará uma registro do console aparecer no console do navegador OU no terminal onde você iniciou o Next, usando <code>npm run dev</code>.</p><p>Em especial, se a página for carregada a partir do servidor, quando você apontar o URL para ela, ou pressionar o botão Refresh (Atualizar) ou Cmd/CTRL-R, todos os registros do console acontecem no terminal. </p><p>As transições de página subsequentes que acontecem ao clicar no mouse farão com que todo o registro do console aconteça dentro do navegador. Não se esqueça disso caso se surpreenda com a ausência de um registro no console do navegador de início.</p><p>Outra ferramenta essencial é a instrução de <code>debugger</code>. Adicionando esta declaração a um componente, o navegador fará uma pausa na renderização da página:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-15.10.32.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-15.10.32" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-15.10.32.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-15.10.32.png 797w" sizes="(min-width: 720px) 720px" width="797" height="1055" loading="lazy"></figure><p>Isso é realmente incrível, porque, agora, você pode usar o depurador do navegador para inspecionar valores e executar sua aplicação uma linha de cada vez.</p><p>Você também pode usar o depurador do VS Code para depurar o código do lado do servidor. Menciono essa técnica e <a href="https://github.com/Microsoft/vscode-recipes/tree/master/Next-js">esse tutorial</a> (em inglês) para que você possa fazer essa configuração.</p><h2 id="adicionando-uma-segunda-p-gina-ao-site"><strong>Adicionando uma segunda página ao site</strong></h2><p>Agora que temos um bom domínio das ferramentas que podemos usar para nos ajudar a desenvolver as aplicações do Next.js, vamos continuar de onde paramos em nossa primeira aplicação:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-13.21.42-1.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-13.21.42-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-13.21.42-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-13.21.42-1.png 707w" width="707" height="487" loading="lazy"></figure><p>Quero adicionar uma segunda página a esse site, um blog. Ele vai ser servido em <code>/blog</code> e, por enquanto, conterá apenas uma simples página estática, assim como nosso primeiro componente <a href="https://www.freecodecamp.org/portuguese/news/p/0a1d3819-cabf-4972-baef-1da55a306967/index.js">index.js</a>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-15.39.40.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-15.39.40" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-15.39.40.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-04-at-15.39.40.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-15.39.40.png 1102w" sizes="(min-width: 720px) 720px" width="1102" height="734" loading="lazy"></figure><p>Depois de salvar o novo arquivo, o processo <code>npm run dev</code> em execução já é capaz de renderizar a página, sem a necessidade de reiniciá-la.</p><p>Quando acessamos o URL <a href="http://localhost:3000/blog">http://localhost:3000/blog</a>, temos a nova página:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-15.41.39.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-15.41.39" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-15.41.39.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-15.41.39.png 663w" width="663" height="559" loading="lazy"></figure><p>Aqui está o que o terminal nos diz:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-15.41.03.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-15.41.03" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-15.41.03.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-15.41.03.png 918w" sizes="(min-width: 720px) 720px" width="918" height="498" loading="lazy"></figure><p>Agora o fato de o URL ser <code>/blog</code> depende apenas do nome do arquivo, e de sua posição na pasta <code>pages</code>.</p><p>Você pode criar uma página <code>pages/hey/ho</code> e ela página aparecerá no URL <a href="http://localhost:3000/hey/ho">http://localhost:3000/hey/ho</a>.</p><p>O que não importa, para fins de URL, é o nome do componente dentro do arquivo.</p><p>Tente ver o código-fonte da página. Quando carregada do servidor, ela listará <code>/_next/static/development/pages/blog.js</code> como um dos pacotes carregados, e não <code>/_next/static/development/pages/index.js</code> como na página inicial. Isso porque, graças à divisão automática do código, não precisamos do pacote que serve a página inicial, apenas do pacote que serve a página do blog.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.24.53.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-16.24.53" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-16.24.53.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.24.53.png 954w" sizes="(min-width: 720px) 720px" width="954" height="542" loading="lazy"></figure><p>Também podemos simplesmente exportar uma função anônima a partir do <code>blog.js</code>: </p><pre><code class="language-js">export default () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Blog&lt;/h1&gt;
  &lt;/div&gt;
)
</code></pre><p>Ou, se você preferir uma sintaxe diferente da sintaxe de <em>arrow functions</em>:</p><pre><code class="language-js">export default function() {
  return (
    &lt;div&gt;
      &lt;h1&gt;Blog&lt;/h1&gt;
    &lt;/div&gt;
  )
}
</code></pre><h2 id="ligando-as-duas-p-ginas">Ligando as duas páginas</h2><p>Agora que temos duas páginas, definidas por <code>index.js</code> e <code>blog.js</code>, podemos introduzir os links.</p><p>Os links HTML normais dentro das páginas são feitos usando a tag <code>a</code>:</p><pre><code class="language-html">&lt;a href="/blog"&gt;Blog&lt;/a&gt;
</code></pre><p>Não podemos fazer isso no Next.js.</p><p>Por quê? Tecnicamente <em>podemos</em>, é claro, porque essa é a web e, na <em>web, as coisas nunca se quebram </em>(é por isso que ainda podemos usar a tag <code>&lt;marquee&gt;</code>. No entanto, um dos principais benefícios de usar o Next é que, uma vez que uma página é carregada, as transições para outra página são muito rápidas graças à renderização do lado do <em>client</em>.</p><p>Se você usar um link <code>a</code> simples:</p><pre><code class="language-js">const Index = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Home page&lt;/h1&gt;
    &lt;a href='/blog'&gt;Blog&lt;/a&gt;
  &lt;/div&gt;
)

export default Index
</code></pre><p>Agora, abra as <strong>ferramentas de desenvolvedor</strong> e o painel <strong>Network</strong>,<strong> </strong>especificamente. Na primeira vez em que carregamos <code>http://localhost:3000/</code>, temos todos os pacotes de páginas carregados:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.26.00.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-16.26.00" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-16.26.00.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-04-at-16.26.00.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.26.00.png 1085w" sizes="(min-width: 720px) 720px" width="1085" height="971" loading="lazy"></figure><p>Agora, se você clicar no botão "Preserve log" (para evitar limpar o painel Network), e clicar no link "Blog", isso é o que acontece:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.27.16.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-16.27.16" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-16.27.16.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-04-at-16.27.16.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.27.16.png 1085w" sizes="(min-width: 720px) 720px" width="1085" height="971" loading="lazy"></figure><p>Recebemos todo aquele JavaScript do servidor novamente! O problema é que não precisamos de todo aquele JavaScript, pois já o temos. Precisaríamos apenas do pacote de páginas do <code>blog.js</code>, o único que é novo na página.</p><p>Para resolver esse problema, usamos um componente fornecido pelo Next, chamado Link.</p><p>Importamos o componente assim:</p><pre><code class="language-js">import Link from 'next/link'
</code></pre><p>Depois, usamos o componente para envolver nosso link com <code>a</code>, assim:</p><pre><code class="language-js">import Link from 'next/link'

const Index = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Home page&lt;/h1&gt;
    &lt;Link href='/blog'&gt;
      &lt;a&gt;Blog&lt;/a&gt;
    &lt;/Link&gt;
  &lt;/div&gt;
)

export default Index</code></pre><p>Agora, se você tentar novamente o que fizemos anteriormente, verá que somente o pacote de <code>blog.js</code> é carregado quando nos movemos para a página do blog:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.35.18.png" class="kg-image" alt="Screen-Shot-2019-11-04-at-16.35.18" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-04-at-16.35.18.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-04-at-16.35.18.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-04-at-16.35.18.png 1085w" sizes="(min-width: 720px) 720px" width="1085" height="971" loading="lazy"></figure><p>A página é carregada mais rápido do que antes. O spinner usual do navegador na aba nem apareceu. No entanto, o URL mudou, como você pode ver. Tudo está funcionando perfeitamente com a <a href="https://flaviocopes.com/history-api/">API de histórico</a> (texto em inglês) do navegador.</p><p>Essa é a renderização do lado do <em>client</em> em ação.</p><p>Se você pressionar o botão Voltar agora, nada é carregado, pois o navegador ainda tem o antigo pacote <code>index.js</code> no lugar, pronto para carregar a rota <code>/index</code>. É tudo automático!</p><h2 id="conte-do-din-mico-com-o-roteador"><strong>Conteúdo dinâmico com o roteador</strong></h2><p>No capítulo anterior, vimos como vincular a página inicial à página do blog.</p><p>Um blog é um grande caso de uso para o Next.js, um que continuaremos a explorar neste capítulo adicionando <strong>posts no blog</strong>.</p><p>As postagens no blog têm um URL dinâmico. Por exemplo, um post intitulado "Olá Mundo" pode ter o URL <code>/blog/ola-mundo</code>. Um post com o título "Meu segundo post" pode ter o URL <code>/blog/meu-segundo-post</code>.</p><p>Esse conteúdo é dinâmico e pode ser retirado de um banco de dados, de arquivos de <em>markdown</em> e outros.</p><p>O Next.js pode servir conteúdo dinâmico baseado em um <strong>URL dinâmico</strong>.</p><p>Criamos um URL dinâmico usando uma página dinâmica com a sintaxe <code>[]</code>.</p><p>Como? Adicionamos um arquivo de páginas <code>pages/blog/[id].js</code>. Esse arquivo tratará todos os URLs dinâmicos sob a rota <code>/blog/</code>, como os que mencionamos acima: <code>/blog/ola-mundo</code>, <code>/blog/meu-segundo-post</code> e muito mais.</p><p>No nome do arquivo, <code>[id]</code> dentro dos colchetes significa que qualquer coisa que seja dinâmica será colocada dentro do parâmetro <code>id</code> da <strong>propriedade de query</strong> de <strong>router</strong> (em português, roteador).</p><p>Ok, isso é um pouco de tudo ao mesmo tempo – e pode confundir.</p><p>O que é o <strong>router</strong>? O <em>router </em>é uma biblioteca fornecida pelo Next.js.</p><p>Nós a importamos de <code>next/router</code>:</p><pre><code class="language-js">import { useRouter } from 'next/router'
</code></pre><p>Uma vez que tenhamos <code>useRouter</code>, instanciamos o objeto <em>router</em> usando:</p><pre><code class="language-js">const router = useRouter()
</code></pre><p>Ao termos esse objeto <em>router</em>, podemos extrair informações a partir dele.</p><p>Em particular, podemos obter a parte dinâmica do URL no arquivo <code>[id].js</code> acessando o <code>router.query.id</code>.</p><p>A parte dinâmica também pode ser apenas uma parte do URL, como <code>post-[id].js</code></p><p>Portanto, vamos continuar e aplicar todas essas coisas na prática.</p><p>Crie o arquivo <code>pages/blog/[id].js</code>:</p><pre><code class="language-js">import { useRouter } from 'next/router'

export default () =&gt; {
  const router = useRouter()

  return (
    &lt;&gt;
      &lt;h1&gt;Blog post&lt;/h1&gt;
      &lt;p&gt;Post id: {router.query.id}&lt;/p&gt;
    &lt;/&gt;
  )
}
</code></pre><p>Agora, se você for à rota <code>http://localhost:3000/blog/test</code>, deverá ver isto:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-16.41.32.png" class="kg-image" alt="Screen-Shot-2019-11-05-at-16.41.32" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-05-at-16.41.32.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-16.41.32.png 770w" sizes="(min-width: 720px) 720px" width="770" height="615" loading="lazy"></figure><p>Podemos usar esse parâmetro de <code>id</code> para obter o post a partir de uma lista de posts, por exemplo, em um banco de dados. Para manter as coisas simples, vamos adicionar um arquivo <code>posts.json</code> na pasta raiz do projeto:</p><pre><code class="language-js">{
  "test": {
    "title": "test post",
    "content": "Hey some post content"
  },
  "second": {
    "title": "second post",
    "content": "Hey this is the second post content"
  }
}
</code></pre><p>Agora podemos importá-la e consultar o post a partir da chave de <code>id</code>:</p><pre><code class="language-js">import { useRouter } from 'next/router'
import posts from '../../posts.json'

export default () =&gt; {
  const router = useRouter()

  const post = posts[router.query.id]

  return (
    &lt;&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.content}&lt;/p&gt;
    &lt;/&gt;
  )
}
</code></pre><p>Recarregando a página, devemos ver este resultado:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-16.44.07.png" class="kg-image" alt="Screen-Shot-2019-11-05-at-16.44.07" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-05-at-16.44.07.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-16.44.07.png 770w" sizes="(min-width: 720px) 720px" width="770" height="615" loading="lazy"></figure><p>‌Em vez disso, porém, recebemos um erro no console e outro erro no navegador:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-18.18.17.png" class="kg-image" alt="Screen-Shot-2019-11-05-at-18.18.17" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-05-at-18.18.17.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-18.18.17.png 898w" sizes="(min-width: 720px) 720px" width="898" height="665" loading="lazy"></figure><p>Por quê? Porque durante a renderização, quando o componente é inicializado, os dados ainda não estão lá. Veremos como fornecer os dados para o componente com <em>getInitialProps</em> na próxima seção.</p><p>Por enquanto, adicione a verificação <code>if (!post) return &lt;p&gt;&lt;/p&gt;</code> &nbsp;antes de retornar o JSX:</p><pre><code class="language-js">import { useRouter } from 'next/router'
import posts from '../../posts.json'

export default () =&gt; {
  const router = useRouter()

  const post = posts[router.query.id]
  if (!post) return &lt;p&gt;&lt;/p&gt;

  return (
    &lt;&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.content}&lt;/p&gt;
    &lt;/&gt;
  )
}
</code></pre><p>Agora, as coisas devem funcionar. Inicialmente, o componente é renderizado sem as informações dinâmicas do <code>router.query.id</code>. Após a renderização, o Next.js aciona uma atualização com o valor da consulta e a página exibe as informações corretas.</p><p>Se você visualizar o código-fonte, verá aquela tag vazia <code>&lt;p&gt;</code> no HTML:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-18.20.58.png" class="kg-image" alt="Screen-Shot-2019-11-05-at-18.20.58" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-05-at-18.20.58.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-18.20.58.png 898w" sizes="(min-width: 720px) 720px" width="898" height="665" loading="lazy"></figure><p>Em breve, resolveremos esse problema da não implementação da renderização do lado do servidor. Afinal, isso prejudica tanto os tempos de carregamento para os nossos usuários, quanto SEO e o compartilhamento social, como já discutimos.</p><p>Podemos completar o exemplo do blog listando esses posts em <code>pages/blog.js</code>:</p><pre><code class="language-js">import posts from '../posts.json'

const Blog = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Blog&lt;/h1&gt;

    &lt;ul&gt;
      {Object.entries(posts).map((value, index) =&gt; {
        return &lt;li key={index}&gt;{value[1].title}&lt;/li&gt;
      })}
    &lt;/ul&gt;
  &lt;/div&gt;
)

export default Blog</code></pre><p>Podemos, também, vinculá-los às páginas individuais dos posts, importando o <code>Link</code> do <code>next/link</code> e usando-o dentro do laço dos posts:</p><pre><code class="language-js">import Link from 'next/link'
import posts from '../posts.json'

const Blog = () =&gt; (
  &lt;div&gt;
    &lt;h1&gt;Blog&lt;/h1&gt;

    &lt;ul&gt;
      {Object.entries(posts).map((value, index) =&gt; {
        return (
          &lt;li key={index}&gt;
            &lt;Link href='/blog/[id]' as={'/blog/' + value[0]}&gt;
              &lt;a&gt;{value[1].title}&lt;/a&gt;
            &lt;/Link&gt;
          &lt;/li&gt;
        )
      })}
    &lt;/ul&gt;
  &lt;/div&gt;
)

export default Blog
</code></pre><h2 id="pr-busca-1">Pré-busca</h2><p>Eu mencionei anteriormente como o componente <code>Link</code> do Next.js pode ser usado para criar links entre duas páginas e que, quando você o usa, o Next.js trata <strong>transparentemente o roteamento do </strong><em><strong>front-end</strong> </em>para nós. Assim, quando um usuário clica em um link, o <em>front-end </em>se encarrega de mostrar a nova página sem acionar um novo ciclo de solicitação e resposta do <em>client</em>/servidor, como normalmente acontece com páginas da web.</p><p>Há outra coisa que o Next.js faz por você quando você usa o <code>Link</code>.</p><p>Assim que um elemento envolto no <code>&lt;Link&gt;</code> aparece na viewport (o que significa que é visível para o usuário do site), o Next.js faz a pré-busca do URL para o qual aponta, desde que seja um link local (no seu site), tornando a aplicação muito rápida para o espectador.</p><p>Esse comportamento é acionado apenas em <strong>modo de produção</strong> (falaremos sobre isto em profundidade mais tarde), o que significa que você tem que parar a aplicação se a estiver executando com <code>npm run dev</code>, compilar seu pacote de produção com <code>npm run build</code> e a executar com <code>npm run start</code> em seu lugar.</p><p>Usando o inspetor da aba Network nas ferramentas do desenvolvedor, você notará que qualquer link na parte superior na página inicial, ao carregar a página, inicia a pré-busca assim que o evento de <code>load</code> for disparado em sua página (ou seja, é acionada quando a página estiver totalmente carregada, acontecendo após o evento <code>DOMContentLoaded</code>).</p><p>Qualquer outra tag <code>Link</code> que não esteja na viewport será pré-buscada quando o usuário rolar até ela.</p><p>A pré-busca é automática em conexões de alta velocidade (conexões Wi-fi e 3g+, a menos que o navegador envie o <a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Headers/Save-Data">cabeçalho de HTTP</a> <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Save-Data"><code>Save-Data</code></a>.</p><p>Você pode escolher não usar a pré-busca de instâncias individuais do <code>Link</code>, configurando o prop <code>prefetch</code> como <code>false</code>:‌ </p><pre><code class="language-jsx">&lt;Link href="/a-link" prefetch={false}&gt;
  &lt;a&gt;A link&lt;/a&gt;
&lt;/Link&gt;
</code></pre><h2 id="usando-o-roteador-para-detectar-o-link-ativo"><strong>Usando o roteador para detectar o link ativo</strong></h2><p>Uma característica muito importante ao trabalhar com links é determinar qual é o URL atual e, em particular, atribuir uma classe ao link ativo, para que possamos dar a ele um estilo diferente dos outros.</p><p>Isso é especialmente útil no cabeçalho de seu site, por exemplo.</p><p>O componente padrão <code>Link</code> do Next.js, oferecido em <code>next/link</code>, não faz isso automaticamente para nós.</p><p>Nós mesmos podemos criar um componente Link e armazená-lo em um arquivo <code>Link.js</code> na pasta <code>components</code>, importando esse componente em vez do padrão <code>next/link</code>.</p><p>Nesse componente, vamos primeiro importar React de <code>react</code>, Link de <code>next/link</code> e o <em>hook </em><code>useRouter</code> de <code>next/router</code>.</p><p>Dentro do componente, determinamos se o nome do caminho atual corresponde ao prop <code>href</code> do componente e, se assim for, anexamos a classe <code>selected</code> aos elementos filhos.</p><p>Finalmente, retornamos esses filhos com a classe atualizada, usando</p><p><code>React.cloneElement()</code>:</p><pre><code class="language-js">import React from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'

export default ({ href, children }) =&gt; {
  const router = useRouter()

  let className = children.props.className || ''
  if (router.pathname === href) {
    className = `${className} selected`
  }

  return &lt;Link href={href}&gt;{React.cloneElement(children, { className })}&lt;/Link&gt;
}
</code></pre><h2 id="usando-next-router">Usando <code>next/router</code></h2><p>Já vimos como usar o componente Link para lidar declarativamente com o roteamento em aplicações do Next.js.</p><p>É realmente útil gerenciar o roteamento no JSX, mas, às vezes, é necessário acionar uma mudança programática de roteamento.</p><p>Nesse caso, você pode acessar o Router do Next.js diretamente, fornecido no pacote <code>next/router</code>, e chamar seu método <code>push()</code>.</p><p>Aqui está um exemplo de como acessar o <em>router</em>:</p><pre><code class="language-js">import { useRouter } from 'next/router'

export default () =&gt; {
  const router = useRouter()
  //...
}
</code></pre><p>Uma vez que obtemos o objeto <em>router</em> invocando o <code>useRouter()</code>, podemos usar seus métodos.</p><p>Esse é o roteador (<em>router</em>) do lado do <em>client</em>. Portanto, os métodos devem ser usados apenas no código voltado para o front-end. O modo mais fácil de garantir isso é envolvendo as chamadas no <em>hook</em> <code>useEffect()</code> do React ou dentro de <code>componentDidMount()</code> nos componentes com <em>state</em> do React.</p><p>Aquele que você provavelmente usará mais serão o <code>push()</code> e o <code>prefetch()</code>.</p><p><code>push()</code> nos permite acionar programaticamente uma alteração de URL no <em>front-end</em>:‌ </p><pre><code class="language-js">router.push('/login')
</code></pre><p><code>prefetch()</code> nos permite fazer programaticamente a pré-busca de um URL, o que é útil quando não temos uma tag <code>Link</code> que lide automaticamente com a pré-busca para nós:‌ </p><pre><code class="language-js">router.prefetch('/login')</code></pre><p>Exemplo completo:</p><pre><code class="language-js">import { useRouter } from 'next/router'

export default () =&gt; {
  const router = useRouter()

  useEffect(() =&gt; {
    router.prefetch('/login')
  })
}
</code></pre><p>Você também pode usar o roteador para ouvir os<a href="https://nextjs.org/docs#router-events"> eventos de mudança de rota</a>.</p><h2 id="enviando-dados-aos-componentes-usando-getinitialprops"><strong>Enviando dados aos componentes usando getInitialProps</strong></h2><p>No capítulo anterior, tivemos um problema com a geração dinâmica da página de post, pois o componente exigia alguns dados antecipadamente. Tentamos obter os dados do arquivo JSON, assim:</p><pre><code class="language-js">import { useRouter } from 'next/router'
import posts from '../../posts.json'

export default () =&gt; {
  const router = useRouter()

  const post = posts[router.query.id]

  return (
    &lt;&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.content}&lt;/p&gt;
    &lt;/&gt;
  )
}
</code></pre><p>Como resultado, obtivemos este erro:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-18.18.17-1.png" class="kg-image" alt="Screen-Shot-2019-11-05-at-18.18.17-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-05-at-18.18.17-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-18.18.17-1.png 898w" sizes="(min-width: 720px) 720px" width="898" height="665" loading="lazy"></figure><p>Como resolvemos isso e como fazemos a renderização do lado do servidor funcionar para as rotas dinâmicas?</p><p>Devemos fornecer o componente com props, usando uma função especial chamada <code>getInitialProps()</code>, que é anexada ao componente.</p><p>Para fazer isso, primeiro nomeamos o componente:</p><pre><code class="language-js">const Post = () =&gt; {
  //...
}

export default Post</code></pre><p>Então, adicionamos a função a ele:</p><pre><code class="language-js">const Post = () =&gt; {
  //...
}

Post.getInitialProps = () =&gt; {
  //...
}

export default Post</code></pre><p>Essa função recebe um objeto como argumento, que contém várias propriedades. Em particular, o que nos interessa agora é que tenhamos o objeto de <code>query</code>, aquele que usamos anteriormente para obter a identificação do post.</p><p>Assim, podemos obtê-lo usando a sintaxe de <em>desestruturação do objeto</em>:</p><pre><code class="language-js">Post.getInitialProps = ({ query }) =&gt; {
  //...
}
</code></pre><p>Agora, podemos retornar o post a partir dessa função:</p><pre><code class="language-js">Post.getInitialProps = ({ query }) =&gt; {
  return {
    post: posts[query.id]
  }
}
</code></pre><p>Também podemos remover a importação de <code>useRouter</code>. Obtemos o post por meio da propriedade <code>props</code> passada para o componente <code>Post</code>:</p><pre><code class="language-js">import posts from '../../posts.json'

const Post = props =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;{props.post.title}&lt;/h1&gt;
      &lt;p&gt;{props.post.content}&lt;/p&gt;
    &lt;/div&gt;
  )
}

Post.getInitialProps = ({ query }) =&gt; {
  return {
    post: posts[query.id]
  }
}

export default Post</code></pre><p>Agora, não haverá mais erros. A SSR (renderização do lado do servidor) estará funcionando como esperado, como você pode ver verificando a fonte de visualização:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-18.53.02.png" class="kg-image" alt="Screen-Shot-2019-11-05-at-18.53.02" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-05-at-18.53.02.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-05-at-18.53.02.png 898w" sizes="(min-width: 720px) 720px" width="898" height="665" loading="lazy"></figure><p>A função <code>getInitialProps</code> será executada no lado do servidor, mas também no lado do <em>client</em> quando navegamos para uma nova página usando o componente <code>Link</code>, como fizemos.</p><p>É importante notar que <code>getInitialProps</code> tem, no objeto de contexto que recebe, além do objeto de <code>query</code>, essas outras propriedades:</p><ul><li><code>pathname</code>: a seção do URL do <code>path</code></li><li><code>asPath</code>: a string do path atual (incluindo a consulta) mostrada no navegador</li></ul><p>No caso de chamar &nbsp;<code>http://localhost:3000/blog/test</code>, isso resultará respectivamente em:</p><ul><li><code>/blog/[id]</code></li><li><code>/blog/test</code></li></ul><p>No caso de renderização do lado do servidor, ele também receberá:</p><ul><li><code>req</code>: o objeto de solicitação HTTP</li><li><code>res</code>: o objeto de resposta HTTP</li><li><code>err</code>: um objeto de erro</li></ul><p><code>req</code> e <code>res</code> serão familiares a você se já tiver programado para o Node.js.</p><h2 id="css"><strong>CSS</strong></h2><p>Como estilizar os componentes React no Next.js?</p><p>Temos muita liberdade, porque podemos usar a biblioteca que preferirmos.</p><p>O Next.js, contudo, vem com o <a href="https://github.com/zeit/styled-jsx"><code>styled-jsx</code></a> integrado, pois ele é uma biblioteca dos mesmos criadores do Next.js.</p><p>Ele é uma biblioteca muito interessante, que nos fornece CSS em escopo, o que é ótimo para a manutenção, pois permite que o CSS afete apenas o componente no qual é aplicado.</p><p>Acho que essa é uma ótima abordagem para escrever CSS, sem a necessidade de aplicar bibliotecas adicionais ou pré-processadores adicionais que aumentam a complexidade.</p><p>Para adicionar CSS a um componente do React no Next.js, nós o inserimos dentro de um trecho de código no JSX, que começa com</p><pre><code class="language-js">&lt;style jsx&gt;{`</code></pre><p>e termina com</p><pre><code class="language-js">`}&lt;/style&gt;</code></pre><p>Dentro destes blocos estranhos, escrevemos CSS simples, como faríamos em um arquivo <code>.css</code>:</p><pre><code class="language-js">&lt;style jsx&gt;{`
  h1 {
    font-size: 3rem;
  }
`}&lt;/style&gt;
</code></pre><p>Você o escreve dentro do JSX, assim:‌</p><pre><code class="language-js">const Index = () =&gt; (
  &lt;div&gt;
		&lt;h1&gt;Home page&lt;/h1&gt;

		&lt;style jsx&gt;{`
		  h1 {
		    font-size: 3rem;
		  }
		`}&lt;/style&gt;
  &lt;/div&gt;
)

export default Index
</code></pre><p>Dentro do bloco, podemos usar a interpolação para alterar dinamicamente os valores. Por exemplo, aqui assumimos que um prop <code>size</code> está sendo passado pelo componente pai e o usamos no bloco <code>styled-jsx</code>:</p><pre><code class="language-js">const Index = props =&gt; (
  &lt;div&gt;
		&lt;h1&gt;Home page&lt;/h1&gt;

		&lt;style jsx&gt;{`
		  h1 {
		    font-size: ${props.size}rem;
		  }
		`}&lt;/style&gt;
  &lt;/div&gt;
)
</code></pre><p>Se você quiser aplicar algum CSS globalmente, não em escopo a um componente, você adiciona a palavra-chave <code>global</code> à tag de <code>style</code>:</p><pre><code class="language-jsx">&lt;style jsx global&gt;{`
body {
  margin: 0;
}
`}&lt;/style&gt;
</code></pre><p>Se você quiser importar um arquivo de CSS externo em um componente Next.js, precisa primeiramente instalar o <code>@zeit/next-css</code>:</p><pre><code class="language-bash">npm install @zeit/next-css</code></pre><p>Depois, é preciso criar um arquivo de configuração na raiz do projeto, chamado <code>next.config.js</code>, com esse conteúdo:‌</p><pre><code class="language-js">const withCSS = require('@zeit/next-css')
module.exports = withCSS()
</code></pre><p>Após reiniciar a aplicação do Next, você pode importar o CSS como normalmente faz com as bibliotecas do JavaScript ou componentes:</p><pre><code class="language-js">import '../style.css'
</code></pre><p>Você também pode importar um arquivo SASS diretamente, usando a biblioteca <a href="https://github.com/zeit/next-plugins/tree/master/packages/next-sass"><code>@zeit/next-sass</code></a>.</p><h2 id="preenchendo-a-tag-head-com-tags-personalizadas"><strong>Preenchendo a tag head com tags personalizadas</strong></h2><p>A partir de qualquer componente da página do Next.js, você pode adicionar informações ao cabeçalho da página.</p><p>Isso é útil quando:</p><ul><li>você quer personalizar o título da página</li><li>você quer mudar uma tag meta</li></ul><p>Como você pode fazer isso?</p><p>Dentro de cada componente, você pode importar o componente <code>Head</code> do <code>next/head</code> e incluí-lo na saída JSX do seu componente:</p><pre><code class="language-js">import Head from 'next/head'

const House = props =&gt; (
  &lt;div&gt;
    &lt;Head&gt;
      &lt;title&gt;The page title&lt;/title&gt;
    &lt;/Head&gt;
    {/* the rest of the JSX */}
  &lt;/div&gt;
)

export default House
</code></pre><p>Você pode adicionar qualquer tag HTML que gostaria que aparecesse na seção <code>&lt;head&gt;</code> da página.</p><p>Ao montar o componente, o Next.js se certificará de que as tags que estão dentro de <code>Head</code> sejam adicionadas ao cabeçalho da página. A mesma coisa ocorre quando da desmontagem do componente. O Next.js se encarregará de remover essas tags.</p><h2 id="adicionando-um-componente-wrapper">Adicionando um componente <em>wrapper</em></h2><p>Todas as páginas em seu site parecem mais ou menos as mesmas. Há uma janela, uma camada de base comum e você quer apenas mudar o que está dentro.</p><p>Há uma barra de navegação, uma barra lateral e, depois, o conteúdo real.</p><p>Como você cria um sistema assim no Next.js?</p><p>Há dois modos. Um deles é usar um<a href="https://flaviocopes.com/react-higher-order-components/"> componente de ordem superior</a> (texto em inglês), criando um componente em <code>components/Layout.js</code>:</p><pre><code class="language-js">export default Page =&gt; {
  return () =&gt; (
    &lt;div&gt;
      &lt;nav&gt;
        &lt;ul&gt;....&lt;/ul&gt;
      &lt;/hav&gt;
      &lt;main&gt;
        &lt;Page /&gt;
      &lt;/main&gt;
    &lt;/div&gt;
  )
}
</code></pre><p>Ali, podemos importar componentes separados para o cabeçalho e/ou barra lateral, além de adicionar todo o CSS de que precisamos.</p><p>Você poderá usar o CSS em cada página assim:</p><pre><code class="language-js">import withLayout from '../components/Layout.js'

const Page = () =&gt; &lt;p&gt;Here's a page!&lt;/p&gt;

export default withLayout(Page)
</code></pre><p>Descobri, porém, que isso funciona apenas para casos simples, onde você não precisa chamar <code>getInitialProps()</code> na página. Por quê?</p><p>Porque <code>getInitialProps()</code> só é chamado no componente de página. Mas se exportarmos o componente de ordem superior <code>withLayout()</code> de uma página, <code>Page.getInitialProps()</code> não será chamado. <code>withLayout.getInitialProps()</code> seria.</p><p>Para evitar complicar desnecessariamente a nossa base de código, a abordagem alternativa é usar <em>props</em>:</p><pre><code class="language-js">export default props =&gt; (
  &lt;div&gt;
    &lt;nav&gt;
      &lt;ul&gt;....&lt;/ul&gt;
    &lt;/hav&gt;
    &lt;main&gt;
      {props.content}
    &lt;/main&gt;
  &lt;/div&gt;
)
</code></pre><p>Em nossas páginas, agora, o usaremos assim:</p><pre><code class="language-js">import Layout from '../components/Layout.js'

const Page = () =&gt; (
  &lt;Layout content={(
    &lt;p&gt;Here's a page!&lt;/p&gt;
  )} /&gt;
)
</code></pre><p>Essa abordagem nos permite utilizar <code>getInitialProps()</code> de dentro de nosso componente de página, com a única desvantagem de ter de escrever o componente JSX dentro da <em>prop</em> <code>content</code>:‌ &nbsp; </p><pre><code class="language-js">import Layout from '../components/Layout.js'

const Page = () =&gt; (
  &lt;Layout content={(
    &lt;p&gt;Here's a page!&lt;/p&gt;
  )} /&gt;
)

Page.getInitialProps = ({ query }) =&gt; {
  //...
}
</code></pre><h2 id="rotas-de-api"><strong>Rotas de API</strong></h2><p>Além de criar <strong>rotas de páginas</strong>, o que significa que as páginas são servidas ao navegador como páginas da web, o Next.js pode criar <strong>rotas de API</strong>.</p><p>Essa é uma característica muito interessante, pois significa que o Next.js pode ser usado para criar um front-end para dados que são armazenados e recuperados pelo próprio Next.js, transferindo o JSON através de pedidos de busca.</p><p>As rotas de API vivem sob a pasta <code>/pages/api/</code> e são mapeadas para o <em>endpoint</em> <code>/api</code>.</p><p>Essa característica é <em>muito</em> útil quando criamos aplicações.</p><p>Nessas rotas, escrevemos o código em Node.js (ao invés do código em React). É uma mudança de paradigma: você passa do <em>front-end</em> para o <em>back-end</em>, sem problemas.</p><p>Digamos que você tenha um arquivo <code>/pages/api/comments.js</code>, cujo objetivo é devolver os comentários de um post de blog como JSON.</p><p>Então, suponhamos que você tenha uma lista de comentários armazenados em um arquivo <code>comments.json</code>:</p><pre><code class="language-json">[
  {
    "comment": "First"
  },
  {
    "comment": "Nice post"
  }
]</code></pre><p>Aqui está uma amostra de código, que retorna ao <em>client</em> a lista de comentários:</p><pre><code class="language-js">import comments from './comments.json'

export default (req, res) =&gt; {
  res.status(200).json(comments)
}
</code></pre><p>Ele ouvirá o URL <code>/api/comments</code> para solicitações GET e você pode tentar chamá-lo usando seu navegador:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-07-at-11.14.42.png" class="kg-image" alt="Screen-Shot-2019-11-07-at-11.14.42" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-07-at-11.14.42.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-07-at-11.14.42.png 914w" sizes="(min-width: 720px) 720px" width="914" height="833" loading="lazy"></figure><p>As rotas de API também podem usar <strong>roteamento dinâmico</strong>, assim como as páginas, usar a sintaxe [] para criar uma rota de API dinâmica, como <code>/pages/api/comments/[id].js</code>, o que recuperará os comentários específicos de um id de determinado post.</p><p>Dentro do <code>[id].js</code>, você pode recuperar o valor de <code>id</code> procurando dentro do objeto de <code>req.query</code>:</p><pre><code class="language-js">import comments from '../comments.json'

export default (req, res) =&gt; {
  res.status(200).json({ post: req.query.id, comments })
}
</code></pre><p>Aqui, você pode ver o código acima em ação:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-07-at-11.59.53.png" class="kg-image" alt="Screen-Shot-2019-11-07-at-11.59.53" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-07-at-11.59.53.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-07-at-11.59.53.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-07-at-11.59.53.png 1002w" sizes="(min-width: 720px) 720px" width="1002" height="487" loading="lazy"></figure><p>Em páginas dinâmicas, você precisaria importar o <code>useRouter</code> do <code>next/router</code>, depois obter o objeto <em>router </em>usando <code>const router = useRouter()</code>. Então, seríamos capazes de obter o valor de <code>id</code> usando <code>router.query.id</code>.</p><p>No lado do servidor, tudo é mais fácil, pois a consulta é anexada ao objeto de solicitação.</p><p>Se você fizer uma solicitação de POST, tudo funciona do mesmo modo – tudo passa por essa exportação padrão.</p><p>Para separar o POST do GET e de outros métodos HTTP (PUT, DELETE), procure o valor do método <code>req.method</code>:</p><pre><code class="language-js">export default (req, res) =&gt; {
  switch (req.method) {
    case 'GET':
      //...
      break
    case 'POST':
      //...
      break
    default:
      res.status(405).end() //Method Not Allowed
      break
  }
}
</code></pre><p>Além de <code>req.query</code> e do método <code>req.method</code> que já vimos, temos acesso aos cookies ao fazermos referência a <code>req.cookies</code>, e ao corpo da solicitação em <code>req.body</code>.</p><p>Internamente, tudo isso é desenvolvido pela <a href="https://github.com/zeit/micro">Micro</a>, uma biblioteca que fornece microsserviços HTTP assíncronos, feita pela mesma equipe que construiu o Next.js.</p><p>Você pode fazer uso de qualquer <em>middleware</em> da Micro em nossas rotas de API para adicionar mais funcionalidade.</p><h2 id="executando-o-c-digo-somente-no-lado-do-servidor-ou-do-client"><strong>Executando o código somente no lado do servidor ou do <em>client</em></strong></h2><p>Em seus componentes de página, você pode executar o código somente no lado do servidor ou no lado do <em>client</em>, verificando a propriedade <code>window</code>.</p><p>Essa propriedade só existe dentro do navegador, portanto você pode verificar</p><pre><code class="language-js">if (typeof window === 'undefined') {

}
</code></pre><p>Você também pode adicionar o código do lado do servidor nesse bloco.</p><p>Do mesmo modo, você pode executar o código do lado do <em>client</em> apenas verificando‌</p><pre><code class="language-js">if (typeof window !== 'undefined') {

}
</code></pre><p>Dica de JS: usamos aqui o operador <code>typeof</code>, pois não podemos detectar se um valor é <em>undefined</em> de outras maneiras. Não podemos fazer se <code>if (window === undefined)</code>, pois obteríamos um erro de tempo de execução "window is not defined" (<em>window</em> não está definido).</p><p>O Next.js, como uma otimização para o momento da <em>build</em>, também remove o código que usa essas verificações dos pacotes. Um pacote do lado do <em>client</em> não incluirá o conteúdo envolto em um bloco<code>(typeof window === 'undefined') {}</code>.</p><h2 id="fazendo-o-deploy-da-vers-o-em-produ-o"><strong>Fazendo o deploy da versão em produção</strong></h2><p>Fazer o <em>deploy</em> de uma aplicação é sempre deixado por último nos tutoriais.</p><p>Aqui, quero apresentá-lo mais cedo, só porque é tão fácil fazer um <em>deploy </em>de um aplicação do Next.js que podemos entrar nesse assunto agora e, depois, passar para os outros tópicos mais complexos.</p><p>Lembre-se de que, no capítulo "Como instalar o Next.js", eu disse para adicionar essas três linhas à seção de <code>script</code> do <code>package.json</code>:</p><pre><code class="language-json">"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "next start"
}
</code></pre><p>Usamos <code>npm run dev</code> até o momento, para chamar o comando <code>next</code> instalado localmente em <code>node_modules/next/dist/bin/next</code>. Isso iniciou o servidor de desenvolvimento, que nos forneceu <strong>mapas de fonte</strong> e <strong>recarregamento rápido de código </strong>(<em>hot code reloading</em>), duas características muito úteis durante a depuração.</p><p>O mesmo comando pode ser invocado para construir o site passando a <em>flag</em> de <code>build</code>, executando <code>npm run build</code>. Então, o mesmo comando pode ser usado para iniciar a aplicação de produção, passando a <em>flag</em> <code>start</code>, executando <code>npm run start</code>.</p><p>Esses dois comandos são os que devemos invocar para fazer o <em>deploy</em> com sucesso da versão de produção de nosso site localmente. A versão de produção é altamente otimizada e não vem com mapas de fonte e outras coisas como recarregamento rápido de código, que não seriam benéficas para os nossos usuários finais.</p><p>Então, vamos criar um <em>deploy</em> de produção de nossa aplicação. Fazemos o <em>build</em> usando:</p><pre><code class="language-bash">npm run build
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-13.46.31.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-13.46.31" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-13.46.31.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-13.46.31.png 962w" sizes="(min-width: 720px) 720px" width="962" height="642" loading="lazy"></figure><p>A saída do comando nos diz que algumas rotas (<code>/</code> e <code>/blog</code>) agora estão pré-renderizadas como HTML estático, enquanto <code>/blog/[id]</code> será servida pelo <em>back-end</em> do Node.js.</p><p>Então, você pode executar <code>npm run start</code> para iniciar o servidor de produção localmente:</p><pre><code class="language-bash">npm run start
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-13.47.01.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-13.47.01" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-13.47.01.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-13.47.01.png 962w" sizes="(min-width: 720px) 720px" width="962" height="354" loading="lazy"></figure><p>Ao visitar <a href="http://localhost:3000">http://localhost:3000</a>, veremos a versão de produção da aplicação, localmente.</p><h2 id="fazendo-o-deploy-no-now"><strong>Fazendo o <em>deploy</em> no Now</strong></h2><p>No capítulo anterior, fizemos o <em>deploy</em> da aplicação do Next.js localmente.</p><p>Como fazemos o <em>deploy</em> em um servidor da web de verdade para que outras pessoas possam acessá-lo?</p><p>Uma das maneiras mais simples de se fazer um <em>deploy </em>de uma aplicação do Next é através da plataforma <strong>Now,</strong> criada pela <a href="https://zeit.co/">Zeit</a>, a mesma empresa que criou o projeto de código aberto do Next.js. Você pode usar o Now para fazer o <em>deploy </em>de aplicações do Node.js, sites estáticos e muito mais.</p><p>O Now torna a etapa de <em>deploy </em>e a etapa de distribuição de uma aplicação muito simples e rápida. Além das aplicações do Node.js, também há suporte ao <em>deploy </em>de código em Go, PHP, Python e outras linguagens.</p><p>Você pode pensar nisso como a "nuvem", pois você não sabe realmente onde será feito o <em>deploy </em>de sua aplicação, mas sabe que terá um URL onde poderá acessá-la.</p><p>Now é grátis para começar a usar, com um generoso plano gratuito que atualmente inclui 100GB de hospedagem, mil invocações de funções <a href="https://www.freecodecamp.org/news/serverless/"><em>serverless</em></a> (texto em inglês) por dia, mil builds por mês, 100GB de largura de banda por mês, e uma localização de <a href="https://www.freecodecamp.org/news/cdn/">CDN</a> (texto em inglês). A<a href="https://zeit.co/pricing"> página de preços</a> ajuda a ter uma ideia dos custos, se você precisar de mais.</p><p>A melhor maneira de começar a usar o Now é por meio da CLI oficial do Now:</p><pre><code class="language-bash">npm install -g now
</code></pre><p>Uma vez que o comando esteja disponível, execute</p><pre><code class="language-bash">now login</code></pre><p>A aplicação, então, pedirá seu e-mail.</p><p>Se você ainda não se registrou, crie uma conta em <a href="https://zeit.co/signup">https://zeit.co/signup</a> antes de continuar, então adicione seu e-mail à CLI do <em>client</em>.</p><p>Uma vez feito isso, a partir da pasta raiz do projeto Next.js, execute</p><pre><code class="language-bash">now</code></pre><p>A aplicação fará o <em>deploy </em>instantaneamente na nuvem do Now, e você receberá o URL único da aplicação:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-14.21.09.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-14.21.09" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-14.21.09.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-14.21.09.png 962w" sizes="(min-width: 720px) 720px" width="962" height="426" loading="lazy"></figure><p>Uma vez executado o programa <code>now</code>, a aplicação é implantada em um URL aleatório sob o domínio <code>now.sh</code>.</p><p>Podemos ver três URLs diferentes na saída dada na imagem:</p><ul><li><a href="https://firstproject-2pv7khwwr.now.sh">https://firstproject-2pv7khwwr.now.sh</a></li><li><a href="https://firstproject-sepia-ten.now.sh">https://firstproject-sepia-ten.now.sh</a></li><li><a href="https://firstproject.flaviocopes.now.sh">https://firstproject.flaviocopes.now.sh</a></li></ul><p>Por que tantos?</p><p>O primeiro é o URL que identifica o <em>deploy</em>. Toda vez que fazemos o <em>deploy</em> da aplicação, esse URL mudará.</p><p>Você pode testar imediatamente, alterando algo no código do projeto, e executar <code>now</code> novamente:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-15.08.11.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-15.08.11" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-15.08.11.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-15.08.11.png 962w" sizes="(min-width: 720px) 720px" width="962" height="330" loading="lazy"></figure><p>Os outros dois URLs não mudarão. O primeiro é aleatório, enquanto o segundo é o nome do seu projeto (que por padrão é o nome da pasta do projeto atual, o nome de sua conta e, em seguida, <code>now.sh</code>.</p><p>Se você visitar o URL, verá a aplicação depois de feito o <em>deploy</em> para a produção.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-14.21.43.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-14.21.43" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-14.21.43.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-06-at-14.21.43.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-14.21.43.png 1013w" sizes="(min-width: 720px) 720px" width="1013" height="532" loading="lazy"></figure><p>Você pode configurar o Now para que sirva o site para o seu próprio domínio ou subdomínio personalizado, mas eu não vou me aprofundar nisso agora.</p><p>O subdomínio <code>now.sh</code> é suficiente para os nossos propósitos de teste.</p><h2 id="analisando-os-pacotes-da-aplica-o">Analisando os pacotes da aplicação</h2><p>O Next nos fornece uma forma de analisar os pacotes de códigos que são gerados.</p><p>Abra o arquivo <code>package.json</code> da aplicação e, na seção de scripts, adicione estes três novos comandos:</p><pre><code class="language-json">"analyze": "cross-env ANALYZE=true next build",
"analyze:server": "cross-env BUNDLE_ANALYZE=server next build",
"analyze:browser": "cross-env BUNDLE_ANALYZE=browser next build"</code></pre><p>Assim:</p><pre><code class="language-json">{
  "name": "primeiroprojeto",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start",
    "analyze": "cross-env ANALYZE=true next build",
    "analyze:server": "cross-env BUNDLE_ANALYZE=server next build",
    "analyze:browser": "cross-env BUNDLE_ANALYZE=browser next build"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "next": "^9.1.2",
    "react": "^16.11.0",
    "react-dom": "^16.11.0"
  }
}
</code></pre><p>Em seguida, instale estes dois pacotes:</p><pre><code class="language-bash">npm install --dev cross-env @next/bundle-analyzer
</code></pre><p>Crie um arquivo <code>next.config.js</code> na raiz do projeto, com este conteúdo:</p><pre><code class="language-js">const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true'
})

module.exports = withBundleAnalyzer({})
</code></pre><p>Agora execute o comando</p><pre><code class="language-bash">npm run analyze
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-16.12.40.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-16.12.40" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-16.12.40.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-06-at-16.12.40.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-16.12.40.png 1028w" sizes="(min-width: 720px) 720px" width="1028" height="834" loading="lazy"></figure><p>Isso deve abrir duas páginas no navegador. Uma para os pacotes dos <em>clients</em>, e outra para os pacotes de servidores:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-16.11.14.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-16.11.14" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-16.11.14.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-06-at-16.11.14.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-16.11.14.png 1392w" sizes="(min-width: 720px) 720px" width="1392" height="1529" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-16.11.23.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-16.11.23" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-16.11.23.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-06-at-16.11.23.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-16.11.23.png 1392w" sizes="(min-width: 720px) 720px" width="1392" height="1529" loading="lazy"></figure><p>Isso é incrivelmente útil. Você pode inspecionar o que ocupa mais espaço nos pacotes, e também usar a barra lateral para excluir os pacotes para ter uma visualização mais fácil dos menores:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-16.14.12.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-16.14.12" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-16.14.12.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-06-at-16.14.12.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-16.14.12.png 1392w" sizes="(min-width: 720px) 720px" width="1392" height="1529" loading="lazy"></figure><h2 id="m-dulos-de-lazy-loading">Módulos de <em>lazy loading</em></h2><p>Ser capaz de analisar visualmente um pacote é ótimo, pois podemos otimizar a nossa aplicação muito facilmente.</p><p>Digamos que precisamos carregar a biblioteca do Moment em nossos posts no blog. Execute:</p><pre><code class="language-bash">npm install moment
</code></pre><p>Desse modo, a incluiremos no projeto.</p><p>Agora, vamos simular o fato de que precisamos dele em duas rotas diferentes: <code>/blog</code> e <code>/blog/[id]</code>.</p><p>Nós importamos o Moment em <code>pages/blog/[id].js</code>:</p><pre><code class="language-jsx">import moment from 'moment'

...

const Post = props =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;{props.post.title}&lt;/h1&gt;
      &lt;p&gt;Published on {moment().format('dddd D MMMM YYYY')}&lt;/p&gt;
      &lt;p&gt;{props.post.content}&lt;/p&gt;
    &lt;/div&gt;
  )
}
</code></pre><p>Estou apenas adicionando a data de hoje, como um exemplo.</p><p>Isto incluirá o Moment.js no pacote de páginas de postagem do blog, como você pode ver executando <code>npm run analyze</code>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-17.56.14.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-17.56.14" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-17.56.14.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-06-at-17.56.14.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-17.56.14.png 1028w" sizes="(min-width: 720px) 720px" width="1028" height="786" loading="lazy"></figure><p>Veja que, agora, temos uma entrada vermelha em <code>/blog/[id]</code>, a rota em que adicionamos o Moment.js!</p><p>Ela passou de cerca de 1kB para 350kB – isso é muito importante. Isso ocorre porque a biblioteca do Moment.js em si é de 349kB.</p><p>A visualização dos pacotes dos <em>clients</em> agora nos mostra que o pacote maior é a página um, que antes era muito pequena. 99% do tamanho de seu código é relacionado ao Moment.js.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-17.55.50.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-17.55.50" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-17.55.50.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-06-at-17.55.50.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-17.55.50.png 1392w" sizes="(min-width: 720px) 720px" width="1392" height="1529" loading="lazy"></figure><p>Toda vez que carregarmos um post no blog, teremos todo esse código transferido para o <em>client</em>. O que não é o ideal.</p><p>Uma correção seria procurar uma biblioteca com um tamanho menor, pois o Moment.js não é conhecido por ser leve (especialmente de início, com todos os idiomas incluídos). Vamos supor, em função do exemplo, contudo, que devemos usá-lo.</p><p>O que podemos fazer é colocar todo o código do Moment em um <strong>pacote separado</strong>.</p><p>Como? Em vez de importar o Moment no nível do componente, realizamos uma importação async dentro do <code>getInitialProps</code> e calculamos o valor a ser enviado ao componente. Lembre-se de que não podemos retornar objetos complexos dentro do objeto retornado pelo <code>getInitialProps()</code>. Então, calculamos a data dentro dele:</p><pre><code class="language-js">import posts from '../../posts.json'

const Post = props =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;{props.post.title}&lt;/h1&gt;
      &lt;p&gt;Published on {props.date}&lt;/p&gt;
      &lt;p&gt;{props.post.content}&lt;/p&gt;
    &lt;/div&gt;
  )
}

Post.getInitialProps = async ({ query }) =&gt; {
  const moment = (await import('moment')).default()
  return {
    date: moment.format('dddd D MMMM YYYY'),
    post: posts[query.id]
  }
}

export default Post
</code></pre><p>Você vê aquela chamada especial para <code>.default()</code> depois de <code>await import</code>? É necessário referenciar a exportação padrão em uma importação dinâmica (ver <a href="https://v8.dev/features/dynamic-import">https://v8.dev/features/dynamic-import</a> – texto em inglês)</p><p>Agora, se executarmos <code>npm run analyze</code> novamente, podemos ver o seguinte:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-18.00.22.png" class="kg-image" alt="Screen-Shot-2019-11-06-at-18.00.22" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screen-Shot-2019-11-06-at-18.00.22.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screen-Shot-2019-11-06-at-18.00.22.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screen-Shot-2019-11-06-at-18.00.22.png 1028w" sizes="(min-width: 720px) 720px" width="1028" height="786" loading="lazy"></figure><p>O nosso pacote <code>/blog/[id]</code> é novamente muito pequeno, pois o Moment foi movido para o seu próprio arquivo de pacote, carregado separadamente pelo navegador.</p><h2 id="para-onde-ir-a-partir-daqui">Para onde ir a partir daqui</h2><p>Há muito mais a saber sobre o Next.js. Eu não falei sobre gerenciar sessões de usuários com login, <em>serverless</em>, gerenciamento de bancos de dados e assim por diante.</p><p>O objetivo deste manual não é ensinar tudo. Ao invés disso, ele busca apresentar, gradualmente, todo o poder do Next.js.</p><p>O próximo passo que recomendo é fazer uma boa leitura na <a href="https://nextjs.org/docs">documentação oficial do Next.js</a> (em inglês) para saber mais sobre todas as características e funcionalidades das quais não falei, além de dar uma olhada em todas as funcionalidades adicionais introduzidas pelos <a href="https://github.com/zeit/next-plugins">plug-ins do Next.js</a>, algumas das quais são bastante surpreendentes.</p><p>Você pode entrar em contato com o autor pelo <a href="https://twitter.com/flaviocopes">Twitter</a>.</p><p>Confira também o site do autor, <a href="https://flaviocopes.com/">flaviocopes.com</a>.</p><p><a href="https://flaviocopes.com/page/nextjs-handbook/">Observação: você pode baixar uma versão em PDF/ePub/Mobi deste tutorial para ler off-line!</a></p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
