#################################################################################################### 01. Criando estrutura do app: [Commit: Criando estrutura do app](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/2fdf95b4f7f166a6b5b55deb916eeef59ffd3d0f) [Figma devstore](https://www.figma.com/community/file/1299037596397442545/devstore-projeto-react) Nesta aula, vamos desenvolver um projeto de e-commerce usando o Next.js com Server Components. O projeto terá funcionalidades básicas, como listagem de produtos, carrinho e busca. Vamos criar um modal para exibir os detalhes do produto quando o usuário clicar em um item. Além disso, vamos aprender sobre interceptação de rotas no Next.js. O foco principal será a busca e exibição de dados de uma API. Utilizaremos imagens de camisetas e moletons da Rocketseat. Vamos configurar o projeto, instalar dependências e configurar o ESLint. Em seguida, começaremos a criar as páginas do projeto. #################################################################################################### 02. Configurando Favicon: [Commit: Configurando Favicon](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/a9168bb93934c6e889d7dd20215910cf8446a53c) Nesta aula, exploramos as funcionalidades do app folder do Next.js, que permite o uso de server components. Aprendemos que o Next.js utiliza nomes de arquivos específicos dentro da pasta app para diferentes propósitos, como criação de páginas, layouts e loading. Também vimos como configurar o favicon e criar arquivos de metadata, como robots.txt, sitemap.xml, manifesto, OpenGraphImage e TwitterImage. Além disso, discutimos a possibilidade de gerar imagens dinâmicas usando código e a opção de usar arquivos de imagem estática para o favicon. #################################################################################################### 03. Criando layout da aplicação: [Commit: Criando layout da aplicação](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/1b8d3e58e11325420899ae2d6ff06e264acc2282) Nesta aula, vamos criar o layout base da nossa aplicação. Vamos começar entendendo que esse layout será aplicado em todas as páginas, mas pode ser que no futuro tenhamos páginas com estruturas diferentes. Para lidar com isso, podemos criar pastas dentro da pasta "app" para agrupar arquivos relacionados a um mesmo grupo de rotas. Por exemplo, podemos criar uma pasta chamada "store" para as páginas relacionadas à loja. Dentro dessa pasta, podemos criar um novo layout específico para a loja. Além disso, podemos criar componentes como o cabeçalho e o loading para serem utilizados nas páginas. #################################################################################################### 04. Componente - Header: [Commit: Componente: Header](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/87be840d7f98ab77dff6380e86b7769e1052c3b9) Nesta aula, aprendemos a estilizar o cabeçalho de uma aplicação utilizando Tailwind CSS. Começamos definindo as cores de fundo e texto do cabeçalho. Em seguida, criamos a estrutura do cabeçalho, dividindo-o em duas seções: uma para o logo e a busca, e outra para o carrinho e a conta do usuário. Utilizamos classes do Tailwind CSS para alinhar e espaçar os elementos corretamente. Também adicionamos ícones e estilizamos o formulário de busca. Por fim, finalizamos o cabeçalho adicionando uma barra separadora entre os links. #################################################################################################### 05. Página - Home: [Commit: Página: Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/6d383571fe8ca584edda5f93cfe1d6ab66bc4155) Nesta aula, vamos criar a estrutura visual da página inicial do nosso projeto. Começaremos exportando as imagens dos produtos e, em seguida, configuraremos a div que conterá os produtos. Usaremos um grid para organizar os elementos e aplicaremos estilos aos elementos internos com base no estado do elemento pai. Também adicionaremos os preços dos produtos e ajustaremos a posição deles. Por fim, faremos alguns ajustes no layout e adicionaremos as imagens dos produtos. #################################################################################################### 06. Route Handlers no Next.js: [Commit: Route Handlers no Next.js](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/4058f9351b797a85a459124f9016c9344eebe19b) Nesta aula, exploramos a funcionalidade de renderização de componentes pelo lado do servidor no Next.js. Isso significa que uma aplicação Next.js também é uma aplicação Node.js, o que nos permite criar rotas de API dentro do projeto. Essas rotas de API podem ser usadas para realizar diversas tarefas, como enviar e-mails, acessar bancos de dados e autenticação. No entanto, é importante ter em mente que essas rotas não são recomendadas para criar APIs completas, pois isso acopla o código do backend ao código do frontend. Em vez disso, elas são mais adequadas para funcionalidades específicas do frontend, como autenticação social. No exemplo dado, criamos uma rota de API que retorna uma lista de produtos destacados. Essa rota pode ser acessada através de `/api/products/featured`. #################################################################################################### 08. Criando Fetch API wrapper: [Commit: Criando Fetch API wrapper](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/9f1fe157693cfaef1eea4bccd6e51e239c1f041a) Nesta aula, aprendemos a criar uma requisição do front-end para a nossa API no Next.js. Como não temos um back-end separado, improvisamos um back-end dentro do próprio Next.js. Em vez de usar o Axios, utilizamos a Fetch API do navegador, que é estendida pelo Next.js para adicionar funcionalidades como caching. Criamos um arquivo api.ts para definir uma função que executa a Fetch API com base em uma URL de base e uma URL específica. Também configuramos variáveis de ambiente para armazenar a URL de base da API. Utilizamos o Zod para validar e transformar as variáveis de ambiente. Por fim, importamos as variáveis de ambiente e usamos a função api para carregar os dados na nossa rota. #################################################################################################### 09. Fetch de produtos na Home: [Commit: Fetch de produtos na Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/ded96fe24617f284b6524b46d640f3a067b77ac6) Nesta aula, aprendemos a carregar os dados dos produtos em destaque na página inicial do nosso projeto. Criamos uma função chamada `getFeaturedProducts` que faz uma requisição para a nossa API usando o `fetch`. Também fizemos algumas manipulações na URL da API para garantir que ela esteja correta. Em seguida, utilizamos o `response.json()` para obter os produtos e os retornamos. Na página inicial, chamamos essa função e exibimos os produtos em destaque. Também criamos um arquivo de tipos para fazer a tipagem dos produtos. Além disso, formatamos o preço para exibir em reais e removemos os centavos. Por fim, utilizamos o `map` para exibir os outros produtos em links. #################################################################################################### 10. Cache & Memoization: [Commit: Cache & Memoization](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/096466350c310254e0e3849a4b35fd925fdc676c) A Memoização é uma funcionalidade do React que evita requisições duplicadas durante o carregamento de uma página. Quando usamos Server Components, o React automaticamente impede que uma requisição seja feita mais de uma vez. No entanto, a Memoização não se aplica a requisições feitas em páginas diferentes. Para evitar requisições duplicadas em páginas diferentes, é necessário utilizar o Cache. O Next.js possui propriedades para controle de Cache, como a opção `force-cache`, que permite cachear uma requisição, e a opção `no-store`, que impede o cache. Além disso, há a opção `revalidate`, que define um tempo em segundos para atualizar o cache da requisição. #################################################################################################### 11. Loading na Home: [Commit: Loading na Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/44f795a7839ad6d969d628e1c587f9c7a9d023e6) Nesta aula, aprendemos a criar uma página de carregamento (loading) para a nossa aplicação. Isso é importante porque, quando fazemos chamadas assíncronas, como uma requisição HTTP, a página pode demorar para carregar e isso pode causar uma experiência ruim para o usuário. Para simular esse atraso, adicionamos um delay nas chamadas HTTP da nossa aplicação. Em seguida, criamos um componente chamado `skeleton` que servirá como base para todas as páginas que precisarem de um sinal de carregamento. Esse componente é uma `div` com uma animação em cinza claro e pode ter sua largura e altura configuradas de acordo com onde for utilizado. Utilizamos o `tailwind-merge` para unir as classes estáticas do componente com as classes recebidas por meio das props, evitando que as classes sejam substituídas. Agora, podemos continuar a implementação da página de carregamento na nossa Home. #################################################################################################### 12. Página - Detalhe do produto: [Commit: Página: Detalhe do produto](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/c96fb82958c0d939b3f6fd8ceca6b33a0885c835) Nesta aula, vamos criar a página de um produto em um site de comércio eletrônico. Vamos começar criando uma nova pasta chamada `product` dentro da pasta `app/store`. Dentro dessa pasta, vamos criar um arquivo chamado `page.tsx` e exportar um componente chamado `Product`. Em seguida, vamos estruturar a página, adicionando uma `div` com uma classe `relative grid` e definindo uma altura máxima de 860 pixels. Vamos adicionar a descrição e o preço do produto, estilizando-os adequadamente. Em seguida, vamos adicionar uma tabela de tamanhos e um botão para adicionar o produto ao carrinho. Por fim, vamos dividir a página em três colunas, com a imagem ocupando duas colunas e os detalhes do produto ocupando uma coluna. Vamos adicionar a imagem usando o componente `next/image` e estilizar as informações do produto. #################################################################################################### 13. Fetch de dados no Produto: [Commit: Fetch de dados no Produto](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/d07d4207397f594e7b8077a2dd258e210565c0a8) Nesta aula, aprendemos a criar uma rota na API para buscar detalhes de um único produto com base no slug. Utilizamos a estrutura de colchetes no Next.js para receber o parâmetro slug na URL. Em seguida, criamos um handler para essa rota, onde recebemos o parâmetro `slug` e validamos se é uma `string`. Em seguida, buscamos o produto com base no slug e retornamos o produto encontrado ou uma mensagem de erro caso o produto não exista. Na página de produto, utilizamos essa rota para buscar e exibir as informações do produto com base no slug. #################################################################################################### 14. Page Metadata no Next.js (SEO): [Commit: Page Metadata no Next.js (SEO)](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/0ef1d3582c9c6630c9bb684428cbe2a42e9b382e) Nesta aula, aprendemos sobre a geração de metadados dinâmicos no Next.js. Vimos como usar a função `generateMetadata` para retornar parâmetros específicos para cada página, como o título do produto. Também exploramos a memoização, que evita chamadas HTTP duplicadas ao identificar que a mesma chamada está sendo feita em diferentes ambientes dentro da mesma página. Além disso, discutimos a importância dos metadados para compor as tags no cabeçalho do HTML, como o título, descrição e outros elementos. Aprendemos a substituir e personalizar os metadados para cada página, usando templates e opções de fallback. #################################################################################################### 15. Geração estática na build: [Commit: Geração estática na build](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/5c8f0b87da98626a01e222ddda6fdd324a0372ef) Nesta aula, vamos falar sobre geração estática no Next.js. A geração estática permite criar uma versão em cache das páginas da aplicação antes de serem publicadas. Isso significa que quando um usuário acessar uma página, ela será exibida de forma instantânea, sem a necessidade de fazer requisições adicionais. Para utilizar a geração estática, podemos exportar uma função chamada `generateStaticParams` dentro de uma página que recebe parâmetros dinâmicos. Essa função deve retornar um array de objetos, onde cada objeto representa um parâmetro que desejamos gerar de forma estática. É importante ressaltar que a geração estática deve ser utilizada com cuidado, pois pode aumentar o tempo de build do projeto. Recomenda-se utilizar a geração estática apenas para páginas que são realmente importantes e que precisam ser carregadas de forma rápida. #################################################################################################### 16. Contexto do carrinho: [Commit: Contexto do carrinho](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/9f0db3d979722caed84136beb468ad0ec4914327) Nesta aula, vamos começar a implementar a funcionalidade do carrinho em nossa aplicação. Para isso, vamos utilizar o contexto do React. Vamos criar um contexto chamado `CartContext` e um provedor chamado `CartProvider`. Dentro do contexto, teremos informações sobre os itens do carrinho e uma função `addToCart` para adicionar itens ao carrinho. Vamos utilizar o hook `useCart` para acessar o contexto em outros componentes. Por fim, vamos envolver nossa aplicação com o `CartProvider` para que todos os componentes tenham acesso ao contexto do carrinho. #################################################################################################### 17. Gerando OpenGraph Image: [Commit: Gerando OpenGraph Image](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/1ef56c4434f2e8de89c26aa20e6bafc3fce7398b) Nesta aula, aprendemos como gerar metadados dinâmicos para cada página de um projeto Next.js. Focamos especialmente na geração de imagens de compartilhamento personalizadas para cada produto. Utilizamos os arquivos OpenGraph Image para criar as imagens dinâmicas. Através do Next.js, podemos converter HTML em imagem utilizando o `ImageResponse`. Também exploramos a possibilidade de carregar fontes personalizadas e passar configurações adicionais para a geração da imagem. Ao final da aula, vimos como acessar os parâmetros dinâmicos da URL para gerar imagens diferentes para cada produto. #################################################################################################### 18. Adicionando ao carrinho: [Commit: Adicionando ao carrinho](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/24f00bf437a3586c4104d74a5fad6b51b264438b) Nesta aula, aprendemos a utilizar o contexto no Next.js para criar componentes cliente e servidor. Começamos adicionando o contexto do carrinho no `StoreLayout`. Em seguida, criamos um novo componente chamado `AddToCartButton` para encapsular a lógica de adicionar produtos ao carrinho. Também aprendemos a isolar ao máximo os componentes, transformando apenas o necessário em componentes cliente. Por fim, implementamos a funcionalidade de adicionar produtos ao carrinho na página de produto. #################################################################################################### 19. API - Busca de produtos: [Commit: API: Busca de produtos](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/5abca4d16b5e9658e906082d8a26b687e8939da5) Nesta aula, vamos começar a trabalhar na funcionalidade de busca da nossa aplicação. Primeiro, vamos criar uma rota chamada `search` na nossa API. Essa rota será responsável por receber a busca do usuário e retornar os produtos correspondentes. Em seguida, vamos construir a página de busca no frontend. Vamos receber o parâmetro de busca na URL e utilizá-lo para filtrar os produtos. Faremos uma busca case-insensitive, ou seja, não iremos diferenciar maiúsculas de minúsculas. Por fim, vamos verificar se o título do produto inclui a busca do usuário. #################################################################################################### 20. Página - Busca de produtos: [Commit: Página: Busca de produtos](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/4e0c947a74e3622dce643295941de12c63c3446e) Nesta aula, vamos criar a página de busca em nossa aplicação. Atualmente, quando o usuário digita algo na barra de busca, nada acontece. Vamos começar adicionando uma `div` que envolve todo o conteúdo da página. Dentro dessa `div`, teremos um parágrafo que exibirá os resultados da busca, com o termo de busca substituído. Em seguida, teremos outra `div` onde serão exibidos os resultados dos produtos da busca. Vamos utilizar um grid simples para organizar esses resultados. #################################################################################################### 21. Formulário de busca: [Commit: Formulário de busca](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/413a069326838adc87d9e82cc14c620603a28af4) Nesta aula, vamos aprender a redirecionar o usuário quando ele preencher a busca e pressionar Enter. Usaremos o `object.fromEntries` para transformar os dados do formulário em um objeto e acessar a `query` de busca. Se o campo de busca estiver vazio, não faremos nada. Caso contrário, usaremos o `router.push` para redirecionar o usuário para a página de busca. Também aprenderemos a manter o estado do campo de busca mesmo após atualizar a página, usando o `useSearchParams` para obter os parâmetros de busca da URL. Por fim, discutiremos a diferença entre `hard navigation` e `soft navigation` e como usar o `useRouter` para realizar a `soft navigation`. #################################################################################################### 22. Buscando produtos da API: [Commit: Buscando produtos da API](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/891a35cf4c566ae8441212b8eda2194da1829321) Nesta aula, aprendemos a criar uma página de busca no Next.js. Começamos implementando a funcionalidade de redirecionamento do usuário para a página inicial caso ele tente acessar a página de busca sem um parâmetro de busca. Em seguida, utilizamos a API para buscar os produtos com base na query de busca fornecida pelo usuário. Implementamos a função `searchProducts` que recebe a query como parâmetro e retorna uma lista de produtos correspondentes. Por fim, utilizamos o método `map` para exibir os produtos na página de busca. Também exploramos duas formas de acessar o parâmetro de busca na URL: utilizando o `useSearchParams` em um componente cliente ou acessando o `searchParams` diretamente nas props do componente. #################################################################################################### 23. Loading da busca: [Commit: Loading da busca](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/abfc6daf77dc41d78dc1faad542767d5fd5b4682) Nesta aula, aprendemos a melhorar a página de carregamento em uma busca. Ajustamos o tempo de carregamento e o tamanho dos elementos para melhorar a experiência do usuário. Criamos uma página de carregamento mais adequada, utilizando uma estrutura semelhante à página de busca. No entanto, não conseguimos acessar os parâmetros de busca dentro da página de loading, então transformamos o componente em um componente cliente para poder utilizar o `useSearchParams`. Por fim, adicionamos um esqueleto de carregamento com altura definida. #################################################################################################### 01. Criando estrutura do app: [Commit: Criando estrutura do app](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/2fdf95b4f7f166a6b5b55deb916eeef59ffd3d0f) [Figma devstore](https://www.figma.com/community/file/1299037596397442545/devstore-projeto-react) Nesta aula, vamos desenvolver um projeto de e-commerce usando o Next.js com Server Components. O projeto terá funcionalidades básicas, como listagem de produtos, carrinho e busca. Vamos criar um modal para exibir os detalhes do produto quando o usuário clicar em um item. Além disso, vamos aprender sobre interceptação de rotas no Next.js. O foco principal será a busca e exibição de dados de uma API. Utilizaremos imagens de camisetas e moletons da Rocketseat. Vamos configurar o projeto, instalar dependências e configurar o ESLint. Em seguida, começaremos a criar as páginas do projeto. #################################################################################################### 02. Configurando Favicon: [Commit: Configurando Favicon](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/a9168bb93934c6e889d7dd20215910cf8446a53c) Nesta aula, exploramos as funcionalidades do app folder do Next.js, que permite o uso de server components. Aprendemos que o Next.js utiliza nomes de arquivos específicos dentro da pasta app para diferentes propósitos, como criação de páginas, layouts e loading. Também vimos como configurar o favicon e criar arquivos de metadata, como robots.txt, sitemap.xml, manifesto, OpenGraphImage e TwitterImage. Além disso, discutimos a possibilidade de gerar imagens dinâmicas usando código e a opção de usar arquivos de imagem estática para o favicon. #################################################################################################### 03. Criando layout da aplicação: [Commit: Criando layout da aplicação](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/1b8d3e58e11325420899ae2d6ff06e264acc2282) Nesta aula, vamos criar o layout base da nossa aplicação. Vamos começar entendendo que esse layout será aplicado em todas as páginas, mas pode ser que no futuro tenhamos páginas com estruturas diferentes. Para lidar com isso, podemos criar pastas dentro da pasta "app" para agrupar arquivos relacionados a um mesmo grupo de rotas. Por exemplo, podemos criar uma pasta chamada "store" para as páginas relacionadas à loja. Dentro dessa pasta, podemos criar um novo layout específico para a loja. Além disso, podemos criar componentes como o cabeçalho e o loading para serem utilizados nas páginas. #################################################################################################### 04. Componente - Header: [Commit: Componente: Header](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/87be840d7f98ab77dff6380e86b7769e1052c3b9) Nesta aula, aprendemos a estilizar o cabeçalho de uma aplicação utilizando Tailwind CSS. Começamos definindo as cores de fundo e texto do cabeçalho. Em seguida, criamos a estrutura do cabeçalho, dividindo-o em duas seções: uma para o logo e a busca, e outra para o carrinho e a conta do usuário. Utilizamos classes do Tailwind CSS para alinhar e espaçar os elementos corretamente. Também adicionamos ícones e estilizamos o formulário de busca. Por fim, finalizamos o cabeçalho adicionando uma barra separadora entre os links. #################################################################################################### 05. Página - Home: [Commit: Página: Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/6d383571fe8ca584edda5f93cfe1d6ab66bc4155) Nesta aula, vamos criar a estrutura visual da página inicial do nosso projeto. Começaremos exportando as imagens dos produtos e, em seguida, configuraremos a div que conterá os produtos. Usaremos um grid para organizar os elementos e aplicaremos estilos aos elementos internos com base no estado do elemento pai. Também adicionaremos os preços dos produtos e ajustaremos a posição deles. Por fim, faremos alguns ajustes no layout e adicionaremos as imagens dos produtos. #################################################################################################### 06. Route Handlers no Next.js: [Commit: Route Handlers no Next.js](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/4058f9351b797a85a459124f9016c9344eebe19b) Nesta aula, exploramos a funcionalidade de renderização de componentes pelo lado do servidor no Next.js. Isso significa que uma aplicação Next.js também é uma aplicação Node.js, o que nos permite criar rotas de API dentro do projeto. Essas rotas de API podem ser usadas para realizar diversas tarefas, como enviar e-mails, acessar bancos de dados e autenticação. No entanto, é importante ter em mente que essas rotas não são recomendadas para criar APIs completas, pois isso acopla o código do backend ao código do frontend. Em vez disso, elas são mais adequadas para funcionalidades específicas do frontend, como autenticação social. No exemplo dado, criamos uma rota de API que retorna uma lista de produtos destacados. Essa rota pode ser acessada através de `/api/products/featured`. #################################################################################################### 08. Criando Fetch API wrapper: [Commit: Criando Fetch API wrapper](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/9f1fe157693cfaef1eea4bccd6e51e239c1f041a) Nesta aula, aprendemos a criar uma requisição do front-end para a nossa API no Next.js. Como não temos um back-end separado, improvisamos um back-end dentro do próprio Next.js. Em vez de usar o Axios, utilizamos a Fetch API do navegador, que é estendida pelo Next.js para adicionar funcionalidades como caching. Criamos um arquivo api.ts para definir uma função que executa a Fetch API com base em uma URL de base e uma URL específica. Também configuramos variáveis de ambiente para armazenar a URL de base da API. Utilizamos o Zod para validar e transformar as variáveis de ambiente. Por fim, importamos as variáveis de ambiente e usamos a função api para carregar os dados na nossa rota. #################################################################################################### 09. Fetch de produtos na Home: [Commit: Fetch de produtos na Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/ded96fe24617f284b6524b46d640f3a067b77ac6) Nesta aula, aprendemos a carregar os dados dos produtos em destaque na página inicial do nosso projeto. Criamos uma função chamada `getFeaturedProducts` que faz uma requisição para a nossa API usando o `fetch`. Também fizemos algumas manipulações na URL da API para garantir que ela esteja correta. Em seguida, utilizamos o `response.json()` para obter os produtos e os retornamos. Na página inicial, chamamos essa função e exibimos os produtos em destaque. Também criamos um arquivo de tipos para fazer a tipagem dos produtos. Além disso, formatamos o preço para exibir em reais e removemos os centavos. Por fim, utilizamos o `map` para exibir os outros produtos em links. #################################################################################################### 10. Cache & Memoization: [Commit: Cache & Memoization](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/096466350c310254e0e3849a4b35fd925fdc676c) A Memoização é uma funcionalidade do React que evita requisições duplicadas durante o carregamento de uma página. Quando usamos Server Components, o React automaticamente impede que uma requisição seja feita mais de uma vez. No entanto, a Memoização não se aplica a requisições feitas em páginas diferentes. Para evitar requisições duplicadas em páginas diferentes, é necessário utilizar o Cache. O Next.js possui propriedades para controle de Cache, como a opção `force-cache`, que permite cachear uma requisição, e a opção `no-store`, que impede o cache. Além disso, há a opção `revalidate`, que define um tempo em segundos para atualizar o cache da requisição. #################################################################################################### 11. Loading na Home: [Commit: Loading na Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/44f795a7839ad6d969d628e1c587f9c7a9d023e6) Nesta aula, aprendemos a criar uma página de carregamento (loading) para a nossa aplicação. Isso é importante porque, quando fazemos chamadas assíncronas, como uma requisição HTTP, a página pode demorar para carregar e isso pode causar uma experiência ruim para o usuário. Para simular esse atraso, adicionamos um delay nas chamadas HTTP da nossa aplicação. Em seguida, criamos um componente chamado `skeleton` que servirá como base para todas as páginas que precisarem de um sinal de carregamento. Esse componente é uma `div` com uma animação em cinza claro e pode ter sua largura e altura configuradas de acordo com onde for utilizado. Utilizamos o `tailwind-merge` para unir as classes estáticas do componente com as classes recebidas por meio das props, evitando que as classes sejam substituídas. Agora, podemos continuar a implementação da página de carregamento na nossa Home. #################################################################################################### 12. Página - Detalhe do produto: [Commit: Página: Detalhe do produto](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/c96fb82958c0d939b3f6fd8ceca6b33a0885c835) Nesta aula, vamos criar a página de um produto em um site de comércio eletrônico. Vamos começar criando uma nova pasta chamada `product` dentro da pasta `app/store`. Dentro dessa pasta, vamos criar um arquivo chamado `page.tsx` e exportar um componente chamado `Product`. Em seguida, vamos estruturar a página, adicionando uma `div` com uma classe `relative grid` e definindo uma altura máxima de 860 pixels. Vamos adicionar a descrição e o preço do produto, estilizando-os adequadamente. Em seguida, vamos adicionar uma tabela de tamanhos e um botão para adicionar o produto ao carrinho. Por fim, vamos dividir a página em três colunas, com a imagem ocupando duas colunas e os detalhes do produto ocupando uma coluna. Vamos adicionar a imagem usando o componente `next/image` e estilizar as informações do produto. #################################################################################################### 13. Fetch de dados no Produto: [Commit: Fetch de dados no Produto](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/d07d4207397f594e7b8077a2dd258e210565c0a8) Nesta aula, aprendemos a criar uma rota na API para buscar detalhes de um único produto com base no slug. Utilizamos a estrutura de colchetes no Next.js para receber o parâmetro slug na URL. Em seguida, criamos um handler para essa rota, onde recebemos o parâmetro `slug` e validamos se é uma `string`. Em seguida, buscamos o produto com base no slug e retornamos o produto encontrado ou uma mensagem de erro caso o produto não exista. Na página de produto, utilizamos essa rota para buscar e exibir as informações do produto com base no slug. #################################################################################################### 14. Page Metadata no Next.js (SEO): [Commit: Page Metadata no Next.js (SEO)](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/0ef1d3582c9c6630c9bb684428cbe2a42e9b382e) Nesta aula, aprendemos sobre a geração de metadados dinâmicos no Next.js. Vimos como usar a função `generateMetadata` para retornar parâmetros específicos para cada página, como o título do produto. Também exploramos a memoização, que evita chamadas HTTP duplicadas ao identificar que a mesma chamada está sendo feita em diferentes ambientes dentro da mesma página. Além disso, discutimos a importância dos metadados para compor as tags no cabeçalho do HTML, como o título, descrição e outros elementos. Aprendemos a substituir e personalizar os metadados para cada página, usando templates e opções de fallback. #################################################################################################### 15. Geração estática na build: [Commit: Geração estática na build](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/5c8f0b87da98626a01e222ddda6fdd324a0372ef) Nesta aula, vamos falar sobre geração estática no Next.js. A geração estática permite criar uma versão em cache das páginas da aplicação antes de serem publicadas. Isso significa que quando um usuário acessar uma página, ela será exibida de forma instantânea, sem a necessidade de fazer requisições adicionais. Para utilizar a geração estática, podemos exportar uma função chamada `generateStaticParams` dentro de uma página que recebe parâmetros dinâmicos. Essa função deve retornar um array de objetos, onde cada objeto representa um parâmetro que desejamos gerar de forma estática. É importante ressaltar que a geração estática deve ser utilizada com cuidado, pois pode aumentar o tempo de build do projeto. Recomenda-se utilizar a geração estática apenas para páginas que são realmente importantes e que precisam ser carregadas de forma rápida. #################################################################################################### 16. Contexto do carrinho: [Commit: Contexto do carrinho](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/9f0db3d979722caed84136beb468ad0ec4914327) Nesta aula, vamos começar a implementar a funcionalidade do carrinho em nossa aplicação. Para isso, vamos utilizar o contexto do React. Vamos criar um contexto chamado `CartContext` e um provedor chamado `CartProvider`. Dentro do contexto, teremos informações sobre os itens do carrinho e uma função `addToCart` para adicionar itens ao carrinho. Vamos utilizar o hook `useCart` para acessar o contexto em outros componentes. Por fim, vamos envolver nossa aplicação com o `CartProvider` para que todos os componentes tenham acesso ao contexto do carrinho. #################################################################################################### 17. Gerando OpenGraph Image: [Commit: Gerando OpenGraph Image](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/1ef56c4434f2e8de89c26aa20e6bafc3fce7398b) Nesta aula, aprendemos como gerar metadados dinâmicos para cada página de um projeto Next.js. Focamos especialmente na geração de imagens de compartilhamento personalizadas para cada produto. Utilizamos os arquivos OpenGraph Image para criar as imagens dinâmicas. Através do Next.js, podemos converter HTML em imagem utilizando o `ImageResponse`. Também exploramos a possibilidade de carregar fontes personalizadas e passar configurações adicionais para a geração da imagem. Ao final da aula, vimos como acessar os parâmetros dinâmicos da URL para gerar imagens diferentes para cada produto. #################################################################################################### 18. Adicionando ao carrinho: [Commit: Adicionando ao carrinho](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/24f00bf437a3586c4104d74a5fad6b51b264438b) Nesta aula, aprendemos a utilizar o contexto no Next.js para criar componentes cliente e servidor. Começamos adicionando o contexto do carrinho no `StoreLayout`. Em seguida, criamos um novo componente chamado `AddToCartButton` para encapsular a lógica de adicionar produtos ao carrinho. Também aprendemos a isolar ao máximo os componentes, transformando apenas o necessário em componentes cliente. Por fim, implementamos a funcionalidade de adicionar produtos ao carrinho na página de produto. #################################################################################################### 19. API - Busca de produtos: [Commit: API: Busca de produtos](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/5abca4d16b5e9658e906082d8a26b687e8939da5) Nesta aula, vamos começar a trabalhar na funcionalidade de busca da nossa aplicação. Primeiro, vamos criar uma rota chamada `search` na nossa API. Essa rota será responsável por receber a busca do usuário e retornar os produtos correspondentes. Em seguida, vamos construir a página de busca no frontend. Vamos receber o parâmetro de busca na URL e utilizá-lo para filtrar os produtos. Faremos uma busca case-insensitive, ou seja, não iremos diferenciar maiúsculas de minúsculas. Por fim, vamos verificar se o título do produto inclui a busca do usuário. #################################################################################################### 20. Página - Busca de produtos: [Commit: Página: Busca de produtos](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/4e0c947a74e3622dce643295941de12c63c3446e) Nesta aula, vamos criar a página de busca em nossa aplicação. Atualmente, quando o usuário digita algo na barra de busca, nada acontece. Vamos começar adicionando uma `div` que envolve todo o conteúdo da página. Dentro dessa `div`, teremos um parágrafo que exibirá os resultados da busca, com o termo de busca substituído. Em seguida, teremos outra `div` onde serão exibidos os resultados dos produtos da busca. Vamos utilizar um grid simples para organizar esses resultados. #################################################################################################### 21. Formulário de busca: [Commit: Formulário de busca](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/413a069326838adc87d9e82cc14c620603a28af4) Nesta aula, vamos aprender a redirecionar o usuário quando ele preencher a busca e pressionar Enter. Usaremos o `object.fromEntries` para transformar os dados do formulário em um objeto e acessar a `query` de busca. Se o campo de busca estiver vazio, não faremos nada. Caso contrário, usaremos o `router.push` para redirecionar o usuário para a página de busca. Também aprenderemos a manter o estado do campo de busca mesmo após atualizar a página, usando o `useSearchParams` para obter os parâmetros de busca da URL. Por fim, discutiremos a diferença entre `hard navigation` e `soft navigation` e como usar o `useRouter` para realizar a `soft navigation`. #################################################################################################### 22. Buscando produtos da API: [Commit: Buscando produtos da API](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/891a35cf4c566ae8441212b8eda2194da1829321) Nesta aula, aprendemos a criar uma página de busca no Next.js. Começamos implementando a funcionalidade de redirecionamento do usuário para a página inicial caso ele tente acessar a página de busca sem um parâmetro de busca. Em seguida, utilizamos a API para buscar os produtos com base na query de busca fornecida pelo usuário. Implementamos a função `searchProducts` que recebe a query como parâmetro e retorna uma lista de produtos correspondentes. Por fim, utilizamos o método `map` para exibir os produtos na página de busca. Também exploramos duas formas de acessar o parâmetro de busca na URL: utilizando o `useSearchParams` em um componente cliente ou acessando o `searchParams` diretamente nas props do componente. #################################################################################################### 23. Loading da busca: [Commit: Loading da busca](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/abfc6daf77dc41d78dc1faad542767d5fd5b4682) Nesta aula, aprendemos a melhorar a página de carregamento em uma busca. Ajustamos o tempo de carregamento e o tamanho dos elementos para melhorar a experiência do usuário. Criamos uma página de carregamento mais adequada, utilizando uma estrutura semelhante à página de busca. No entanto, não conseguimos acessar os parâmetros de busca dentro da página de loading, então transformamos o componente em um componente cliente para poder utilizar o `useSearchParams`. Por fim, adicionamos um esqueleto de carregamento com altura definida. #################################################################################################### 01. Criando estrutura do app: [Commit: Criando estrutura do app](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/2fdf95b4f7f166a6b5b55deb916eeef59ffd3d0f) [Figma devstore](https://www.figma.com/community/file/1299037596397442545/devstore-projeto-react) Nesta aula, vamos desenvolver um projeto de e-commerce usando o Next.js com Server Components. O projeto terá funcionalidades básicas, como listagem de produtos, carrinho e busca. Vamos criar um modal para exibir os detalhes do produto quando o usuário clicar em um item. Além disso, vamos aprender sobre interceptação de rotas no Next.js. O foco principal será a busca e exibição de dados de uma API. Utilizaremos imagens de camisetas e moletons da Rocketseat. Vamos configurar o projeto, instalar dependências e configurar o ESLint. Em seguida, começaremos a criar as páginas do projeto. #################################################################################################### 02. Configurando Favicon: [Commit: Configurando Favicon](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/a9168bb93934c6e889d7dd20215910cf8446a53c) Nesta aula, exploramos as funcionalidades do app folder do Next.js, que permite o uso de server components. Aprendemos que o Next.js utiliza nomes de arquivos específicos dentro da pasta app para diferentes propósitos, como criação de páginas, layouts e loading. Também vimos como configurar o favicon e criar arquivos de metadata, como robots.txt, sitemap.xml, manifesto, OpenGraphImage e TwitterImage. Além disso, discutimos a possibilidade de gerar imagens dinâmicas usando código e a opção de usar arquivos de imagem estática para o favicon. #################################################################################################### 03. Criando layout da aplicação: [Commit: Criando layout da aplicação](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/1b8d3e58e11325420899ae2d6ff06e264acc2282) Nesta aula, vamos criar o layout base da nossa aplicação. Vamos começar entendendo que esse layout será aplicado em todas as páginas, mas pode ser que no futuro tenhamos páginas com estruturas diferentes. Para lidar com isso, podemos criar pastas dentro da pasta "app" para agrupar arquivos relacionados a um mesmo grupo de rotas. Por exemplo, podemos criar uma pasta chamada "store" para as páginas relacionadas à loja. Dentro dessa pasta, podemos criar um novo layout específico para a loja. Além disso, podemos criar componentes como o cabeçalho e o loading para serem utilizados nas páginas. #################################################################################################### 04. Componente - Header: [Commit: Componente: Header](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/87be840d7f98ab77dff6380e86b7769e1052c3b9) Nesta aula, aprendemos a estilizar o cabeçalho de uma aplicação utilizando Tailwind CSS. Começamos definindo as cores de fundo e texto do cabeçalho. Em seguida, criamos a estrutura do cabeçalho, dividindo-o em duas seções: uma para o logo e a busca, e outra para o carrinho e a conta do usuário. Utilizamos classes do Tailwind CSS para alinhar e espaçar os elementos corretamente. Também adicionamos ícones e estilizamos o formulário de busca. Por fim, finalizamos o cabeçalho adicionando uma barra separadora entre os links. #################################################################################################### 05. Página - Home: [Commit: Página: Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/6d383571fe8ca584edda5f93cfe1d6ab66bc4155) Nesta aula, vamos criar a estrutura visual da página inicial do nosso projeto. Começaremos exportando as imagens dos produtos e, em seguida, configuraremos a div que conterá os produtos. Usaremos um grid para organizar os elementos e aplicaremos estilos aos elementos internos com base no estado do elemento pai. Também adicionaremos os preços dos produtos e ajustaremos a posição deles. Por fim, faremos alguns ajustes no layout e adicionaremos as imagens dos produtos. #################################################################################################### 06. Route Handlers no Next.js: [Commit: Route Handlers no Next.js](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/4058f9351b797a85a459124f9016c9344eebe19b) Nesta aula, exploramos a funcionalidade de renderização de componentes pelo lado do servidor no Next.js. Isso significa que uma aplicação Next.js também é uma aplicação Node.js, o que nos permite criar rotas de API dentro do projeto. Essas rotas de API podem ser usadas para realizar diversas tarefas, como enviar e-mails, acessar bancos de dados e autenticação. No entanto, é importante ter em mente que essas rotas não são recomendadas para criar APIs completas, pois isso acopla o código do backend ao código do frontend. Em vez disso, elas são mais adequadas para funcionalidades específicas do frontend, como autenticação social. No exemplo dado, criamos uma rota de API que retorna uma lista de produtos destacados. Essa rota pode ser acessada através de `/api/products/featured`. #################################################################################################### 08. Criando Fetch API wrapper: [Commit: Criando Fetch API wrapper](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/9f1fe157693cfaef1eea4bccd6e51e239c1f041a) Nesta aula, aprendemos a criar uma requisição do front-end para a nossa API no Next.js. Como não temos um back-end separado, improvisamos um back-end dentro do próprio Next.js. Em vez de usar o Axios, utilizamos a Fetch API do navegador, que é estendida pelo Next.js para adicionar funcionalidades como caching. Criamos um arquivo api.ts para definir uma função que executa a Fetch API com base em uma URL de base e uma URL específica. Também configuramos variáveis de ambiente para armazenar a URL de base da API. Utilizamos o Zod para validar e transformar as variáveis de ambiente. Por fim, importamos as variáveis de ambiente e usamos a função api para carregar os dados na nossa rota. #################################################################################################### 09. Fetch de produtos na Home: [Commit: Fetch de produtos na Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/ded96fe24617f284b6524b46d640f3a067b77ac6) Nesta aula, aprendemos a carregar os dados dos produtos em destaque na página inicial do nosso projeto. Criamos uma função chamada `getFeaturedProducts` que faz uma requisição para a nossa API usando o `fetch`. Também fizemos algumas manipulações na URL da API para garantir que ela esteja correta. Em seguida, utilizamos o `response.json()` para obter os produtos e os retornamos. Na página inicial, chamamos essa função e exibimos os produtos em destaque. Também criamos um arquivo de tipos para fazer a tipagem dos produtos. Além disso, formatamos o preço para exibir em reais e removemos os centavos. Por fim, utilizamos o `map` para exibir os outros produtos em links. #################################################################################################### 10. Cache & Memoization: [Commit: Cache & Memoization](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/096466350c310254e0e3849a4b35fd925fdc676c) A Memoização é uma funcionalidade do React que evita requisições duplicadas durante o carregamento de uma página. Quando usamos Server Components, o React automaticamente impede que uma requisição seja feita mais de uma vez. No entanto, a Memoização não se aplica a requisições feitas em páginas diferentes. Para evitar requisições duplicadas em páginas diferentes, é necessário utilizar o Cache. O Next.js possui propriedades para controle de Cache, como a opção `force-cache`, que permite cachear uma requisição, e a opção `no-store`, que impede o cache. Além disso, há a opção `revalidate`, que define um tempo em segundos para atualizar o cache da requisição. #################################################################################################### 11. Loading na Home: [Commit: Loading na Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/44f795a7839ad6d969d628e1c587f9c7a9d023e6) Nesta aula, aprendemos a criar uma página de carregamento (loading) para a nossa aplicação. Isso é importante porque, quando fazemos chamadas assíncronas, como uma requisição HTTP, a página pode demorar para carregar e isso pode causar uma experiência ruim para o usuário. Para simular esse atraso, adicionamos um delay nas chamadas HTTP da nossa aplicação. Em seguida, criamos um componente chamado `skeleton` que servirá como base para todas as páginas que precisarem de um sinal de carregamento. Esse componente é uma `div` com uma animação em cinza claro e pode ter sua largura e altura configuradas de acordo com onde for utilizado. Utilizamos o `tailwind-merge` para unir as classes estáticas do componente com as classes recebidas por meio das props, evitando que as classes sejam substituídas. Agora, podemos continuar a implementação da página de carregamento na nossa Home. #################################################################################################### 12. Página - Detalhe do produto: [Commit: Página: Detalhe do produto](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/c96fb82958c0d939b3f6fd8ceca6b33a0885c835) Nesta aula, vamos criar a página de um produto em um site de comércio eletrônico. Vamos começar criando uma nova pasta chamada `product` dentro da pasta `app/store`. Dentro dessa pasta, vamos criar um arquivo chamado `page.tsx` e exportar um componente chamado `Product`. Em seguida, vamos estruturar a página, adicionando uma `div` com uma classe `relative grid` e definindo uma altura máxima de 860 pixels. Vamos adicionar a descrição e o preço do produto, estilizando-os adequadamente. Em seguida, vamos adicionar uma tabela de tamanhos e um botão para adicionar o produto ao carrinho. Por fim, vamos dividir a página em três colunas, com a imagem ocupando duas colunas e os detalhes do produto ocupando uma coluna. Vamos adicionar a imagem usando o componente `next/image` e estilizar as informações do produto. #################################################################################################### 13. Fetch de dados no Produto: [Commit: Fetch de dados no Produto](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/d07d4207397f594e7b8077a2dd258e210565c0a8) Nesta aula, aprendemos a criar uma rota na API para buscar detalhes de um único produto com base no slug. Utilizamos a estrutura de colchetes no Next.js para receber o parâmetro slug na URL. Em seguida, criamos um handler para essa rota, onde recebemos o parâmetro `slug` e validamos se é uma `string`. Em seguida, buscamos o produto com base no slug e retornamos o produto encontrado ou uma mensagem de erro caso o produto não exista. Na página de produto, utilizamos essa rota para buscar e exibir as informações do produto com base no slug. #################################################################################################### 14. Page Metadata no Next.js (SEO): [Commit: Page Metadata no Next.js (SEO)](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/0ef1d3582c9c6630c9bb684428cbe2a42e9b382e) Nesta aula, aprendemos sobre a geração de metadados dinâmicos no Next.js. Vimos como usar a função `generateMetadata` para retornar parâmetros específicos para cada página, como o título do produto. Também exploramos a memoização, que evita chamadas HTTP duplicadas ao identificar que a mesma chamada está sendo feita em diferentes ambientes dentro da mesma página. Além disso, discutimos a importância dos metadados para compor as tags no cabeçalho do HTML, como o título, descrição e outros elementos. Aprendemos a substituir e personalizar os metadados para cada página, usando templates e opções de fallback. #################################################################################################### 15. Geração estática na build: [Commit: Geração estática na build](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/5c8f0b87da98626a01e222ddda6fdd324a0372ef) Nesta aula, vamos falar sobre geração estática no Next.js. A geração estática permite criar uma versão em cache das páginas da aplicação antes de serem publicadas. Isso significa que quando um usuário acessar uma página, ela será exibida de forma instantânea, sem a necessidade de fazer requisições adicionais. Para utilizar a geração estática, podemos exportar uma função chamada `generateStaticParams` dentro de uma página que recebe parâmetros dinâmicos. Essa função deve retornar um array de objetos, onde cada objeto representa um parâmetro que desejamos gerar de forma estática. É importante ressaltar que a geração estática deve ser utilizada com cuidado, pois pode aumentar o tempo de build do projeto. Recomenda-se utilizar a geração estática apenas para páginas que são realmente importantes e que precisam ser carregadas de forma rápida. #################################################################################################### 16. Contexto do carrinho: [Commit: Contexto do carrinho](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/9f0db3d979722caed84136beb468ad0ec4914327) Nesta aula, vamos começar a implementar a funcionalidade do carrinho em nossa aplicação. Para isso, vamos utilizar o contexto do React. Vamos criar um contexto chamado `CartContext` e um provedor chamado `CartProvider`. Dentro do contexto, teremos informações sobre os itens do carrinho e uma função `addToCart` para adicionar itens ao carrinho. Vamos utilizar o hook `useCart` para acessar o contexto em outros componentes. Por fim, vamos envolver nossa aplicação com o `CartProvider` para que todos os componentes tenham acesso ao contexto do carrinho. #################################################################################################### 17. Gerando OpenGraph Image: [Commit: Gerando OpenGraph Image](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/1ef56c4434f2e8de89c26aa20e6bafc3fce7398b) Nesta aula, aprendemos como gerar metadados dinâmicos para cada página de um projeto Next.js. Focamos especialmente na geração de imagens de compartilhamento personalizadas para cada produto. Utilizamos os arquivos OpenGraph Image para criar as imagens dinâmicas. Através do Next.js, podemos converter HTML em imagem utilizando o `ImageResponse`. Também exploramos a possibilidade de carregar fontes personalizadas e passar configurações adicionais para a geração da imagem. Ao final da aula, vimos como acessar os parâmetros dinâmicos da URL para gerar imagens diferentes para cada produto. #################################################################################################### 18. Adicionando ao carrinho: [Commit: Adicionando ao carrinho](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/24f00bf437a3586c4104d74a5fad6b51b264438b) Nesta aula, aprendemos a utilizar o contexto no Next.js para criar componentes cliente e servidor. Começamos adicionando o contexto do carrinho no `StoreLayout`. Em seguida, criamos um novo componente chamado `AddToCartButton` para encapsular a lógica de adicionar produtos ao carrinho. Também aprendemos a isolar ao máximo os componentes, transformando apenas o necessário em componentes cliente. Por fim, implementamos a funcionalidade de adicionar produtos ao carrinho na página de produto. #################################################################################################### 19. API - Busca de produtos: [Commit: API: Busca de produtos](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/5abca4d16b5e9658e906082d8a26b687e8939da5) Nesta aula, vamos começar a trabalhar na funcionalidade de busca da nossa aplicação. Primeiro, vamos criar uma rota chamada `search` na nossa API. Essa rota será responsável por receber a busca do usuário e retornar os produtos correspondentes. Em seguida, vamos construir a página de busca no frontend. Vamos receber o parâmetro de busca na URL e utilizá-lo para filtrar os produtos. Faremos uma busca case-insensitive, ou seja, não iremos diferenciar maiúsculas de minúsculas. Por fim, vamos verificar se o título do produto inclui a busca do usuário. #################################################################################################### 20. Página - Busca de produtos: [Commit: Página: Busca de produtos](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/4e0c947a74e3622dce643295941de12c63c3446e) Nesta aula, vamos criar a página de busca em nossa aplicação. Atualmente, quando o usuário digita algo na barra de busca, nada acontece. Vamos começar adicionando uma `div` que envolve todo o conteúdo da página. Dentro dessa `div`, teremos um parágrafo que exibirá os resultados da busca, com o termo de busca substituído. Em seguida, teremos outra `div` onde serão exibidos os resultados dos produtos da busca. Vamos utilizar um grid simples para organizar esses resultados. #################################################################################################### 21. Formulário de busca: [Commit: Formulário de busca](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/413a069326838adc87d9e82cc14c620603a28af4) Nesta aula, vamos aprender a redirecionar o usuário quando ele preencher a busca e pressionar Enter. Usaremos o `object.fromEntries` para transformar os dados do formulário em um objeto e acessar a `query` de busca. Se o campo de busca estiver vazio, não faremos nada. Caso contrário, usaremos o `router.push` para redirecionar o usuário para a página de busca. Também aprenderemos a manter o estado do campo de busca mesmo após atualizar a página, usando o `useSearchParams` para obter os parâmetros de busca da URL. Por fim, discutiremos a diferença entre `hard navigation` e `soft navigation` e como usar o `useRouter` para realizar a `soft navigation`. #################################################################################################### 22. Buscando produtos da API: [Commit: Buscando produtos da API](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/891a35cf4c566ae8441212b8eda2194da1829321) Nesta aula, aprendemos a criar uma página de busca no Next.js. Começamos implementando a funcionalidade de redirecionamento do usuário para a página inicial caso ele tente acessar a página de busca sem um parâmetro de busca. Em seguida, utilizamos a API para buscar os produtos com base na query de busca fornecida pelo usuário. Implementamos a função `searchProducts` que recebe a query como parâmetro e retorna uma lista de produtos correspondentes. Por fim, utilizamos o método `map` para exibir os produtos na página de busca. Também exploramos duas formas de acessar o parâmetro de busca na URL: utilizando o `useSearchParams` em um componente cliente ou acessando o `searchParams` diretamente nas props do componente. #################################################################################################### 23. Loading da busca: [Commit: Loading da busca](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/abfc6daf77dc41d78dc1faad542767d5fd5b4682) Nesta aula, aprendemos a melhorar a página de carregamento em uma busca. Ajustamos o tempo de carregamento e o tamanho dos elementos para melhorar a experiência do usuário. Criamos uma página de carregamento mais adequada, utilizando uma estrutura semelhante à página de busca. No entanto, não conseguimos acessar os parâmetros de busca dentro da página de loading, então transformamos o componente em um componente cliente para poder utilizar o `useSearchParams`. Por fim, adicionamos um esqueleto de carregamento com altura definida. #################################################################################################### 01. Criando estrutura do app: [Commit: Criando estrutura do app](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/2fdf95b4f7f166a6b5b55deb916eeef59ffd3d0f) [Figma devstore](https://www.figma.com/community/file/1299037596397442545/devstore-projeto-react) Nesta aula, vamos desenvolver um projeto de e-commerce usando o Next.js com Server Components. O projeto terá funcionalidades básicas, como listagem de produtos, carrinho e busca. Vamos criar um modal para exibir os detalhes do produto quando o usuário clicar em um item. Além disso, vamos aprender sobre interceptação de rotas no Next.js. O foco principal será a busca e exibição de dados de uma API. Utilizaremos imagens de camisetas e moletons da Rocketseat. Vamos configurar o projeto, instalar dependências e configurar o ESLint. Em seguida, começaremos a criar as páginas do projeto. #################################################################################################### 02. Configurando Favicon: [Commit: Configurando Favicon](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/a9168bb93934c6e889d7dd20215910cf8446a53c) Nesta aula, exploramos as funcionalidades do app folder do Next.js, que permite o uso de server components. Aprendemos que o Next.js utiliza nomes de arquivos específicos dentro da pasta app para diferentes propósitos, como criação de páginas, layouts e loading. Também vimos como configurar o favicon e criar arquivos de metadata, como robots.txt, sitemap.xml, manifesto, OpenGraphImage e TwitterImage. Além disso, discutimos a possibilidade de gerar imagens dinâmicas usando código e a opção de usar arquivos de imagem estática para o favicon. #################################################################################################### 03. Criando layout da aplicação: [Commit: Criando layout da aplicação](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/1b8d3e58e11325420899ae2d6ff06e264acc2282) Nesta aula, vamos criar o layout base da nossa aplicação. Vamos começar entendendo que esse layout será aplicado em todas as páginas, mas pode ser que no futuro tenhamos páginas com estruturas diferentes. Para lidar com isso, podemos criar pastas dentro da pasta "app" para agrupar arquivos relacionados a um mesmo grupo de rotas. Por exemplo, podemos criar uma pasta chamada "store" para as páginas relacionadas à loja. Dentro dessa pasta, podemos criar um novo layout específico para a loja. Além disso, podemos criar componentes como o cabeçalho e o loading para serem utilizados nas páginas. #################################################################################################### 04. Componente - Header: [Commit: Componente: Header](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/87be840d7f98ab77dff6380e86b7769e1052c3b9) Nesta aula, aprendemos a estilizar o cabeçalho de uma aplicação utilizando Tailwind CSS. Começamos definindo as cores de fundo e texto do cabeçalho. Em seguida, criamos a estrutura do cabeçalho, dividindo-o em duas seções: uma para o logo e a busca, e outra para o carrinho e a conta do usuário. Utilizamos classes do Tailwind CSS para alinhar e espaçar os elementos corretamente. Também adicionamos ícones e estilizamos o formulário de busca. Por fim, finalizamos o cabeçalho adicionando uma barra separadora entre os links. #################################################################################################### 05. Página - Home: [Commit: Página: Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/6d383571fe8ca584edda5f93cfe1d6ab66bc4155) Nesta aula, vamos criar a estrutura visual da página inicial do nosso projeto. Começaremos exportando as imagens dos produtos e, em seguida, configuraremos a div que conterá os produtos. Usaremos um grid para organizar os elementos e aplicaremos estilos aos elementos internos com base no estado do elemento pai. Também adicionaremos os preços dos produtos e ajustaremos a posição deles. Por fim, faremos alguns ajustes no layout e adicionaremos as imagens dos produtos. #################################################################################################### 06. Route Handlers no Next.js: [Commit: Route Handlers no Next.js](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/4058f9351b797a85a459124f9016c9344eebe19b) Nesta aula, exploramos a funcionalidade de renderização de componentes pelo lado do servidor no Next.js. Isso significa que uma aplicação Next.js também é uma aplicação Node.js, o que nos permite criar rotas de API dentro do projeto. Essas rotas de API podem ser usadas para realizar diversas tarefas, como enviar e-mails, acessar bancos de dados e autenticação. No entanto, é importante ter em mente que essas rotas não são recomendadas para criar APIs completas, pois isso acopla o código do backend ao código do frontend. Em vez disso, elas são mais adequadas para funcionalidades específicas do frontend, como autenticação social. No exemplo dado, criamos uma rota de API que retorna uma lista de produtos destacados. Essa rota pode ser acessada através de `/api/products/featured`. #################################################################################################### 08. Criando Fetch API wrapper: [Commit: Criando Fetch API wrapper](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/9f1fe157693cfaef1eea4bccd6e51e239c1f041a) Nesta aula, aprendemos a criar uma requisição do front-end para a nossa API no Next.js. Como não temos um back-end separado, improvisamos um back-end dentro do próprio Next.js. Em vez de usar o Axios, utilizamos a Fetch API do navegador, que é estendida pelo Next.js para adicionar funcionalidades como caching. Criamos um arquivo api.ts para definir uma função que executa a Fetch API com base em uma URL de base e uma URL específica. Também configuramos variáveis de ambiente para armazenar a URL de base da API. Utilizamos o Zod para validar e transformar as variáveis de ambiente. Por fim, importamos as variáveis de ambiente e usamos a função api para carregar os dados na nossa rota. #################################################################################################### 09. Fetch de produtos na Home: [Commit: Fetch de produtos na Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/ded96fe24617f284b6524b46d640f3a067b77ac6) Nesta aula, aprendemos a carregar os dados dos produtos em destaque na página inicial do nosso projeto. Criamos uma função chamada `getFeaturedProducts` que faz uma requisição para a nossa API usando o `fetch`. Também fizemos algumas manipulações na URL da API para garantir que ela esteja correta. Em seguida, utilizamos o `response.json()` para obter os produtos e os retornamos. Na página inicial, chamamos essa função e exibimos os produtos em destaque. Também criamos um arquivo de tipos para fazer a tipagem dos produtos. Além disso, formatamos o preço para exibir em reais e removemos os centavos. Por fim, utilizamos o `map` para exibir os outros produtos em links. #################################################################################################### 10. Cache & Memoization: [Commit: Cache & Memoization](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/096466350c310254e0e3849a4b35fd925fdc676c) A Memoização é uma funcionalidade do React que evita requisições duplicadas durante o carregamento de uma página. Quando usamos Server Components, o React automaticamente impede que uma requisição seja feita mais de uma vez. No entanto, a Memoização não se aplica a requisições feitas em páginas diferentes. Para evitar requisições duplicadas em páginas diferentes, é necessário utilizar o Cache. O Next.js possui propriedades para controle de Cache, como a opção `force-cache`, que permite cachear uma requisição, e a opção `no-store`, que impede o cache. Além disso, há a opção `revalidate`, que define um tempo em segundos para atualizar o cache da requisição. #################################################################################################### 11. Loading na Home: [Commit: Loading na Home](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/44f795a7839ad6d969d628e1c587f9c7a9d023e6) Nesta aula, aprendemos a criar uma página de carregamento (loading) para a nossa aplicação. Isso é importante porque, quando fazemos chamadas assíncronas, como uma requisição HTTP, a página pode demorar para carregar e isso pode causar uma experiência ruim para o usuário. Para simular esse atraso, adicionamos um delay nas chamadas HTTP da nossa aplicação. Em seguida, criamos um componente chamado `skeleton` que servirá como base para todas as páginas que precisarem de um sinal de carregamento. Esse componente é uma `div` com uma animação em cinza claro e pode ter sua largura e altura configuradas de acordo com onde for utilizado. Utilizamos o `tailwind-merge` para unir as classes estáticas do componente com as classes recebidas por meio das props, evitando que as classes sejam substituídas. Agora, podemos continuar a implementação da página de carregamento na nossa Home. #################################################################################################### 12. Página - Detalhe do produto: [Commit: Página: Detalhe do produto](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/c96fb82958c0d939b3f6fd8ceca6b33a0885c835) Nesta aula, vamos criar a página de um produto em um site de comércio eletrônico. Vamos começar criando uma nova pasta chamada `product` dentro da pasta `app/store`. Dentro dessa pasta, vamos criar um arquivo chamado `page.tsx` e exportar um componente chamado `Product`. Em seguida, vamos estruturar a página, adicionando uma `div` com uma classe `relative grid` e definindo uma altura máxima de 860 pixels. Vamos adicionar a descrição e o preço do produto, estilizando-os adequadamente. Em seguida, vamos adicionar uma tabela de tamanhos e um botão para adicionar o produto ao carrinho. Por fim, vamos dividir a página em três colunas, com a imagem ocupando duas colunas e os detalhes do produto ocupando uma coluna. Vamos adicionar a imagem usando o componente `next/image` e estilizar as informações do produto. #################################################################################################### 13. Fetch de dados no Produto: [Commit: Fetch de dados no Produto](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/d07d4207397f594e7b8077a2dd258e210565c0a8) Nesta aula, aprendemos a criar uma rota na API para buscar detalhes de um único produto com base no slug. Utilizamos a estrutura de colchetes no Next.js para receber o parâmetro slug na URL. Em seguida, criamos um handler para essa rota, onde recebemos o parâmetro `slug` e validamos se é uma `string`. Em seguida, buscamos o produto com base no slug e retornamos o produto encontrado ou uma mensagem de erro caso o produto não exista. Na página de produto, utilizamos essa rota para buscar e exibir as informações do produto com base no slug. #################################################################################################### 14. Page Metadata no Next.js (SEO): [Commit: Page Metadata no Next.js (SEO)](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/0ef1d3582c9c6630c9bb684428cbe2a42e9b382e) Nesta aula, aprendemos sobre a geração de metadados dinâmicos no Next.js. Vimos como usar a função `generateMetadata` para retornar parâmetros específicos para cada página, como o título do produto. Também exploramos a memoização, que evita chamadas HTTP duplicadas ao identificar que a mesma chamada está sendo feita em diferentes ambientes dentro da mesma página. Além disso, discutimos a importância dos metadados para compor as tags no cabeçalho do HTML, como o título, descrição e outros elementos. Aprendemos a substituir e personalizar os metadados para cada página, usando templates e opções de fallback. #################################################################################################### 15. Geração estática na build: [Commit: Geração estática na build](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/5c8f0b87da98626a01e222ddda6fdd324a0372ef) Nesta aula, vamos falar sobre geração estática no Next.js. A geração estática permite criar uma versão em cache das páginas da aplicação antes de serem publicadas. Isso significa que quando um usuário acessar uma página, ela será exibida de forma instantânea, sem a necessidade de fazer requisições adicionais. Para utilizar a geração estática, podemos exportar uma função chamada `generateStaticParams` dentro de uma página que recebe parâmetros dinâmicos. Essa função deve retornar um array de objetos, onde cada objeto representa um parâmetro que desejamos gerar de forma estática. É importante ressaltar que a geração estática deve ser utilizada com cuidado, pois pode aumentar o tempo de build do projeto. Recomenda-se utilizar a geração estática apenas para páginas que são realmente importantes e que precisam ser carregadas de forma rápida. #################################################################################################### 16. Contexto do carrinho: [Commit: Contexto do carrinho](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/9f0db3d979722caed84136beb468ad0ec4914327) Nesta aula, vamos começar a implementar a funcionalidade do carrinho em nossa aplicação. Para isso, vamos utilizar o contexto do React. Vamos criar um contexto chamado `CartContext` e um provedor chamado `CartProvider`. Dentro do contexto, teremos informações sobre os itens do carrinho e uma função `addToCart` para adicionar itens ao carrinho. Vamos utilizar o hook `useCart` para acessar o contexto em outros componentes. Por fim, vamos envolver nossa aplicação com o `CartProvider` para que todos os componentes tenham acesso ao contexto do carrinho. #################################################################################################### 17. Gerando OpenGraph Image: [Commit: Gerando OpenGraph Image](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/1ef56c4434f2e8de89c26aa20e6bafc3fce7398b) Nesta aula, aprendemos como gerar metadados dinâmicos para cada página de um projeto Next.js. Focamos especialmente na geração de imagens de compartilhamento personalizadas para cada produto. Utilizamos os arquivos OpenGraph Image para criar as imagens dinâmicas. Através do Next.js, podemos converter HTML em imagem utilizando o `ImageResponse`. Também exploramos a possibilidade de carregar fontes personalizadas e passar configurações adicionais para a geração da imagem. Ao final da aula, vimos como acessar os parâmetros dinâmicos da URL para gerar imagens diferentes para cada produto. #################################################################################################### 18. Adicionando ao carrinho: [Commit: Adicionando ao carrinho](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/24f00bf437a3586c4104d74a5fad6b51b264438b) Nesta aula, aprendemos a utilizar o contexto no Next.js para criar componentes cliente e servidor. Começamos adicionando o contexto do carrinho no `StoreLayout`. Em seguida, criamos um novo componente chamado `AddToCartButton` para encapsular a lógica de adicionar produtos ao carrinho. Também aprendemos a isolar ao máximo os componentes, transformando apenas o necessário em componentes cliente. Por fim, implementamos a funcionalidade de adicionar produtos ao carrinho na página de produto. #################################################################################################### 19. API - Busca de produtos: [Commit: API: Busca de produtos](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/5abca4d16b5e9658e906082d8a26b687e8939da5) Nesta aula, vamos começar a trabalhar na funcionalidade de busca da nossa aplicação. Primeiro, vamos criar uma rota chamada `search` na nossa API. Essa rota será responsável por receber a busca do usuário e retornar os produtos correspondentes. Em seguida, vamos construir a página de busca no frontend. Vamos receber o parâmetro de busca na URL e utilizá-lo para filtrar os produtos. Faremos uma busca case-insensitive, ou seja, não iremos diferenciar maiúsculas de minúsculas. Por fim, vamos verificar se o título do produto inclui a busca do usuário. #################################################################################################### 20. Página - Busca de produtos: [Commit: Página: Busca de produtos](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/4e0c947a74e3622dce643295941de12c63c3446e) Nesta aula, vamos criar a página de busca em nossa aplicação. Atualmente, quando o usuário digita algo na barra de busca, nada acontece. Vamos começar adicionando uma `div` que envolve todo o conteúdo da página. Dentro dessa `div`, teremos um parágrafo que exibirá os resultados da busca, com o termo de busca substituído. Em seguida, teremos outra `div` onde serão exibidos os resultados dos produtos da busca. Vamos utilizar um grid simples para organizar esses resultados. #################################################################################################### 21. Formulário de busca: [Commit: Formulário de busca](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/413a069326838adc87d9e82cc14c620603a28af4) Nesta aula, vamos aprender a redirecionar o usuário quando ele preencher a busca e pressionar Enter. Usaremos o `object.fromEntries` para transformar os dados do formulário em um objeto e acessar a `query` de busca. Se o campo de busca estiver vazio, não faremos nada. Caso contrário, usaremos o `router.push` para redirecionar o usuário para a página de busca. Também aprenderemos a manter o estado do campo de busca mesmo após atualizar a página, usando o `useSearchParams` para obter os parâmetros de busca da URL. Por fim, discutiremos a diferença entre `hard navigation` e `soft navigation` e como usar o `useRouter` para realizar a `soft navigation`. #################################################################################################### 22. Buscando produtos da API: [Commit: Buscando produtos da API](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/891a35cf4c566ae8441212b8eda2194da1829321) Nesta aula, aprendemos a criar uma página de busca no Next.js. Começamos implementando a funcionalidade de redirecionamento do usuário para a página inicial caso ele tente acessar a página de busca sem um parâmetro de busca. Em seguida, utilizamos a API para buscar os produtos com base na query de busca fornecida pelo usuário. Implementamos a função `searchProducts` que recebe a query como parâmetro e retorna uma lista de produtos correspondentes. Por fim, utilizamos o método `map` para exibir os produtos na página de busca. Também exploramos duas formas de acessar o parâmetro de busca na URL: utilizando o `useSearchParams` em um componente cliente ou acessando o `searchParams` diretamente nas props do componente. #################################################################################################### 23. Loading da busca: [Commit: Loading da busca](https://github.com/rocketseat-education/ignite-reactjs-next-app-router-tests-devstore/commit/abfc6daf77dc41d78dc1faad542767d5fd5b4682) Nesta aula, aprendemos a melhorar a página de carregamento em uma busca. Ajustamos o tempo de carregamento e o tamanho dos elementos para melhorar a experiência do usuário. Criamos uma página de carregamento mais adequada, utilizando uma estrutura semelhante à página de busca. No entanto, não conseguimos acessar os parâmetros de busca dentro da página de loading, então transformamos o componente em um componente cliente para poder utilizar o `useSearchParams`. Por fim, adicionamos um esqueleto de carregamento com altura definida.