Harmal — lüks mücevher e-ticareti ve yönetim paneli
Bakü'de el yapımı mücevher ve doğal ipek kelağayı satan lüks bir marka için üç dilli e-ticaret sitesi. Next.js ile full-stack geliştirildi: editoryal tarzda vitrin, dergi bölümü ve markanın kendisinin yönettiği yönetim paneli — ürünler, koleksiyonlar, dergi yazıları ve gelen talepler için.
Canlı siteyi gör- Müşteri
- Harmal — el yapımı mücevher ve ipek kelağayı markası, Bakü
- Rol
- Full-stack geliştirme — projenin tüm katmanları: üç dilli frontend mimarisi, Next.js route handler'ları, Prisma/SQLite veri modeli, JWT tabanlı yönetici kimlik doğrulaması, görsel yükleme akışı, performans ve VPS'te yayına alma (PM2 + Nginx).
- Stack
- Next.js · TypeScript · Prisma · SQLite · Tailwind CSS
- Tarih
- Ağustos 2026
- Dil
- 3 — AZ / EN / RU
- Lighthouse (mobil)
- 93
- Lighthouse (masaüstü)
- 93
Lüks mücevherin online satışında iki ayrı sorun var. Birincisi güven: müşteri ürünü eline almadan, dört haneli bir tutarı ekrandaki fotoğrafa bakarak ödemeli. Sıradan bir e-ticaret şablonu — sık ürün ızgarası, indirim etiketleri, «hemen al» düğmeleri — bu güveni kurmaz, aksine markayı ucuzlatır. İkincisi site yayına çıktıktan sonra başlar: koleksiyon mevsimle değişir, fiyat altın kuruna bağlıdır, dergiye düzenli yazı düşer. Bu tür her değişiklik için geliştiriciye yazmak gerekiyorsa site birkaç ayda eskir — pratikte marka siteyi güncellemekten basitçe vazgeçer.
- Üç dilli arayüz — Azerbaycan Türkçesi, İngilizce ve Rusça, her biri ayrı adreste
- Koleksiyon vitrini ve ürün kategorileri
- Markanın kökenini anlatan editoryal tarzda bölümler
- Müşteri yorumları bölümü
- Tarihli yazılarla dergi (blog) bölümü
- Sıkça sorulan sorular bölümü
- Kalite ilkelerini anlatan «Harmal Standardı» bölümü
- Başlıkta canlı arama alanı
- Ayrı dergi sayfası — yazılar Kültür, Rehber ve Stil kategorilerine göre filtreleniyor
- Ayrı mağaza, iletişim ve sıkça sorulan sorular sayfaları
- Parallax ile açılan marka kökeni hikâyesi
- Yönetim paneli: ürün ve koleksiyon ekleme, düzenleme, silme
- Yönetim panelinden dergi yazılarının yazılması ve yayımlanması
- Siteden gelen talep ve siparişlerin panel içinde listelenmesi
- Ürün ve dergi görsellerinin doğrudan panelden yüklenmesi
- JWT ile korunan yönetici girişi — panel rotaları middleware seviyesinde kapalı
- Frontend
- Next.js App Router. Her dil (AZ / EN / RU) kendi rotasında; vitrin, mağaza, dergi, iletişim ve SSS sayfaları sunucu tarafında render ediliyor. Görseller `next/image` ile boyutlandırılıyor, marka kökeni parallax ile açılıyor, başlıkta canlı arama çalışıyor.
- Backend
- Ayrı bir API sunucusu yok — backend aynı Next.js uygulamasının route handler'larıdır. Ürün, koleksiyon, dergi ve talep işlemleri bu rotalardan geçiyor. Frontend ile backend aynı TypeScript tiplerini paylaşıyor; yani bir alan adı değiştiğinde hata build sırasında ortaya çıkıyor — kullanıcı onu görmeden önce.
- Veritabanı
- Prisma + SQLite. Şema `schema.prisma` dosyasında tanımlanıyor ve değişiklikler migration ile yapılıyor; veritabanı ise sunucunun kendi diskinde tek bir dosya olarak yaşıyor. Ürünler, koleksiyonlar, dergi yazıları ve talepler aynı şemanın içinde.
- Kimlik doğrulama
- Kendi JWT akışı: giriş başarılı olduğunda token sunucuda imzalanıp `httpOnly` cookie'ye yazılıyor. `/admin` altındaki rotalar hem middleware seviyesinde hem de her route handler'ın içinde kontrol ediliyor.
- Medya
- Ürün ve dergi görselleri yönetim panelinden yükleniyor ve VPS'in diskine yazılıyor; sitede `next/image` üzerinden ekran boyutuna uygun şekilde sunuluyor.
- Altyapı
- VPS üzerinde Next.js süreci PM2 ile ayakta tutuluyor — yeniden başlatma ve çökme durumunda kaldırma onun işi. Önde Nginx reverse proxy duruyor: SSL, sıkıştırma ve statik dosyaların önbelleği orada çözülüyor.
Neden Next.js?
Mücevher sitesi görsel ağırlıklı, üç dilde çalışıyor ve aynı zamanda kendi yönetim paneline ihtiyaç duyuyor. Next.js bu üçünü tek uygulamada birleştiriyor: sayfalar sunucu tarafında hazır HTML olarak sunuluyor, yönetim rotaları ise aynı projenin içinde yaşıyor. Klasik bir SPA ve ayrı bir API yapısında aynı iş iki repo, iki deploy ve iki kez tekrarlanan tip tanımı demek olurdu.
Görsellerin optimizasyonu
Ürün fotoğrafları sitenin en ağır kısmı. `next/image` ile her görsel ekran boyutuna uygun ölçüde ve modern formatta (WebP) sunuluyor — böylece mobil kullanıcı masaüstü boyutunda görsel indirmiyor. Lüks bir markada fotoğraf kalitesi düşürülemez, bu yüzden kazanç kaliteden değil, boyuttan elde ediliyor.
Üç dil ayrı rotada, hreflang ile birbirine bağlı
Her dil kendi adresinde yaşıyor, yani arama motorları üç ayrı sayfa indeksliyor — bu, markanın hem Azerbaycan Türkçesi hem de Rusça konuşan müşteriye ulaşması için önemli. Ama ayrı adres tek başına yetmez: sistem bu üç sayfanın aynı içeriğin çevirisi olduğunu da bilmeli. Bu yüzden her sayfada hreflang bağlantıları ve x-default işareti var. Bunlar olmadan üç dil birbirinin rakibi olarak indekslenir ve marka fiilen kendi kendisiyle yarışır.
Yapılandırılmış veri markayı makineye anlatır
Sayfada dört ayrı JSON-LD bloğu var. Bu, arama motoruna ve yapay zekâ modellerine markanın ne sattığını, nerede bulunduğunu ve hangi yazıları yayımladığını tahmin ettirmiyor — doğrudan söylüyor. Lüks bir marka için bu özellikle önemli, çünkü arama sonucunda çıkan kısa açıklama çoğu zaman müşterinin markayla ilk temasıdır.
Dergi satış kanalının bir parçası
Kelağayı kültürünü okuyan, pırlanta seçme rehberi arayan ve günlük stil tavsiyesi isteyen üç farklı kişidir. Yazılar tam da bu üç kategoriye ayrıldı, çünkü her biri farklı bir aramadan geliyor ve farklı bir koleksiyona götürüyor. Dergi burada bir içerik bölümü değil, mağaza sayfalarına açılan bir giriş kapısı.
Neden Postgres değil de SQLite?
Harmal'ın veri profili belli: yüzlerce ürün ve dergi yazısı, günde birkaç yazma işlemi, buna karşılık binlerce okuma. Bu profilde SQLite aynı makinede, ağ gidiş-dönüşü olmadan okuyor — sorgu için ayrı bir veritabanı sunucusuna gidilmiyor. Postgres burada ne hız kazandırırdı ne de yeni bir özellik getirirdi: yalnızca ayrı bir süreç, ayrı bellek ve ayrı bir arıza noktası eklerdi. Prisma şeması ise yerinde — mağaza büyüyüp aynı anda çok sayıda yazma gerektirdiğinde veritabanı değişikliği birkaç satırlık bir migration. Teknolojiyi bugünkü yüke göre seçmek, yarınki ihtimal için peşin ödemekten ucuzdur.
Panel olmasa site üç ayda eskir
Mevsim değişince koleksiyon değişir, altın pahalanınca fiyat güncellenir, dergiye yazı düşer. Bu değişiklikleri kodda yapmak, markanın her seferinde geliştiricinin boş vaktini beklemesi demek — pratikte beklemiyor, siteyi güncellemekten vazgeçiyor ve vitrin geçmiş mevsimde donup kalıyor. Bu yüzden ürün, koleksiyon ve dergi yönetim panelinden yönetiliyor: marka kendi vitrinini kendisi sürdürüyor, ben yalnızca sistemi sürdürüyorum.
Giriş token'ı httpOnly cookie'de saklanır
Yönetim paneli, markanın tüm ürün veritabanına ve müşteri taleplerine açılan kapı. Token `localStorage`'da saklansaydı, sitedeki herhangi bir XSS açığı onu okuyabilirdi. `httpOnly` cookie JavaScript'e görünmez, `SameSite` ise token'ın başka bir siteden gönderilen isteğe eklenmesini engeller. Kontrol yalnızca middleware'de değil, her route handler'ın kendi içinde: arayüzü gizlemek koruma değil, sadece görüntüdür — API adresini bilen kişi arayüzü hiç görmez.
Neden Vercel değil de kendi VPS'i?
Bu projenin iki parçası kalıcı diske dayanıyor: SQLite dosyası ve yönetimden yüklenen ürün görselleri. Serverless ortamda dosya sistemi geçicidir — yazılan dosya bir sonraki deploy'a, çoğu zaman bir sonraki isteğe kadar yaşar. Yani Vercel seçilseydi, hem veritabanı hem de görsel depolama için ayrı ücretli hizmetler bağlanmalıydı. VPS'te ikisi de uygulamanın hemen yanında. Yani SQLite, diskte görsel depolama ve VPS birbirinden bağımsız üç karar değil — aynı kararın üç yüzü.
PM2 ve Nginx işi paylaşıyor
Next.js'in sunucu süreci tek başına yaşamayı bilmez: çöktüğünde kalkmalı, sunucu yeniden başladığında kendiliğinden çalışmalı — bunu PM2 yapıyor. Nginx ise önde durup ona ait olmayan işi üstleniyor: SSL sonlandırma, sıkıştırma, statik dosyaların önbelleği. Bu ayrım olmasaydı, aynı süreç hem uygulamayı çalıştırmak hem de her istekte şifrelemeyle uğraşmak zorunda kalırdı — yani ürün sayfası sertifika işleminin arkasında sıra beklerdi.
Site Ağustos 2026'dan beri üç dilde yayında. PageSpeed Insights ölçümünde performans hem mobilde hem masaüstünde 93, SEO ise 100 puan — ürün fotoğraflarıyla dolu bir vitrin için bu, görsel boyutlandırmanın ve statik üretimin işe yaradığını gösteriyor. Günlük içerik markanın kendi elinde: ürün, koleksiyon, fiyat ve dergi yazıları yönetim panelinden değişiyor, sıradan bir güncelleme için geliştirici müdahalesi gerekmiyor.
- Harmal hazır bir platform (Shopify, WooCommerce) üzerinde mi kuruldu?
- Hayır. Site sıfırdan Next.js ve TypeScript ile yazıldı — kendi veritabanı (Prisma + SQLite), kendi backend rotaları ve kendi yönetim paneliyle. Aylık abonelik ücreti, tema kısıtlaması veya eklenti bağımlılığı yok.
- Ürünleri ve dergi yazılarını kim ekliyor?
- Markanın kendisi. Ürünler, koleksiyonlar ve dergi yazıları yönetim panelinden ekleniyor, düzenleniyor ve siliniyor; görseller de doğrudan panelden yükleniyor. Sıradan bir içerik değişikliği için geliştirici müdahalesi gerekmiyor.
- Sitenin backend kısmını kim yazdı?
- Projenin tüm katmanları — frontend, Next.js route handler'ları, Prisma veri modeli, yönetim paneli, kimlik doğrulama ve sunucuda yayına alma — Nurlan Qadirov tarafından yazıldı. Harmal hem frontend hem de full-stack bir iş örneği.
- Site kaç dilde çalışıyor?
- Üç dilde: Azerbaycan Türkçesi, İngilizce ve Rusça. Her dil ayrı bir adreste yaşıyor ve hreflang ile diğerlerine bağlanıyor; yani üçü de arama motorları için bağımsız sayfalar.
- Site nerede barındırılıyor?
- Kendi VPS'inde. Next.js süreci PM2 ile ayakta tutuluyor, önünde Nginx reverse proxy duruyor. Bu seçim, SQLite veritabanının ve yönetimden yüklenen görsellerin kalıcı bir diskte kalması içindir.
Projenizi konuşalım — genellikle aynı gün yanıt veriyorum.
Nurlan Qadirov — Baku, Azerbaijan