Storefront là bộ mặt của hệ thống E-commerce. Yêu cầu quan trọng nhất là Tốc độ (Core Web Vitals) và SEO.
1. Hybrid Rendering Strategy
Không dùng use client cho toàn bộ ứng dụng. Chúng ta tận dụng tối đa Server Components.
Home Page & Product Listing (ISR)
Trang chủ và danh sách sản phẩm nên được cache và revalidate theo thời gian (revalidate: 60).
tsx:
// apps/store/app/page.tsx
import { ProductCard } from "@repo/ui/product-card";
import { getFeaturedProducts } from "@/lib/api";
export const revalidate = 60; // Revalidate mỗi 60s
export default async function HomePage() {
const products = await getFeaturedProducts();
return (
<main className="container py-10">
<h1 className="text-3xl font-bold mb-6">Sản phẩm nổi bật</h1>
<div className="grid grid-cols-4 gap-6">
{products.map((p) => (
<ProductCard key={p.id} product={p} />
))}
</div>
</main>
);
}Product Detail (Dynamic + Metadata)
Trang chi tiết sản phẩm cần SEO Title chuẩn chỉnh.
tsx:
// apps/store/app/products/[slug]/page.tsx
export async function generateMetadata({ params }): Promise<Metadata> {
const product = await getProduct(params.slug);
return {
title: `${product.name} - Mua ngay giá tốt`,
description: product.summary,
openGraph: { images: [product.thumbnail] }
}
}
export default async function ProductPage({ params }) {
const product = await getProduct(params.slug);
return <ProductDetailClient product={product} />
}2. Client Components: Interactivity
Chỉ những phần tương tác mới dùng Client Component.
- Add to Cart Button: Cần truy cập LocalStorage/Zustand.
- Gallery Slider: Cần Event Listeners.
tsx:
// apps/store/components/add-to-cart.tsx
"use client";
import { useCartStore } from "@/store/cart";
import { Button } from "@repo/ui/button";
export function AddToCart({ product }) {
const addItem = useCartStore((s) => s.addItem);
return (
<Button onClick={() => addItem(product)}>
Thêm vào giỏ
</Button>
);
}3. Optimistic Updates (Cart)
Khi user bấm "Thêm vào giỏ", giao diện phải phản hồi ngay lập tức (hiện số +1 ở icon giỏ hàng) trước khi server kịp trả lời.
Zustand kết hợp với persist middleware là lựa chọn hoàn hảo cho Cart ở Client-side.