Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Produto & checkout (Next avançado) #4

Open
jemluz opened this issue Jan 19, 2024 · 9 comments
Open

Produto & checkout (Next avançado) #4

jemluz opened this issue Jan 19, 2024 · 9 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@jemluz
Copy link
Owner

jemluz commented Jan 19, 2024

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 jemluz added the documentation Improvements or additions to documentation label Jan 19, 2024
@jemluz jemluz self-assigned this Jan 19, 2024
jemluz added a commit that referenced this issue Jan 19, 2024
jemluz added a commit that referenced this issue Jan 19, 2024
@jemluz
Copy link
Owner Author

jemluz commented Jan 20, 2024

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 added a commit that referenced this issue Jan 20, 2024
@jemluz
Copy link
Owner Author

jemluz commented Jan 30, 2024

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:

  • Na build
  • E de acordo com o revalidate (se houver)

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
Copy link
Owner Author

jemluz commented Jan 30, 2024

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

  • false : só vai retornar um 404
  • true : vai pegar o ID da url e replicar o loading, como se estivessemos colocado manualmente o ID no get...Paths
  • 'blocking' : não carrega nada em tela, dps que a request carregar ele libera a página. (não recomendado na maioria dos casos por não dar feedback ao usuário)

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
Copy link
Owner Author

jemluz commented Jan 30, 2024

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
Copy link
Owner Author

jemluz commented Jan 30, 2024

API Routes no NextJS

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

  • Quando não há um beckend/API externo
  • Quando a rota é algo exclusivo/específico do client web (que se ficasse no backend atrapalharia requisições de outros clients que tbm consomem o back)

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
Copy link
Owner Author

jemluz commented Feb 5, 2024

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 added a commit that referenced this issue Feb 5, 2024
- npm i axios
- see notes at #4
@jemluz
Copy link
Owner Author

jemluz commented Feb 6, 2024

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?

  • Client Side (useEffect + axios) = não é seguro pois iria expor a SECRET_KEY
  • Server Side (SSP) = é quem sobra hehe, vamos manter a chamada no back para proteger as variáveis sensíveis e ao mesmo tempo sem comprometer as informações dinâmicas da página
  • Server Side (SP) = não faz muito sentido uma página de sucesso ser estática, pois não é uma página muito visitada pelos usuários e não possuí essa demanda por mais performance, além de ter dados dinânimos

@jemluz
Copy link
Owner Author

jemluz commented Feb 7, 2024

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
Copy link
Owner Author

jemluz commented Feb 7, 2024

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>
    </>
  )
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant