Kampanya ve Widget
Segment, deney, sıklık sınırı ve custom widget
Panelde tanımladığınız kampanya ve widget'lar uygulamada da çalışır. SDK size hangi yüzeylerin bu ekranda gösterilmeye hakkı olduğunu verir; Akinon App Maker eklentisi bunları native olarak çizer.
Hangi kapılardan geçer
getSurfaces() bir yüzeyi döndürmeden önce web widget'ının sorduğu soruların
aynısını sorar — ve aynı sırada. Sıra önemlidir: her adım "gereğinden fazla
gösterme" yönünde koruma sağlar.
- Test modu. Test modundaki bir kampanya gerçek ziyaretçiye görünmez; test edene ise yalnızca o görünür. Filtre değil, kapıdır.
- Sayfa hedefleme.
app://home,app://productgibi sentetik ekran adlarına göre. Bkz. Event Takibi. - Ülke hedefleme. Ülke, isteğin IP adresinden sunucu tarafında çözülür ve
yapılandırmayla birlikte uygulamaya gelir — uygulamanın bunu bilmesi
gerekmez.
getSurfaces()çağrısındacountrygeçerseniz sizin değeriniz kullanılır. - Deney dışlaması. Bir A/B testi kontrol yüzeyini varyantıyla değiştirdiyse kontrol çizilmez. İkisini birlikte göstermek ziyaretçiye her iki kolu aynı anda göstermek olur.
- Segment hedeflemesi.
includemodunda ziyaretçi listedeki segmentlerden en az birinde olmalı;excludemodunda hiçbirinde olmamalıdır. Segment üyeliği sunucuya sorulur ve beş dakika önbelleklenir. - Boş içerik. İçeriği olmayan bir kayıt atlanır. Tek istisna
customtipidir: orada kod içeriğin kendisidir. - Deney içeriği.
config_overridemodunda varyantın içeriği kontrolün üzerine birleştirilir. Dizi değerleri değiştirilir, birleştirilmez — üç slaytlı bir varyant altı slayt olmaz. - Koşullu içerik ve sepet değerleri. Kampanyanın durumları varsa eşleşen ilk durum uygulanır; gizleyen bir durum yüzeyi düşürür. Metindeki sepet değerleri uygulamanın bildirdiği sepetle doldurulur. Ayrıntı aşağıda.
- Çatışma çözümü. Aynı yuvayı isteyen iki yüzeyden biri gösterilir.
- Sıklık sınırı. Harcanmış bir kota yüzeyi düşürür.
Segment kapısı ağ hatasında ne yapar
Sunucuya ulaşılamazsa cevap "hiçbir segmentte değil" olur. Bu, include
modunda göstermemek, exclude modunda göstermek demektir — web ile
birebir aynı davranış. Tersi olsaydı bir kampanya ya tüm kitlesinden
saklanırdı ya da bastırılmış olduğu kitleye gösterilirdi.
Çatışma çözümü: uygulamada neden daha kritik
Web'de iki widget aynı CSS seçicisini hedeflediğinde çakışır. Uygulamada
çekişilen kaynak yuva konumudur: top, bottom, center. Aynı yuvaya
iki duyuru çubuğu üst üste biner, iki popup aynı anda açılır.
Kurallar web ile aynıdır:
| Davranış | Sonuç |
|---|---|
highest_priority (varsayılan) | En yüksek öncelik kazanır; eşitlikte kayıt kimliğine göre kararlı seçim |
all | Gruptaki herkes gösterilir |
random | Grubun tamamı random ise biri seçilir |
Pratik sonuç: aynı ekranda aynı yuvaya iki yüzey koyarsanız biri hiç görünmez. Panelde bunu görürseniz ya ekranları ayırın ya da öncelik verin. Seçiciyle yerleştirilmiş yüzeyler uygulamada bir yuva işgal etmez, dolayısıyla hiçbir şeyle çekişmez.
Sıklık sınırı
Panelde tanımladığınız perSession, perDay, perWeek, total ve
minInterval kuralları uygulamada da geçerlidir.
Uygulamada bu web'den daha önemlidir: bir web sayfası her gezinmede yeniden yüklenirken uygulama süreci ekranların ötesinde yaşar. Kota kalıcı olarak diske yazılır, yani uygulama kapanıp açıldığında da korunur.
Kota yüzey gerçekten çizildiğinde harcanır, listeye girdiğinde değil. Tetikleyicisi hiç ateşlenmemiş bir popup ya da eşiğinin altında kalan bir sayaç kotasını kaybetmez.
Koşullu içerik, sepet ve ürün değerleri
Panelde bir kampanyaya koşullu içerik
eklediyseniz SDK durumu sizin yerinize seçer. getSurfaces() size kazanan
durumun içeriğini verir: surface.content o durumun metinlerini taşır,
surface.stateId hangi durumun kazandığını söyler (temel içerikte null).
Gizleyen bir durum eşleşirse yüzey listede hiç yer almaz; çizilmediği için
gösterim de yazılmaz ve çatışma çözümünde başka bir yüzeyin yuvasını almaz.
Kampanya metnindeki {cart.total} ve {cart.itemCount} değerleri de
uygulamanın bildirdiği sepetle doldurulur. Bir durumun metnindeki değer
söylenemiyorsa (sepet henüz bildirilmemişse ya da tutarın yazılacağı bir para
birimi yoksa) o durum atlanır ve sıradaki eşleşen duruma, en sonda temel
içeriğe geçilir; temel içerik de söylenemiyorsa yüzey döndürülmez. Uygulamanız
hiçbir zaman ham bir süslü parantez basmaz.
Ürün değerleri ({product.title}, {product.price}, {product.originalPrice},
{product.discountAmount}, {product.discountRate}, {product.stock})
ekranın gösterdiği üründen doldurulur. Uygulamada ürünü SDK'ya siz verirsiniz,
çünkü ekran ürünü zaten mağazadan almıştır:
const surfaces = await selwise.getSurfaces('app://product', {
product: {
title: product.name,
price: product.price, // şimdiki fiyat
originalPrice: product.retailPrice, // indirimden önceki fiyat; indirim yoksa vermeyin
stock: selectedVariant.stock, // bilinmiyorsa vermeyin
currency: 'TRY', // isteğe bağlı; yoksa kanalın para birimi
},
});
- Ürünü yalnızca ürün ekranında verin. Ürün verilmeyen bir ekranda ürün değeri kullanan durum atlanır, temel içerik de ürün değeri kullanıyorsa yüzey döndürülmez.
- Değerler web'deki kurallarla söylenir: önceki fiyat, indirim tutarı ve
indirim yüzdesi yalnızca önceki fiyat şimdiki fiyattan yüksekse, stok
yalnızca sıfırdan büyükse söylenir. Sayısal bir metin de kabul edilir
(
'899.00'). - Ürün değiştiğinde (başka bir ürüne geçildiğinde, ya da ürün yeniden
yüklendiğinde)
getSurfaces()çağrısını yeni ürünle yineleyin. Yeni ürün yüklenirken önceki ürünü vermeyin; bunun yerineproduct: { pending: true }verin. Ürüne bağlı metni ya da durumu olan yüzey ürün gelene kadar döndürülmez; önce temel içerik gösterilip ürün gelince değiştirilmez. Diğer yüzeyler bundan etkilenmez. - Aynı ürün ürün koşullarını da yanıtlar: bir durumda ya da hedeflemede Ürün stoğu, Ürün indirimde, Ürün indirim oranı (%) veya Ürün fiyatı koşulu bu üründen okunur. Ürün verilmeyen bir ekranda bu koşullar eşleşmez: durum atlanır, ürün koşuluyla hedeflenmiş yüzey döndürülmez.
Durumlar ve değerler getSurfaces() çağrıldığı andaki sepete göre seçilir.
Ekranınızdaki kampanyalar sepetten söz ediyorsa onCartChange geldiğinde
getSurfaces() çağrısını yineleyin. Tutarların biçimi için
getSurfaces(url, { locale: 'tr-TR' }) ile görüntüleyenin dilini
verebilirsiniz; verilmezse cihazın dili kullanılır.
SDK, yapılandırma isteğinde hangi değerleri doldurabildiğini ve hangi koşulları tanıdığını sunucuya bildirir. Eski bir SDK sürümü bunu bildirmez ya da daha azını bildirir, ve sunucu ona dolduramayacağı değerleri ya da tanımadığı koşulları içeren kampanyaları hiç göndermez: sepet değerlerini tanıyan ama ürün değerlerini tanımayan bir sürüm yalnızca ürün değeri kullanan kampanyaları almaz; ürün koşullarını tanımayan bir sürüm ürün koşulu taşıyan kampanyaları almaz, çünkü tanımadığı kuralı yok sayıp kampanyayı daha geniş bir kitleye gösterirdi. SDK aynı bildirimi deney atamalarını isterken de yapar; bir kolunun söylediğini ya da sorduğunu tanımayan sürüm o denemeye hiç alınmaz. Böylece eski bir uygulama sürümü de süslü parantez basmaz.
Akinon App Maker eklentisi ürünü ProductDetail ekranında uygulamanın kendi
ürün durumundan otomatik verir; ürün yüklenirken { pending: true } verir,
önceki ürünü hiçbir zaman vermez.
Sepet
Sepet uygulamanızın içinde yaşar, bu yüzden SDK'ya onu siz bildirirsiniz. Sepet her değiştiğinde ve uygulama açılıp sepet yüklendiğinde çağırın:
selwise.setCart({
total: 379.8, // indirimler düşülmüş ürün toplamı, kargo hariç
itemCount: 3, // sepetteki ürün adedi
currency: 'TRY', // isteğe bağlı; yoksa kanalın para birimi
codes: ['4055'], // isteğe bağlı; sepet satırlarının ürün kodları
});
selwise.getCart(); // { known: true, total: 379.8, itemCount: 3, currency: 'TRY' }
const stop = selwise.onCartChange((cart) => {
// hedef çubuğunu yeniden çözün, sepetten söz eden ekranlarda getSurfaces() çağırın
});
-
Tutar her seferinde sepetin tamamıdır, değişen satır değil. Kargo ve hediye paketi gibi ücretler dahil edilmez, çünkü ücretsiz kargo eşiği ürün toplamına göre yazılır. Sayısal bir metin de kabul edilir (
'379.80'). -
Bildirilmemiş sepet bilinmeyen sepettir. Uygulama her açılışta bilinmeyen bir sepetle başlar; sepet diske yazılmaz. Önceki açılıştan kalan bir tutar başka bir cihazda değişmiş olabilir, ve yanlış bir tutar hiç tutar olmamasından kötüdür.
-
Sepet artık bilinmiyorsa (sipariş sonrası temizlendi, ziyaretçi çıkış yaptı)
setCart(null)çağırın. Sepet olmayan bir değer (negatif ya da sayısal olmayan tutar) reddedilir,falsedöner ve sepeti bilinmeyen yapar. -
Bildirilen sepet hedeflemede de kullanılır:
behaviorgeçmediğinizgetSurfaces()çağrılarında Sepet tutarı ve Sepetteki ürün adedi kuralları bu sepetle değerlendirilir. Kendibehaviordeğerinizi geçerseniz sizin verdiğiniz sinyaller önceliklidir; SDK yalnızca vermediğiniz sepet sinyallerini doldurur. -
codesisteğe bağlıdır: sepet satırlarının ürün kodları (ürün kodu, SKU ya da sepet kodu). Yalnızca Kargo Bedavaya Tamamla şeridine gönderilir ve sepetteki ürünlerin o şeritte önerilmemesini sağlar; sepetin ölçülmüş sayılıp sayılmamasını etkilemez. Tutar aynı kalıp bir satır başka bir ürünle değişirse bu da sepet değişikliği sayılır veonCartChangeçağrılır.
Akinon App Maker eklentisi bunu uygulamanın kendi sepetinden otomatik yapar.
Hedef çubuğu
goal_bar tipindeki bir yüzeyin ne söyleyeceğini resolveGoalBar verir.
Web widget'ı ve paneldeki önizleme de aynı hesaplamayı kullanır, yani aynı
sepet her kanalda aynı cümleyi okur. Her onCartChange geldiğinde yeniden
çözün ve döneni çizin:
const view = selwise.resolveGoalBar(surface, { locale: 'tr-TR' });
if (view.visible) {
// view.text — "Ücretsiz kargo için 401 TL kaldı"
// view.buttonText / view.buttonUrl — duruma göre değişen buton
// view.progress.percent — çubuğun doluluğu, 0–100
// view.progress.markers — ara adımların çubuk üzerindeki yeri
}
visible: falseise hiçbir şey çizmeyin ve gösterim yazmayın. Sepet bilinmiyorsa, boş sepette çubuğun gösterilmesi istenmemişse ya da cümledeki bir değer söylenemiyorsa durum budur.- Gösterimi (
trackSurfaceView) görünür bir durum ilk kez çizildiğinde yazın, yüzey listeye girdiğinde değil. - Butonun metni ve adresi duruma göre değişir; tıklamada
surface.contentdeğilview.buttonUrlkullanın.
Hedefe ulaşma
goal_reached, sepetin bir adımı çubuk ekrandayken geçtiği anlamına gelir.
Ekranda ne olduğunu yalnızca uygulama bildiği için bu olayı siz bildirirsiniz;
kural web ile aynıdır:
import { goalStepsCrossed } from '@selwise/react-native';
// Aynı çubuğun bir önceki ve yeni görünümü:
for (const step of goalStepsCrossed(previousView, nextView)) {
selwise.trackGoalReached(surface, { step });
}
- Yalnızca önceki görünüm görünürken geçilen adımlar sayılır. Çubuk ilk kez göründüğünde zaten geçilmiş bir adım ve çubuk gizliyken geçilen bir adım bildirilmez. Yeni görünümün görünür olması gerekmez: hedefe ulaşınca kaybolan bir çubuğun son adımı da ekranda geçilmiştir.
- Çubuk ekrandan çıktığında (başka bir ekran, kapatma) önceki görünümü unutun; geri dönüldüğünde karşılaştırma sıfırdan başlar.
- SDK her adımı oturum başına bir kez gönderir; uygulama yeniden açılsa da
aynı oturumda tekrar göndermez.
trackGoalReachedgönderip göndermediğini döndürür. getSurfaces()sonucundaki yüzeyi geçerseniz{ step }yeterlidir; eşik ve ölçüt çubuğun içeriğinden okunur. Yalnızca kimliği tuttuysanızthresholdvemetricdeğerlerini de geçin.- Hedefe ulaşma bir tıklama değildir ve ciro kredisi almaz.
Geri sayım: günlük kesim saati
Geri sayım sayacı sabit bir bitiş tarihine ya da günlük kesim saatine
("14:00'e kadar verilen siparişler bugün kargoda") sayabilir. Kesim saati
mağazanın saat dilimindedir ve geçtiğinde ertesi günün aynı saatine döner.
Hedef anı countdownTarget verir; her saniye yeniden sorun, bir kez okuyup
saklamayın:
import { countdownTarget } from '@selwise/react-native';
const target = countdownTarget(surface.content, Date.now()); // epoch ms ya da null
null dönerse sayacı çizmeyin. Akinon App Maker eklentisi bunu her saniye
yapar.
Marka teması
Panelde tanımladığınız marka teması uygulamaya da gelir. Bu kozmetik bir
ayrıntı değil: widget stil varsayılanları var(--selwise-brand, …)
biçimindedir, yani hiçbir rengi elle değiştirmemiş bir merchant bile bu
referansları gönderir. Eklenti bunları çözer; tema tanımlı değilse
referansın içindeki yedek değer kullanılır — web'de olduğu gibi.
Kendi bileşenlerinizi boyamak isterseniz tokenlara doğrudan erişebilirsiniz:
const tokens = selwise.getTheme();
// { '--selwise-brand': '#d3145a', '--selwise-brand-text': '#ffffff', ... }
Panelden gelen takip ayarları
Panelin Takip Ayarları ekranındaki değerler uygulamada da uygulanır: yığın boyutu, gönderim aralığı, çevrimdışı kalıcılık, yeniden deneme sayısı ve kuyruk sınırı.
init() çağrısında açıkça geçtiğiniz bir seçenek panelden gelene göre
önceliklidir — uygulama, panelin bilemeyeceği şeyleri bilir. Panelden gelen
hata ayıklama modu yalnızca açabilir: kendi isteğiyle log açmış bir
uygulamayı susturmaz.
Custom widget: kendi HTML/CSS/JS'iniz
custom tipindeki bir widget uygulamada izole bir WebView içinde çalışır.
İçeriği panelin HTML alanından, stilini ve kodunu ise hem içerik bloğundan hem
de panelin Özel CSS / Özel JS alanlarından okur.
WebView içindeki kodunuza bir köprü açılır:
selwise.track('kupon_kullanildi', { code: 'KIKOAPP20' });
selwise.addToCart('4711', 1);
selwise.navigate('/baskets/basket/');
selwise.close();
addToCart uygulamanın kendi sepet aksiyonunu tetikler, doğrudan istek
atmaz: WebView'in mağaza oturumu yoktur, oradan eklenen ürün ziyaretçinin
görmediği bir sepete düşerdi. Sepet ikonundaki sayı da bu sayede güncellenir.
selwise.track ile gönderdiğiniz isim custom_event olarak kaydedilir ve
verdiğiniz ad üstverisinde saklanır.
Yüksekliği ölçmeniz gerekmez; belge kendi boyunu bildirir ve WebView ona göre büyür.
Arama yönlendirmeleri
Panelde tanımlı bir arama yönlendirmesi (kargo → kargo sayfası) uygulamada da
çalışır: eklenti sonuç listesi yerine hedefe götürür. Bu bir cevaptır,
başarısız arama değildir — bu yüzden sıfır sonuç raporunuza yazılmaz.
Ürün zenginleştirme
Panelde yazdığınız kendi HTML/CSS içeriğiniz uygulamada da çalışır. Tek fark yerleştirmenin nasıl söylendiği: webde bir CSS seçicisi verirsiniz, uygulamada bir yuva adı.
<SelwiseEnrichment plugin={Selwise} code={product.sku} slot="pdp-specs" />
Panelde kurala pdp-specs adını verdiğinizde içerik bu ekranda görünür. Kuralı
sonradan değiştirmeniz, silmeniz veya yenisini eklemeniz için uygulamada
hiçbir şey yapılması gerekmez — yeni sürüm de, yapılandırma da, dağıtım da.
Bu, zenginleştirmenin tamamen dinamik kalmasını sağlayan şey.
Hangi yuva adlarının tanımlı olduğunu SDK söyler:
selwise.getEnrichmentSlots();
// ['basket-shipping', 'pdp-specs']
Markup uygulamaya nasıl geliyor
Webde widget ham blokları ve bir token haritası alır, yorumlamayı ve CSS kapsamlamasını kendisi yapar — çünkü içeriği merchant'ın kendi sayfasına yerleştirir ve oradaki stillerden korunması gerekir.
Uygulamada bu gerekmez: içerik izole bir WebView'de çizilir. Bu yüzden yorumlama, temizleme (sanitize) ve CSS kapsamlaması sunucuda yapılır ve uygulamaya bitmiş markup gelir. Alternatif, bir CSS temizleyicisinin kopyasını React Native paketinin içinde taşımak olurdu — ayrışması en pahalı kod türü.
Sonuç olarak panelde onayladığınız şey ekranda görünen şeydir; iki yol aynı
prepareEnrichmentBlock ve aynı DOMPurify geçişini kullanır.
Token'lar ve kendi feed alanlarınız
Webdekiyle birebir aynı: ${title}, ${brand}, ${formattedPrice},
${imageUrl} ve besleme dosyanızın kendi alanları için ${attr.gtin},
${attr.garanti_suresi} gibi. Kanalınız kataloğu başka bir kanaldan ödünç
alıyorsa (uygulama kanallarında olağan durum) token'lar o katalogdan çözülür.
Bir yuvada birden fazla kural
Bir yuvaya birkaç kural yığılabilir — künye tablosu, altında SSS, altında kargo notu. Hepsi tek WebView içinde çizilir, ama her kural kendi kökünü korur: gösterim kural başına bir kez raporlanır, kaç blok yığdığından bağımsız olarak. Bir bağlantıya dokunulduğunda tıklama, o bağlantıyı içeren kurala atfedilir.
Segment ve test modu
Kampanya ve widget'larla aynı: segment hedeflemesi ve test modu istemcide uygulanır. Bu, bir ürün için verilen cevabın tüm ziyaretçiler için önbelleklenebilmesini sağlayan şey.
Uygulamada geçerli olmayan tek ayar
Sunucu tarafı render (SSR). Webde bir kuralı merchant'ın kendi sunucusunun
çizmesini seçebilirsiniz; amacı JavaScript çalıştırmayan istemcilerdir —
GPTBot, ClaudeBot, bağlantı önizleme botları. Bir uygulamayı hiçbir tarayıcı
tarama yapmaz, dolayısıyla bu seçeneğin uygulamada bir karşılığı yoktur.
Uygulama kanalında panel bu seçeneği hiç göstermez ve renderMode değeri
uygulamadaki görünürlüğü etkilemez: SEO için server işaretlediğiniz bir kural
uygulamada da görünür.
Sırada ne var
Son güncelleme: 9 Ekim 2026