Boas-vindas a mais um curso Next! Me chamo Patricia Silva.
Audiodescrição: Patricia é uma mulher branca de cabelos cacheados. Usa óculos e veste uma camisa quadriculada azul.
Neste novo desafio, vamos implementar e evoluir uma aplicação existente, que é o Meteora.
3500-meteora-next-14.vercel.app
O Meteora já está aberto no meu navegador. Ele é um e-commerce e temos duas páginas. A primeira é a página que lista todos os produtos, onde temos imagens e botões. A segunda é a página de detalhes do produto, que é uma rota dinâmica.
Vamos enfrentar alguns desafios para tornar essa página, que é dinâmica, em uma página estática.
Estamos falando de uma página dinâmica, que renderiza do lado do servidor, mas que no final será puramente estática. O Next permite termos páginas dinâmicas e páginas estáticas na mesma aplicação. Um dos grandes pilares de vantagens de um site estático é a performance.
A pessoa usuária vai poder acessar a página de uma forma muito mais rápida. A carga do servidor vai diminuir, porque as páginas podem ser buscadas do cache. Elas são distribuídas pela CDN, então, dependendo da localização geográfica da pessoa usuária, ela vai receber essas páginas de uma forma muito mais rápida.
Portanto, o grande pilar da performance é o foco principal.
Para aprender tudo isso, é necessário ter conhecimento em HTML, CSS, principalmente em JavaScript e React.
Vamos lá?
Já baixei o projeto e o clonei em minha máquina, e ele está aberto no Visual Studio Code (VS Code).
Analisaremos a estrutura do projeto.
No VS Code, do lado esquerdo, na barra de exploração de arquivos; temos, por exemplo, o package.json
, que descreve as configurações do projeto e as bibliotecas importadas.
Temos também o next.config.mjs
, onde configuramos um provedor externo de imagens. As imagens estão hospedadas em outro lugar, não dentro do projeto.
Temos a pasta src
(source), os mocks
do projeto, que são de produtos
e categorias
. É uma estrutura fixa, toda a estrutura está simulada aqui. Abrindo o arquivo produtos.js
, podemos verificar todos os produtos. Fechando esse arquivo, temos o arquivo de categorias.js
, onde estão todas as categorias.
Cada categoria tem uma estrutura de nome e a imagem que está hospedada em um outro servidor externo, no caso, o GitHub.
Fechando a pasta mocks
, temos um diretório lib
com um arquivo chamado api.js
. Esse arquivo api
é apenas para facilitar, para termos métodos para buscar os produtos, todas as categorias, ou buscar os produtos pelo id, pelo slug, etc. Por exemplo, desejamos apenas o produto 1 ou 2.
Na atual configuração do Next 14, a estrutura principal é a pasta app
. Neste contexto, abandonamos a utilização do app router
e das pages
. Em vez disso, centralizamos todos os elementos necessários na pasta app
, que inclui diversos componentes
como categorias
, Footer
, Header
, Produto
, detalhe do produto, listagem completa de produtos, bem como os ícones associados.
Fechamos a pasta componentes
.
Temos a pasta produto/[slug]
, que é uma página dinâmica, onde vamos especificar qual é o produto que queremos acessar, e conseguiremos renderizar os detalhes daquele produto.
Agora, precisamos rodar o projeto localmente no navegador.
Já estamos com o terminal aberto e estamos usando o yarn. Duas coisas que vamos fazer são: instalar as dependências do projeto e garantir que estamos usando o node 18.19. Recomendamos usar 18.17+.
Vamos limpar o terminal e rodar yarn dev
, porque no package.json
, o yarn dev
sobe o servidor do Next. Digitamos no terminal yarn dev
, que vai abrir o localhost na porta 3000.
yarn dev
Obtemos:
Indo para o navegador e colocando o http://localhost:3000, a página renderiza corretamente.
Clicando em "Ver mais" de um produto, por exemplo, nessa camiseta, abre a página de detalhe do produto. Perceba que a URL também muda, é /produto/1
, porque o 1 é o ID desse produto, e é dessa forma que recuperamos o detalhe desse produto.
Mudando para a aba do GitHub, é onde criamos um projeto chamado Meteora Assets. Nele adicionamos todas as imagens de produto e categorias. Clicando em produtos, temos as imagens de produto aqui, e categorias.
Por que decidimos colocar esses assets em um projeto separado e não incorporá-los dentro do projeto do Meteora em si? Porque temos uma facilidade maior de gerenciar essas imagens.
Na hora de fazer o build do projeto, que é pegar todo aquele código e empacotar para que ele se torne estático, será muito mais rápido, o projeto terá um tamanho muito menor, porque as imagens não estão lá dentro.
Além disso, quando as imagens estão em um host externo, não teremos gasto de servidor quando hospedarmos esse projeto no final. Para gerenciar melhor essas imagens, achamos muito mais fácil dividir essa complexidade, deixar as imagens em um projeto só cuidando delas lá, e então usamos apenas por meio de links as imagens dentro do projeto, é muito mais simples de gerenciá-las.
Agora, precisamos evoluir essa aplicação e aplicar estratégias a cada passo que avançamos. Estamos mais perto de completar essa Static Site Generation (Geração de Site Estático), pois basicamente temos que aplicar estratégias para que, no final, consigamos atingir o resultado.
Retornamos ao VSCode, navegamos na estrutura de diretórios dentro de "src > app". Temos o arquivo page.js
. Esta é a página inicial do site, onde listamos todos os produtos.
page.js
// código omitido
export default async function Home () {
const produtos = getTodosProdutos();
const categorias = getCategorias();
// código omitido
Na linha 7, fazemos um getTodosProdutos()
, entramos nesse método nele clicando sobre ele. Ele está localizado dentro de "lib > api.js". Mais ou menos na linha 5, esse método retorna um mock de produtos.
api.js
import { produtos } from "../mocks/produtos";
import { categorias } from "../mocks/categorias";
export function getTodos Produtos () {
return produtos;
}
// código omitido
Nós acessamos o mock de produtos na primeira linha do arquivo através do caminho "../mocks/produtos". Somos redirecionados para o arquivo produtos.js
. Note que este mock consiste em um array estático de objetos que representam produtos.
Retornando ao método no arquivo api.js
, ele é bastante simples e não é assíncrono; simplesmente fazemos uma chamada para obter os mocks dos produtos. Agora que concluímos a exposição da estrutura desta api.js
, vamos passar para o arquivo page.js
, na linha 7, onde substituiremos essa operação getTodosProdutos()
por uma rota de API (api route).
page.js
// código omitido
export default async function Home () {
const produtos = getTodosProdutos();
const categorias = getCategorias();
// código omitido
Vamos realizar um fetch
em uma API route de produtos que criaremos agora, pois isso nos aproximará da nossa estratégia de geração de um site estático.
Primeiro, criaremos essa API route de produtos.
Então, dentro do diretório app
, criaremos um subdiretório chamado api
. Dentro deste, criaremos outro diretório chamado produtos
, e dentro de produtos, criaremos um arquivo chamado route.js
.
Seremos redirecionados para o arquivo route.js
.
Primeiro, iremos importar alguns facilitadores, como o NextResponse
, que vem do nextServer e nos ajuda a retornar respostas de forma mais eficiente. Também iremos importar o método getTodosProdutos
, que já está retornando nosso objeto de produtos.
route.js
import { NextResponse } from "next/server";
import { getTodos Produtos } from "@/lib/api";
Por enquanto, esses dados serão mockados dentro do projeto, já que ainda não temos um back-end ou qualquer serviço externo que retorne os produtos. No entanto, isso é algo que esperamos ter no futuro.
Criamos uma função que será exportada como assíncrona: export async function
. O nome dela será GET(){}
. Dentro dessa função, criamos uma constante chamada produtos
, na qual chamamos o método getTodosProdutos()
, obtendo assim todos os produtos disponíveis. Agora, vamos retornar utilizando return NextResponse.json({})
, passando como argumento um objeto contendo os produtos
.
route.js
import { NextResponse } from "next/server";
import { getTodos Produtos } from "@/lib/api";
export async function GET() {
const produtos = getTodosProdutos();
return NextResponse.json({ produtos });
}
Assim, temos uma API route de produtos.
Testaremos esse get
no navegador. Voltamos para o navegador, e já vamos inserir o endereço localhost:3000/api/produtos.
localhost:3000/api/produtos
Retornou um objeto de produtos que tem um array de produtos. Nossa API route de produtos está funcionando corretamente.
Agora, voltamos para o VS Code. Fechamos o arquivo route.ja
. Aqui na página page.js
, criamos um método que vai fazer um fetch
para aquela API route.
Criamos após o import
uma async function fetchProductosApi()
. No corpo dessa função, criamos uma constante que vai receberá o resultado do fetch
. Portanto, após o const res
colocamos um await fetch
, o fetch
vamos fazer para http://localhost:3000/api/produtos.
page.js
// código omitido
async function fetchProductosApi() {
const res = await fetch("http://localhost:3000/api/produtos");
}
// código omitido
Agora, criamos uma condição onde, se essa resposta não for ok
(if(!res.ok)
), vamos lançar um throw New Error()
. Passamos "não foi possível obter os dados" para esse erro.
page.js
// código omitido
async function fetchProductosApi() {
const res = await fetch("http://localhost:3000/api/produtos");
if(!res.ok) {
throw new Error("Não foi possível obter os dados")
}
}
// código omitido
Nossa próxima etapa é estabelecer uma variável constante para os produtos. Nessa variável, vamos receber a resposta em formato JSON com await res.json()
. Feito isso, vamos retornar os produtos utilizando return produtos
.
page.js
// código omitido
async function fetchProductosApi() {
const res = await fetch("http://localhost:3000/api/produtos");
if(!res.ok) {
throw new Error("Não foi possível obter os dados")
}
const produtos = await res.json();
return produtos;
}
// código omitido
Agora que temos a fetchProductosApi()
pronta, dentro do método da página, na linha 19, onde anteriormente estávamos fazendo um getTodosProdutos()
, chamamos o fetch
.
Utilizamos o await fetchProductosApi()
. No entanto, em produtos
, ao invés de atribuir o resultado diretamente à constante, faremos uma desestruturação para extrair apenas a propriedade produtos do objeto retornado. Dessa forma, teremos apenas o array de produtos, que será passado como argumento para o componente de produtos na linha 26.
page.js
// código omitido
export default async function Home () {
const produtos = await fetchProductosApi()
const categorias = getCategorias();
// código omitido
Vamos voltar no navegador, na página localhost:3000, teclamos "F5". Continua funcionando corretamente.
Voltamos para o VSCode, estamos consumindo API route. Agora, estamos fazendo uma requisição HTTP para uma API. Paramos o servidor com ^C
no terminal, vamos limpar com clear
, e rodar o yarn build
.
yarn build
O yarn build
é um comando que compila todo o projeto para gerar um projeto estático, para gerar HTML, CSS e Javascript, que é o que o navegador entende.
Queremos mostrar para vocês uma coisa: no output do yarn build
, reparem que a rota barra (/
) é estática, esse círculo é o símbolo de estático, e o nosso /api/produtos
também é estático.
No entanto, ainda temos a página de detalhes do produto, /produto/[slug]
, que vai receber o ID do produto e vai renderizar o detalhe do produto. Ele está marcado como dinâmico, é uma URL, uma rota dinâmica.
Mas esse símbolo de dinâmico (lambda) significa que a rota está sendo renderizada no servidor, é SSR. No entanto, precisamos trabalhar nisso, precisamos fazer com que essa rota também seja estática.
Portanto, daqui para frente, vamos seguir os passos para nos aproximarmos da geração deste site estático e vamos verificar no output do yarn build
se conseguimos atingir esse objetivo.
Então, o que buscamos é uma página que está acessando os produtos através de uma API, ou seja, estamos fazendo uma requisição HTTP e recuperando esses dados. Isso faz parte da progressão da nossa estratégia para gerar o site estático no final.
Portanto, acompanhem-nos, pois ainda não terminamos; precisamos implementar outras estratégias.
O curso Next.js: gerando site estático com SSG possui 96 minutos de vídeos, em um total de 32 atividades. Gostou? Conheça nossos outros cursos de Next.JS em Front-end, ou leia nossos artigos de Front-end.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.