Next.js ile Headless E-Commerce Mimarisi

Modern, Ölçeklenebilir ve Performans Odaklı Bir Yaklaşım

Geleneksel e-ticaret uygulamaları, frontend, backend ve içerik yönetimini tek bir monolit yapı altında sunmaktadır. Ancak artan performans beklentileri ve SEO gereksinimleri Headless E-Commerce mimarisini kaçınılmaz hale getirmiştir.

Bu makalemde, Next.js App Router kullanarak uçtan uca bir Headless E-Commerce mimarisi nasıl kurgulanır, hangi katmanlara ayrılır ve bu yapı neden avantajlıdır sorularını ele alacağım.

Headless E-Commerce Nedir?

Headless E-Commerce; frontend ile backend katmanlarının birbirlerinden tamamen ayrıldığı bir mimaridir. Yani backend yalnızca API sağlar, frontend ise bu API'leri tüketerek arayüzü oluşturur.

Klasik vs Headless Karşılaştırması
Özellik Klasik E-Commerce Headless E-Commerce
Frontend Backend'e bağlı Tamamen bağımsız
Performans Orta Yüksek
SEO Sınırlı Gelişmiş (SSR/SSG)
Çoklu Platform Zor Kolay
Ölçeklenebilirlik Düşük Yüksek

Mimari Genel Bakış

Bu makalemde, aşağıdaki örneği kullanacağım;


    ┌──────────────┐
    │ Next.js App  │  ← Frontend (SSR / SSG)
    └──────┬───────┘
           │ REST / GraphQL
    ┌──────▼───────┐
    │ API Layer    │  ← Ürün, Sepet, Sipariş
    └──────┬───────┘
           │
    ┌──────▼───────┐
    │ Commerce DB  │  ← PostgreSQL / MongoDB
    └──────────────┘

Bağımlılıklar

  • Next.js 14 (App Router)
  • Typescript
  • REST API
  • Prisma ORM
  • PostgreSQL
  • Stripe (Ödeme Yöntemi)
  • Redis (Opsiyonel)

Proje Klasör Yapısı


    src/
    ├─ app/
    │  ├─ page.tsx
    │  ├─ products/
    │  │  └─ [slug]/page.tsx
    │  ├─ cart/
    │  └─ checkout/
    ├─ lib/
    │  ├─ api.ts
    │  └─ fetcher.ts
    ├─ services/
    │  └─ product.service.ts
    ├─ components/
    │  ├─ ProductCard.tsx
    │  └─ AddToCart.tsx

Backend (Headless API) – Ürün Endpoint’i

/api/products


    // services/product.service.ts
    export async function getProducts() {
        return fetch("https://api.example.com/products", {
            cache: "no-store",
        }).then(res => res.json());
    }

Frontend – Ürün Listeleme (SSR)

/app/page.tsx


    import { getProducts } from "@/services/product.service";
    import ProductCard from "@/components/ProductCard";

    export default async function HomePage() {
        const products = await getProducts();

        return (
            <main className="grid grid-cols-3 gap-6">
                {products.map((product: any) => (
                    <ProductCard key={product.id} product={product} />
                ))}
            </main>
        );
    }

Bu kısımda Server Component kullandığımız için;

  • SEO mükemmel,
  • İlk yükleme çok hızlı,
  • Google botları, sayfayı direkt indeksler.

Dinamik Ürün Detay Sayfası

/app/products/[slug]/page.tsx


    async function getProduct(slug: string) {
      const res = await fetch(
        `https://api.example.com/products/${slug}`,
        { cache: "no-store" }
      );
      return res.json();
    }

    export default async function ProductDetail({ params }: any) {
      const product = await getProduct(params.slug);

      return (
        <div>
          <h1>{product.title}</h1>
          <p>{product.description}</p>
          <strong>{product.price} ₺</strong>
        </div>
      );
    }

Sepet Yönetimi (Client Component)

AdToCard.tsx


    "use client";

    export default function AddToCart({ productId }: { productId: string }) {
      const addToCart = async () => {
        await fetch("/api/cart", {
          method: "POST",
          body: JSON.stringify({ productId }),
        });
      };

      return (
        <button onClick={addToCart}>
          Sepete Ekle
        </button>
      );
    }

Headless mimaride sepet yönetimi;

  • Cookie,
  • Redis,
  • Localstorage ile yapılabilir.

Ödeme Akışı (Stripe Mantığı)


    Kullanıcı → Checkout → API → Stripe → Webhook → Sipariş Oluştur

Checkout API Örneği


    // app/api/checkout/route.ts
    import Stripe from "stripe";

    const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

    export async function POST(req: Request) {
      const session = await stripe.checkout.sessions.create({
        payment_method_types: ["card"],
        mode: "payment",
        line_items: [],
        success_url: "/success",
        cancel_url: "/cancel",
      });

      return Response.json({ url: session.url });
    }

Headless Mimarinin Avantajları

1. Performans

  • SSR + Streaming,
  • CDN uyumlu.

2. SEO

  • Google botları gerçek HTML'i görür,
  • Core Web Vitals skorları yükselir.

3. Ölçeklenebilirlik

  • Frontend ve backend bağımsız ölçeklenir.

4. Çoklu Kanal

  • Aynı API -> Web, Mobil, PWA.

Headless Mimarisi Ne Zaman Tercih Edilmeli?

  • Büyük ürün katalogları,
  • SEO odaklı projeler,
  • Web + Mobil birlikte,
  • Uzun vadeli büyüme hedefi.

Sonuç

Next.js + Headless E-Commerce, modern e-ticaret dünyasında en güçlü kombinasyonlardan biridir. Doğru kurgulandığında:

  • Google’da daha hızlı sıralama alır,
  • Kullanıcı deneyimi artar,
  • Bakım ve geliştirme maliyeti düşer.

20 Ara 2025
Yorum