jemluz / ignite-shop

An intermediate project to deepen knowledge in NextJS and scalability (by @rocketseat)
https://jemluz-ignite-shop.vercel.app/
1 stars 0 forks source link

Produto & checkout (Next avançado) #4

Open jemluz opened 9 months ago

jemluz commented 9 months ago

Navegação via Link

Utilizar o no react permite que o carregamento / (""redirecionamento"") seja isolado ao componente de link. Isso vai fazer com que a página não carregue todos os recursos globais novamente ao abrir a página de produto. Só irá carregar o essencial otimizando performance.

É uma herança do SPA que o Next tira proveito justamente por ser um framework feito em cima do react. image

jemluz commented 9 months ago

Carregando dados de produto

Utilizamos o params no getSP( ) para capturar os dados (parâmetros de rota) que vem do link de produto. É como utilizar const { query } = useRouter( ) dentro do componente.

Mas o params não vem tipado, então ele vai dar esse erro de tipagem. image

Isso por que o método retrieve do stripe que estamos chamando espera obrigatoriamente uma string. image

E por não estar com tipagem ambígua ( string | string[ ] ) ele não será aceito. image

Para corrigir isso podemos forçar a tipagem utilizando a função String( ) image

Ou aproveitar a um conceito muito importante que é declarando os generics do GetStaticProps image

O primeiro parâmetro do generics é qual é o tipo do retorno que será entregue pelo return da função. O segundo parâmetro é qual o tipo do objeto params que ele espera receber. E é isso que vamos usar, declarando que o id recebido é do tipo string.

image Pronto, fim do erro.

jemluz commented 9 months ago

SSG com parâmetro dinâmico

Quando usamos getSSP, se 1 milhão de pessoas acessarem a página, o código do server side irá executar 1 milhão de vezes.

Quando usamos getSP, o código só irá rodar em 2 situações:

Porém, na situação da build, se estivermos trabalhando com parâmetros dinâmicos (como o id do produto por exemplo), como o next irá puxar esses dados?

De onde ele vai puxar? É uma build! Não tem de onde puxar.

Para esses casos, precisamos retornar uma outra const chamada getStaticPaths, que é um método que vai devolver esses IDs reais. Com isso, no momento da build será gerada uma versão estática da página de produto.

jemluz commented 9 months ago

Fallback do SSG

Mas e se você tiver infinitos/muitos produtos?

Devemos manter o getStaticPaths enxuto ao máximo.

Caso 1 -> Colocar uma seleção dos produtos mais vendidos no get...Paths (no caso do stripe não temos essa opção). Isso vai otimizar a experiência do usuário justamente nas páginas que nós já sabemos que recebem mais requisição. Caso 2 -> Demais produtos (que não recebem tantas requisições) podemos usar a opção fallback do get..Paths.

Como o fallback funciona

No modo true, a página terá os componentes carregados enquanto a função getStaticPaths roda assincronamente, quando ela terminar, o next irá preencher os componentes com os dados que vieram da requisição.

Por isso nesses podemos usar a renderização de esqueletos, que já marca os espaços em tela, mais ainda não exibe nenhum conteudo. image

Também podemos obter uma propriedade isFallback para detectar o estado de loading dessa requisição. image

jemluz commented 9 months ago

Prefetch de links

Toda vez que utilizamos um do next, esse componente já vem com o comportamento de prefetch. Ao passar o mouse em cima do link ele já faz uma requisição prévia, antes mesmo de clicar.

prefetch

Mas se seu site tiver muitos links, você deve cuidar para não ficar lento. Podemos configurar manualmente esse comportamento. Para isso utilizamos o atributo prefetch e setamos ele como false (que por padrão sempre é true)

jemluz commented 9 months ago

API Routes no NextJS

O next tem suporte para rotas de API. Você pode utilizar em um desses casos:

Como utilizar

É necessário uma pasta chamada /api dentro da pasta /pages e todo arquivo que for criado dentro dela irá corresponder a uma rota (igual ao nome do arquivo)

image

image

image

jemluz commented 9 months ago

Requisições com axios

O Axios é a forma mais recomendada de fazer requisições, principalmente para api externas (quando comparado ao fetch).

Redirecionamento para rota externa

// checkoutUrl nesse caso é a rota alvo
// ...dentro da request
window.location.href = checkoutUrl

Redirecionamento para rota interna (do /src)

const router = useRouter();

// ...dentro da request
router.push('/rota-desejada')

Tipos de métodos REST nas rotas /src/api

O next não faz distinção de métodos GET POST PUT e DELETE para as rotas dentro de /src/api. Por isso se atente a limitar o acesso desses métodos caso ache necessário com req.method.

Loading de redirecionamento

O estado de loading não precisa ser desativado dentro do try pois esse em questão redireciona para uma página. Foda-se se você desativou.

Por isso só é desativado dentro do catch.

image

jemluz commented 9 months ago

Dados da compra no sucesso

O stripe automaticamente preenche o id da compra se você utilizar session_id={CHECKOUT_SESSION_ID}

Revisão rápida

A pagina de success deve realizar a request de qual forma?

jemluz commented 9 months ago

Redirect no SSR

Você pode fazer redirecionamento usando o getSSP (nesse caso quando criamos um tratamento para quando não houver session id)

export const getServerSideProps: GetServerSideProps = async ({ query }) => {
  if (!query.session_id) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      }
    }
  }
//...
}
jemluz commented 9 months ago

SEO no Next

Você pode usar a tag <Head> para trabalhar com SEO

export default function Success({ costumerName, product }: SuccessProps) {
  return (
    <>
      <Head>
        <title>Compra efetuada | Ignite Shop</title>
        <meta name="robots" content="noindex" />
      </Head>

      <SucessContainer>
        <h1>Compra efetuada</h1>

        <ImageContainer>
          <Image src={product.imageUrl} width={120} height={110} alt="" />
        </ImageContainer>

        <p>Uhuul <strong>{costumerName}</strong>, sua <strong>{product.name}</strong> já está a caminho da sua casa.</p>

        <Link href="/">
          Voltar ao catálogo
        </Link>
      </SucessContainer>
    </>
  )
}