Docs
Plataforma E-commerce

Plataforma E-commerce

Como implementar y personalizar la plataforma de comercio electrónico.

Manual de Usuario

Configuración Inicial

1. Variables de Entorno

Edita .env:

# Shopify
SHOPIFY_APP_API_SECRET_KEY=tu_clave_secreta_shopify
SHOPIFY_STORE_DOMAIN=tu-tienda.myshopify.com
SHOPIFY_STOREFRONT_ACCESS_TOKEN=token_acceso_storefront
SHOPIFY_ADMIN_ACCESS_TOKEN=token_acceso_admin
 
# MeiliSearch
MEILISEARCH_HOST=http://localhost:7700
MEILISEARCH_ADMIN_API_KEY=clave_admin_meilisearch
 
# Configuración General
LIVE_URL=https://tu-dominio.com

2. Configuración del Tema

Edita tailwind.config.ts:

module.exports = {
  theme: {
    colors: {
      primary: '#000000',
      secondary: '#666666',
      accent: '#ff0000'
    },
    container: {
      screens: {
        sm: '640px',
        md: '768px',
        lg: '1024px',
        xl: '1280px'
      }
    }
  }
}

3. Configuración de Navegación

Edita app/layout.tsx:

const navigationItems: NavItem[] = [
  {
    text: "Inicio",
    href: "/",
  },
  {
    text: "Categorías",
    href: "/category",
    submenu: {
      variant: "text-grid",
      items: [
        {
          text: "Electrónica",
          items: [
            { text: "Smartphones", href: "/category/smartphones" },
            { text: "Laptops", href: "/category/laptops" }
          ]
        }
      ]
    }
  }
]

Personalización de Componentes

1. Barra de Navegación

Edita components/NavigationBar/NavigationBar.tsx:

export function NavigationBar() {
  return (
    <nav className="bg-white shadow-sm">
      <div className="max-w-7xl mx-auto px-4">
        <div className="flex items-center justify-between h-16">
          <Logo />
          <SearchButton />
          <div className="flex items-center gap-4">
            <CartButton />
            <FavoritesButton />
            <ProfileMenu />
          </div>
        </div>
      </div>
    </nav>
  )
}

2. Tarjeta de Producto

Edita components/ProductCard/ProductCard.tsx:

export function ProductCard({ 
  title,
  price,
  image,
  handle
}: ProductCardProps) {
  return (
    <div className="group relative">
      <Image 
        src={image}
        alt={title}
        className="w-full aspect-square object-cover"
      />
      <div className="p-4">
        <h3 className="text-lg font-medium">{title}</h3>
        <p className="text-xl font-bold">{price}</p>
        <AddToCartButton handle={handle} />
      </div>
    </div>
  )
}

3. Carrito de Compras

Edita views/Cart/CartView.tsx:

export function CartView() {
  return (
    <div className="fixed right-0 top-0 h-full w-96">
      <div className="flex h-full flex-col">
        <header className="p-4 border-b">
          <h2>Tu Carrito</h2>
        </header>
        <div className="flex-1 overflow-auto p-4">
          <CartItems />
        </div>
        <footer className="border-t p-4">
          <CartSummary />
          <CheckoutButton />
        </footer>
      </div>
    </div>
  )
}

Configuración de Búsqueda

1. Cliente MeiliSearch

Edita clients/meilisearch.ts:

export const meilisearch = new MeiliSearch({
  host: env.MEILISEARCH_HOST,
  apiKey: env.MEILISEARCH_ADMIN_API_KEY,
})
 
export const searchConfig = {
  indexName: 'products',
  searchableAttributes: [
    'title',
    'description',
    'vendor'
  ],
  filterableAttributes: [
    'price',
    'categories',
    'vendor'
  ],
  sortableAttributes: [
    'price',
    'created_at'
  ]
}

2. Configuración de Búsqueda

Edita actions/product.actions.ts:

export const searchProducts = unstable_cache(
  async (query: string, filters = {}, limit = 20) => {
    const index = await meilisearch.getIndex('products')
    
    return await index.search(query, {
      limit,
      filter: buildFilters(filters),
      sort: ['price:asc']
    })
  },
  ['product-search'],
  { revalidate: 60 }
)

Integración con Shopify

1. Cliente Storefront

Edita clients/storefrontClient.ts:

export const storefrontClient = {
  async getProduct(id: string) {
    // Implementación
  },
  
  async createCart(items = []) {
    // Implementación  
  },
  
  async checkout(cartId: string) {
    // Implementación
  }
}

2. Webhooks

Edita app/api/webhooks/route.ts:

export async function POST(req: Request) {
  const hmac = req.headers.get('X-Shopify-Hmac-Sha256')
  const topic = req.headers.get('X-Shopify-Topic')
  
  if (!isValidWebhook(hmac)) {
    return new Response(null, { status: 401 })
  }
 
  switch (topic) {
    case 'products/create':
      await handleProductCreate(req.body)
      break
    case 'products/update':
      await handleProductUpdate(req.body)
      break
    case 'products/delete':
      await handleProductDelete(req.body) 
      break
  }
 
  return new Response(null, { status: 200 })
}

Mejores Prácticas

1. Rendimiento

  • Implementar caching con unstable_cache
  • Usar Server Components cuando sea posible
  • Optimizar imágenes con next/image
  • Implementar loading states con Suspense
<Suspense fallback={<ProductSkeleton />}>
  <ProductView />  
</Suspense>

2. SEO

  • Configurar metadata por página
  • Implementar Open Graph tags
  • Generar sitemap.xml dinámico
  • Usar rutas semánticas
export const metadata = {
  title: 'Título de la Página | Tu Tienda',
  description: 'Descripción de la página',
  openGraph: {
    title: 'Título OG',
    description: 'Descripción OG',
    images: ['/og-image.jpg']
  }
}

3. Accesibilidad

  • Usar roles ARIA apropiados
  • Implementar manejo de teclado
  • Mantener buen contraste de colores
  • Incluir textos alternativos
<button
  role="button"
  aria-label="Agregar al carrito"
  onKeyDown={handleKeyDown}
>
  Agregar al carrito
</button>

Solución de Problemas

1. Caché y Datos

# Limpiar caché
rm -rf .next
npm run dev
 
# Regenerar tipos
npm run generate:types
 
# Verificar índices
npm run reindex

2. Errores Comunes

  • Verificar variables de entorno
  • Validar permisos de API
  • Comprobar webhooks
  • Revisar logs de error

3. Optimizaciones

  • Monitorear Core Web Vitals
  • Analizar bundle size
  • Verificar tiempos de respuesta
  • Optimizar queries