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
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
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
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
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
Criando uma constante de produtos
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
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
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.
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.
Conclusão e Próximos Passos
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.