Roadmap
Avançado

Ecommerce em 2024

O jeito mais moderno de criar um ecommerce

tailwind
vercel
github
medusajs
render
nuxt

Antes de começar vamos criar alguns componentes antes para nosso código ficar mais organizado.

Criando o componente de card de produto

Dentro da pasta components crie um arquivo ProductCard.vue e cole o seguinte código:

ProductCard.vue
<script setup lang="ts">
defineProps<{
  image: string;
  title: string;
  price: number;
  handle: string;
  variantId: string;
}>()
</script>

<template>
  <nuxt-link :to="{path: `/produtos/${handle}`, query: {variant: variantId}}" class="cursor-pointer group">
    <div class="w-full h-auto aspect-[16/12] overflow-hidden rounded-lg">
      <img :src="image" :alt="title" class="w-full h-full object-center object-cover group-hover:scale-105 transition">
    </div>
    <div class="py-4 px-4">
      <h3 class="mb-1">
        {{ title }}
      </h3>
      <div class="font-bold">
        {{ new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(price) }}
      </div>
    </div>
  </nuxt-link>
</template>
Clique aqui para expandir

Uma coisa interessante desse componente de produto que criamos é que, o link que o usuário vai ser redirecionado ao clicar no card, contém duas propriedades: uma chamada handle que é a URL do produto (exemplo: se o nome do produto é Camisa Florida, a url vai ser camisa-florida para ajudar no SEO) e outra propriedade chamada variant que vai pré selecionar a variante do produto ao carregar a página.

Essa variant define as opções do produto, ou seja, se o produto tem "Tamanho" e "Cor", a variante vai selecionar um tamanho e cor automaticamente quando o usuário clicar no card.

Criando a página inicial da loja

Dentro do projeto medusa-storefront crie uma pasta chamada pages, dentro dessa pasta crie um arquivo index.vue e cole o seguinte código:

index.vue
<script setup lang="ts">
const client = useMedusaClient();
const { products } = await client.products.list();
</script>

<template>
  <section class="h-screen relative mb-20">
    <div class="items-center container relative h-full grid grid-cols-2">
      <div class="py-20 flex-1 pr-10">
        <h1 class="text-6xl font-extrabold text-zinc-900 mb-4">
          Bota na cabeça que estilo não é marra
        </h1>
        <p class="flex-1 text-zinc-600 text-base mb-10">
          Usando a nova coleção da Umbrella você fica pronto para qualquer tempestade.
        </p>
        <nuxt-link to="/colecoes">
          <Button size="lg">
            Nova Coleção
          </Button>
        </nuxt-link>
      </div>
    </div>
    <div class="absolute w-full h-full top-0 left-0 grid grid-cols-2 pointer-events-none">
      <div class="col-start-2 w-full h-full overflow-hidden">
        <img src="/hero.png" class="w-full h-full object-center object-cover" />
      </div>
    </div>
  </section>
  <section class="container my-40">
    <h2 class="font-extrabold mb-4 text-3xl">
      Só no precinho 🔥
    </h2>
    <div class="grid grid-cols-[repeat(auto-fill,_minmax(280px,_1fr))] gap-4">
      <ProductCard v-for="product in products" 
        :key="product.id" 
        :image="product.images ? product.images[0].url : ''" 
        :title="(product.title as string)" 
        :price="product.variants[0].prices[0].amount / 100"
        :handle="(product.handle as string)"
        :variant-id="(product.variants[0].id as string)"
      />
    </div>
  </section>
</template>
Clique aqui para expandir

Perceba que chamamos a função client.products.list() para acessar a api e listar os produtos

Além disso nós estamos usando um componente <Button></Button> que instalamos nas aulas anteriores com o shadcn.

Para finalizar também chamamos o componente <ProductCard></ProductCard> com um v-for para listar todos os cards de produto na parte inferior da página inicial.

Opa, calma aí!

Parece que você não está logado, caso tenha interesse em salvar seu progresso de estudo faça login agora.