Sunucu Taraflı Render API
Basmaya hazır HTML döndüren sunucudan sunucuya endpoint
Sunucu taraflı render ucu, panelde hazırladığınız zenginleştirme içeriğini basmaya hazır HTML olarak döndürür. Kendi uygulama sunucunuzdan çağırır, çıktıyı şablonunuza olduğu gibi yazarsınız. Bu sayfa HTTP sözleşmesidir: kimlik, parametreler, yanıt, önbellek, sınırlar, hatalar.
- Ne olduğu, ne zaman kullanılacağı, mimari ve panel ayarı: Sunucu Taraflı Render
- Kopyalanıp yapıştırılabilir PHP, Node, Next.js, Django örnekleri: Sunucu Taraflı Render Örnekleri
Neden hazır HTML
Diğer public uçlar ham veri döndürür ve işlemeyi widget yapar: yer tutucu doldurma, HTML temizleme, CSS kapsamlama. Sunucu tarafında bu üç adımı size yaptırmak üç ayrı güvenlik açığı davetiyesi olurdu: şablonda |safe, temizlenmemiş markup, kapsamlanmamış CSS. Bu yüzden uç son hâli döndürür: yer tutucular yerleşmiş, izin listesine göre temizlenmiş, CSS blok kapsamına alınmış. Widget'ın tarayıcıda, panel önizlemesinin ve bu ucun kullandığı işleme hattı aynıdır; panelde onayladığınız blok sayfada onayladığınız hâliyle çıkar.
Dönen HTML'i ikinci bir sanitizer'dan geçirmeyin
İçerik zaten temizlendi. Genel amaçlı bir sanitizer data-selwise-* niteliklerini siler; widget bloğu tanıyamaz, sayfada olduğunu bilmez ve ikinci bir kopyasını basar. Alışverişçi içeriği iki kez görür, arama motoru kopya içerik görür.
Uç nokta
/api/v1/public/sites/{siteKey}/ssr/enrichmentsKimlik: x-selwise-api-key, her istekte (ssr_read kapsamı)
Parametreler
siteKeystring · yolzorunluKanal anahtarı (Kanallar → Kanal Özeti → Kanal Anahtarı). Kanalı adlandırır; sır değildir.
codestring · sorguÜrün kodu: sku, item_code ya da sepet kodu; büyük/küçük harf duyarsız, en çok 100 karakter. Boş ya da uzunsa hata değil boş yanıt döner.
slotsstring · sorguYuva adları: virgülle ayrılmış (a,b) ya da tekrarlı parametre (slots=a&slots=b). Küçük harf, rakam ve tek tire; en çok 10, fazlası atılır. Verilmezse boş yanıt.
langstring · sorguZiyaretçinin ya da sayfanın dili (tr, en-GB…). Hesabın dillerinden en yakını seçilir; yoksa varsayılan dil. Tek dilli hesapta etkisi yoktur.
200 Başarılı
vstringİçerik sürüm damgası; ETag olarak da gelir. If-None-Match ile geri gönderirseniz değişmediyse 304 alırsınız.
modestringŞu an her zaman anonymous: yanıtta kişiye göre değişen bir şey yoktur, sayfa önbelleğine yazılabilir.
anonymous
slotsnesne (anahtar → değer)Yuva adına göre basılmaya hazır HTML. İçeriği olmayan yuva boş döner.
Alt alanlar (2)
htmlstringReady to print: interpolated, sanitised, scoped and wrapped in a stamped root.
assignmentIdsstring listesicssstringÇizilen blokların kapsamlanmış stilleri, tekilleştirilmiş. Sayfaya bir kez basın.
metanesneSorulan kod, katalogda bulunup bulunmadığı ve render zamanı.
Alt alanlar (3)
codestringresolvedbooleanrenderedAtstring · date-timeÖrnek yanıt
{
"v": "m3k1p.4",
"mode": "anonymous",
"slots": {},
"css": "string",
"meta": {
"code": "ABC-1",
"resolved": true,
"renderedAt": "2026-10-21T09:12:00.000Z"
}
}304 Değişmedi
If-None-Match matched the digest (v).
Hatalar: 400 geçersiz istek, 401 anahtar gönderilmedi, 402 modül sözleşmede yok, 403 anahtar geçersiz ya da kapsamı yetmiyor, 404 kanal bilinmiyor, 429 hız sınırı. Gövde biçimi için Hatalar ve Limitler.
curl -X GET 'https://api.selwise.com/api/v1/public/sites/{siteKey}/ssr/enrichments' \
-H "x-selwise-api-key: $SELWISE_API_KEY"GET /api/v1/public/sites/SITE_KEY/ssr/enrichments?code=ABC-1&slots=urun-aciklama-alti
x-selwise-api-key: swpk_live_...
Kimlik doğrulama
Diğer public uçlar güvenliği doğrulanmış alan adından alır. Sunucudan gelen bir isteğin Origin başlığı yoktur ve bir tarayıcı da bu ucu kimliksiz çağıramasın diye, bu uç her istekte, başlığın varlığından bağımsız olarak site API anahtarı ister.
Anahtarı Channels ekranında kanalın satırındaki ⋮ menüsünden API keys'i açıp Purpose (Kullanım amacı) olarak Server-side rendering (Sunucu taraflı render) seçerek oluşturun. Anahtar swpk_live_ ile başlar ve yalnızca bir kez gösterilir. Ayrıntı: API Anahtarları.
ssr_read kapsamı mobil SDK'nın mobile_read/mobile_write çiftiyle aynı torbada değildir: SSR anahtarı sizin uygulama sunucunuzda yaşar, dağıtım hattınızdan, CI günlüklerinizden ve imajlarınızdan geçer; sızan bir SSR anahtarı hiçbir şey yazamaz ve iptali mobil uygulamayı durdurmaz. ssr_read bu uç dışında hiçbir ucu açmaz.
SSR yalnızca web kanalı içindir: bir uygulama kanalının sayfa şablonu yoktur. Uygulama kanalında bir ssr_read anahtarı 403 alır; uygulamanın karşılığı app/enrichments ucudur.
| Yanıt | Anlamı |
|---|---|
401 | x-selwise-api-key başlığı yok. Bir şey sunmadınız |
403 | Anahtar geçersiz, iptal edilmiş ya da ssr_read kapsamı yok; ya da kanal bir web kanalı değil; ya da hesabın teslimatı kapalı |
404 | siteKey bulunamadı |
429 | Anahtar başına hız sınırı; Retry-After saniyedir |
Hız sınırı
Anahtar başına, IP başına değil: varsayılan 6000 istek/dakika. Sınır, anahtar doğrulanmadan önce sayılır; yanlış anahtarla yapılan deneme de sayaca girer (anahtar deneme saldırısının veritabanına ulaşmasını sınırlamak için).
Sebebi doğrudan sizinle ilgili: diğer public uçları alışverişçilerin tarayıcıları çağırır, yani bir IP kabaca bir ziyaretçidir. SSR çağrısını sizin sunucularınız yapar; bütün mağaza trafiği birkaç adresten çıkar. IP başına sayılsaydı yoğun bir mağaza paylaşılan public kovayı saniyeler içinde tüketir ve widget'ınızı, olay akışınızı ve aramanızı da durdururdu.
Yanıt X-RateLimit-Limit ve X-RateLimit-Remaining başlıklarını taşır. Selwise'in kendi sınırlayıcı deposu erişilemezse sınır açık bırakılır (istek reddedilmez): ürün sayfanız bizim sınırlayıcımızın arızası yüzünden render olmamalıdır.
İstek
Bir blok birden çok dilde yazılmışsa lang hangisinin basılacağını seçer; her dil ayrı önbelleğe yazılır. Hazır Akinon yardımcıları dili kendisi gönderir: PZ Classic Django'nun etkin dilini okur, PZ Next yardımcısının son parametresi dildir.
İki yazım da kabul edilir, çünkü ikisi de doğal olarak yazılan biçimdir: Django'nun urlencode çıktısı tekrarlı, elle kurulan bir Next.js adresi virgüllü olur.
Yuva adları kural gibi katlanır: küçük harf, boşluk ve alt çizgi tire olur (Urun_Aciklama → urun-aciklama); katlandıktan sonra geçerli olmayan ad (64 karakter, harf-rakam-tire, uçlarda tire yok) atılır. Şablonunuza panelin Saved as (Kaydedilecek hâli) satırındaki adı yazın.
Hata yerine boş yanıt. code boş, 100 karakterden uzun ya da slots boşsa uç 400 vermez: her istenen yuvayı boş bırakan bir 200 ve Cache-Control: no-store döner. Çağıran şablon, kendi sayfa modelinde ne varsa onu yeni okumuştur; bir veri sorunu yüzünden ürün sayfasının 400 ile kırılması istenmez, çünkü render hata durumunda sessizce boş kalacak şekilde tasarlanmıştır.
Yanıt
{
"v": "m3k1p.4",
"mode": "anonymous",
"slots": {
"urun-aciklama-alti": {
"html": "<div data-selwise-root=\"true\" data-selwise-entity-type=\"enrichment\" data-selwise-entity-id=\"8f3a2b7c-...\" data-selwise-ssr=\"1\" data-selwise-ssr-v=\"m3k1p.4\" data-selwise-ssr-slot=\"urun-aciklama-alti\"><div data-selwise-enrichment=\"5d1e9c0a...\">...</div></div>",
"assignmentIds": ["8f3a2b7c-..."]
},
"sepet-ustu": { "html": "", "assignmentIds": [] }
},
"css": "[data-selwise-enrichment=\"5d1e9c0a...\"] .spec-table{...}",
"meta": {
"code": "ABC-1",
"resolved": true,
"renderedAt": "2026-10-09T09:12:00.000Z"
}
}
Alanların tablosu yukarıdaki uç kutusundadır. Bir şablon yazarken bilmeniz gerekenler:
- İstenen her yuva (katlanmış adıyla)
slotsiçinde bulunur; içeriği olmayan yuva boş dize ve boş dizi taşır. Anahtar hiç eksilmez, şablon null denetimi yazmaz. - Bir yuvada birden çok kural varsa HTML'leri sırayla art arda gelir;
assignmentIdsçizim sırasıdır. meta.resolvedfalseise içerik yine gelir; yalnızca ürün yer tutucuları (${title},${price}...) boş kalır.meta.renderedAtyanıtın üretildiği andır; önbellekten dönen yanıtta eski bir an olabilir.
css alanının ayrı olması zorunlu: zenginleştirme izin listesi style etiketini yasaklar, yani markup'ın içine gömülü CSS zaten silinir. Stil blok kapsamına alınmış olduğu için head erişiminiz yoksa içeriğin yanına da basabilirsiniz.
Kök öğenin imzası
Her kuralın HTML'i tek bir kök öğeyle sarılır ve widget onu şu niteliklerden tanır; bunları değiştirmeyin ve silmeyin:
| Nitelik | Anlamı |
|---|---|
data-selwise-root="true" | Widget'ın kendi çizdiği her öğede bulunan kök işareti |
data-selwise-entity-type="enrichment" | Varlığın türü |
data-selwise-entity-id | Kuralın kimliği: widget bu kuralı bir daha çizmez |
data-selwise-ssr="1" | Bu kökü sunucunun yazdığını bildirir; widget çizmek yerine ölçümü devralır |
data-selwise-ssr-v | Sunucunun yanıt aldığı sürüm damgası |
data-selwise-ssr-slot | Köklerin hangi yuvaya yazıldığı |
İçeride her blok bir data-selwise-enrichment="<blokKimliği>" sarmalayıcısındadır; css alanındaki kurallar bu niteliğe göre kapsamlanmıştır.
Hangi kurallar döner
Yalnızca sunucuda basılabilecek ve ziyaretçiye göre değişmeyen kurallar:
| Döner | Dönmez | Neden |
|---|---|---|
Nerede oluşturulur alanı Sunucu, tarayıcı yedekli (auto) ya da Yalnızca sunucu (server) olan, yuva adı dolu, etkin (başlangıç ve bitiş penceresinde) kurallar | Test modundaki kurallar | Önbelleğe donan test içeriği herkese gider ve mağazadaki test bayrağı hiç sorulmaz |
| Tüm ziyaretçileri hedefleyen kurallar (segmentsiz, ya da segment listesi boş) | Segment hedefli kurallar | Kişiye göre değişen bir cevaptır; paylaşılan bir önbellekte bir ziyaretçinin segmenti herkese yapıştırılır |
| Ürüne kod listesiyle ya da katalog koşuluyla eşleşen kurallar | Yalnızca tarayıcı (client) kuralları, yuva adı olmayan kurallar | Adresi yoktur; yalnızca tarayıcıda yaşar |
Aynı yuvaya birden çok kural düşerse sıra: Priority (Öncelik) yüksek olan önce, eşitlikte eski olan önce. When rules collide (Kurallar çakıştığında) ayarı Render only the highest-priority block olan bir kural yuvayı tek başına alır. Bu sıra, widget'ın tarayıcıda kullandığıyla aynıdır; sunucuda ve tarayıcıda aynı içerik görünür.
Önbellekleme
İki ayrı katman var ve ikisi de anlamlı:
Selwise tarafında. Yanıt (ürün kodu, yuva kümesi ve sürüm damgası anahtarlı) 5 dakika tutulur; içeriği olmayan yanıt 1 dakika, çünkü bir ürünün kural listesine yeni eklenmesi çabuk görünmelidir. Sürüm damgası anahtarın parçası olduğu için bir kuralı panelden düzenlediğinizde yeni istekler yeni içeriği alır.
Sizin tarafınızda. Yanıt şu başlıklarla gelir:
Cache-Control: public, max-age=60, stale-while-revalidate=600
ETag: W/"..."
Vary: x-selwise-api-key
ETag'i saklarsanız tekrar render bir gövde yerine 304 maliyetine iner (If-None-Match gönderin). ETag içerikten (sürüm, yuvalar, css) türetilir, renderedAt'ten değil: bayt bayt aynı içerik için yeni bir doğrulayıcı çıkmaz. max-age kasten kısa: bu HTML sizin sayfanızın içine girdiği anda bizim önbelleğimizin ulaşamayacağı bir yere geçer ve panelde yapılan bir düzenleme oraya yetişemez. Vary: x-selwise-api-key paylaşılan bir önbelleğin bir merchant'ın içeriğini başkasının anahtarına sunmasını engeller.
Bir ürün başına bir upstream çağrısı yeter: sayfa önbelleğiniz ya da süreç içi önbellek 60 saniye tutarsa yoğun bir ürün sayfası dakikada bir Selwise çağrısına iner.
Zaman aşımı ve yedek davranışı
Çağrıyı kısa bir zaman aşımıyla yapın (önerilen 400 ms; sağlıklı bir çağrının kat kat üstü, alışverişçinin fark etmeyeceği kadar kısa) ve hatayı yutun. Ürün sayfanız bizim yüzümüzden beklememeli.
Bozulma merdiveni şu sırayla iner ve hiçbir basamak diğerini beklemez:
SSR başarılı → içerik ilk baytta, tarayıcı botu görür, widget ölçümü devralır
SSR başarısız → şablon hiçbir şey basmaz → kural "Sunucu, tarayıcı yedekli" ise widget tarayıcıda basar
widget de yoksa → sayfa mağazanın kendi hâliyle çıkar, hiçbir şey kırılmaz
Yani istemcinizi şöyle yazın: zaman aşımı, ağ hatası, 4xx, 5xx ve bozuk JSON hepsi boş dize döner. 404 ve 403 kalıcı hatalardır (yanlış anahtar, yanlış siteKey, SSR'ı olmayan kanal); onları günlüğe uyarı olarak yazın ve alarm kurun, çünkü bu durumda içerik hiç gelmez ve sayfa yine de başarılı görünür.
Boyut sınırı
Bir yanıtın markup'ı en çok 256 KB taşır. Sınıra ulaşıldığında yanıt kural sınırında kesilir: ilk kurallar gelir, sınırı aşan kural (parçası değil, tamamı) atlanır; sunucu günlüğüne bir uyarı düşer. Bu HTML sizin sayfanızın içinde her ürün görüntülemesinde taşındığı için sınır bir formalite değildir.
Hatalar
| Durum | Ne zaman |
|---|---|
200 | Her durumda içerik yoksa bile; slots.*.html boş olabilir |
304 | If-None-Match ETag ile eşleşti, gövde yok |
401 | Başlık yok |
403 | Anahtar geçersiz/iptal/kapsam yok, web kanalı değil, hesap teslimatı kapalı |
404 | siteKey yok |
429 | Anahtar başına dakikada 6000 aşıldı |
5xx | Selwise tarafında geçici hata; boş dize basın, bir sonraki ziyarette yeniden deneyin |
Hiçbir 400 yoktur: geçersiz parametreler boş yanıt verir.
Arama ve öneriler
Arama ve öneri uçları da sunucudan çağrılabilir; ikisi de JSON döndürür ve markup üretmez: liste şablonu sizin tasarımınızdır, bizim basacağımız markup orada yabancı durur. Bkz. Arama API'si, Öneri API'si. Öneri şeritlerinin sunucuda HTML olarak oluşturulması bugün yoktur; kampanya ve widget'lar da sunucuda basılmaz (geri sayım, sepet ve ziyaretçi sayısı gibi içerikler zamana ve ziyaretçiye göre değişir ve bir sayfa önbelleği tek bir cevabı herkese donduracağından bilerek dışarıda).
Son güncelleme: 21 Ekim 2026
