← Blog

Çerezsiz ziyaretçi sayacı yazmak

10 Ekim 2026·2 dakikayazılımgizlilikNext.js

Bir sitenin hangi sayfalarının okunduğunu bilmek için büyük bir analitik servisi, çerez onay penceresi ve ziyaretçileri siteler arası izleyen bir betik gerekmez. Bu sitenin ziyaretçi sayacını birkaç yüz satırla kendim yazdım. Bu yazı, nasıl çalıştığını ve hangi kararların gizliliği koruduğunu anlatıyor.

Neyi saymak istiyorum?

  • Hangi sayfalar okunuyor?
  • Ziyaretçiler nereden geliyor (arama, sosyal medya, doğrudan)?
  • Günde kaç tekil ziyaretçi var?

Kişiyi tanımak, onu siteler arasında takip etmek ya da uzun süreli bir profil çıkarmak hedeflerin arasında değil.

Tekil ziyaretçi, çerez olmadan

Tekil ziyaretçiyi saymanın alışılmış yolu, tarayıcıya kalıcı bir çerez koymaktır. Onun yerine her istek için sunucuda şu özeti üretiyorum:

const visitor = createHmac("sha256", SECRET)
  .update(`${gün}|${ip}|${tarayıcıBilgisi}`)
  .digest("hex")
  .slice(0, 16);
  • Gün de özetin içinde: aynı kişi ertesi gün farklı bir özet üretir; ziyaretçiler günler arasında birbirine bağlanamaz.
  • Tek yönlü: özetten IP adresine geri dönülemez; IP adresinin kendisi hiçbir yere yazılmaz.
  • Gizli anahtarla: yalnız sunucunun bildiği bir anahtar kullanıldığı için, olası IP'leri deneyerek özeti tahmin etmek pratik değildir.

Kimleri saymıyorum?

  • Botlar: tarayıcı bilgisinde bot, crawler ya da başsız tarayıcı izi olan istekler.
  • İzlenmek istemeyenler: tarayıcısında "Do Not Track" ya da "Global Privacy Control" açık olan ziyaretçiler hiç sayılmaz.
  • Kendim: panelde oturumum açıkken yaptığım ziyaretler yazılmaz; yoksa en sadık okuyucu ben olurdum.

Gelinen site

Ziyaretçinin hangi siteden geldiği document.referrer ile yalnız ilk sayfada gönderilir. Site içinde sayfadan sayfaya geçerken aynı bilgi tekrar gönderilmez; aksi hâlde her sayfa görüntülemesi dışarıdan gelmiş gibi görünürdü. Kampanya bağlantılarındaki utm_source parametresi varsa o kullanılır.

Sayaç sinyali navigator.sendBeacon ile gönderilir: sayfa kapanırken bile iletilir ve sayfanın yüklenmesini beklemez. Sinyal başarısız olursa sayfa hiçbir şekilde etkilenmez; sayaç asla okuma deneyimini bozmamalı.

Saklama süresi

Kayıtlar 400 gün sonra, her sabah çalışan zamanlanmış görevle silinir. Bir yıldan eskisini karşılaştırmak için yeterli, gereksiz uzun tutmayacak kadar kısa.

Sayacın ne topladığını ve ne toplamadığını ziyaretçilerin de görebileceği şekilde gizlilik sayfasında yazdım. Sitenin geri kalanının nasıl yapıldığı kolofon sayfasında.