# npm, Önbellek ve CSP

Script yerine npm paketi, dağıtılan dosyaların önbelleği, CSP ve service worker
Kaynak: https://selwise.com/docs/integration/advanced-installation

Script etiketiyle kurulumun ötesindeki dört konu: script yerine npm paketi, Selwise'ın dağıttığı dosyaların önbellek davranışı, tarayıcı bildirimleri için service worker ve içerik güvenlik politikası (CSP) olan siteler. Standart kurulum için [Widget Kurulumu](/docs/integration/widget-installation).

## npm paketi

Etiket ekleyemediğiniz ya da çalışma zamanının yaşam döngüsünü uygulama kabuğunun yönetmesini istediğiniz durumlarda (Next.js uygulamaları, SPA kabukları) `@selwise/widget` paketini kullanın:

```bash
npm install @selwise/widget
```

```ts
import Selwise from '@selwise/widget';

const widget = new Selwise();
await widget.init({
  siteKey: 'SITE_KEY',
  apiUrl: 'https://api.selwise.com/api/v1', // isteğe bağlı
  exposeGlobal: true,                       // window.Selwise'ı da kur
});
```

| Seçenek | Tür | Varsayılan | Açıklama |
| --- | --- | --- | --- |
| `siteKey` | `string` | yok | Zorunlu. Boşsa `init()` hiçbir şey yapmaz |
| `apiUrl` | `string` | `https://api.selwise.com/api/v1` | `/api/v1` eksikse eklenir. Ortamda `NEXT_PUBLIC_API_URL` tanımlıysa o **sizin verdiğinizi geçersiz kılar**: yanlışlıkla tanımlı bir değişken istekleri başka bir ana bilgisayara yönlendirir |
| `exposeGlobal` | `boolean` | `false` | `true` ise örneği `window.Selwise`'a atar; `destroy()` onu temizler. Kuyruğa alınmış çağrılar (komut kuyruğu) yalnızca bu seçenekle oynatılır |
| `locale` | `string` | `<html lang>` | Widget'ın konuşacağı dil (`en`, `en-GB`). Hesapta açık değilse hesabın varsayılan dili kullanılır. Bkz. [Dil](/docs/integration/javascript-api#dil) |

- **Tarayıcıda çalışır.** `init()` gerçek bir DOM ister; SSR sırasında çağrılırsa konsola `init() must be called in a browser environment` yazar ve hiçbir şey yapmaz. Modülü içe aktarmak her yerde güvenlidir. Next.js'te `init()`'i bir istemci bileşeninde `useEffect` içinde çağırın.
- **Uygulama kabuğu başına tek örnek.** İki canlı örnek çift olay ve çift çizim demektir. Bir `Selwise` örneği oluşturup paylaşın, kabuk kapanırken `destroy()` çağırın.
- Paket CDN sürümünden farklı olarak **tek bir modül** olarak gelir (arama, öneri, çizici parçaları birleşik, gzip ~130 KB); CDN sürümü yalnızca kullanılan parçaları ayrıca indirir. Sayfa performansı öncelikse CDN'i seçin.
- Çıktı tipleri paketle gelir (`WidgetConfig`, `ConsentState`, `TrackArgs`, `SelwiseDataLayer`); ek olarak `resolveApiUrl(input?)` dışa aktarılır.

Tam yöntem listesi: [JavaScript API](/docs/integration/javascript-api). Mobil uygulamada bu paket değil, [Mobil SDK](/docs/mobile/overview) kullanılır.

## Dağıtılan dosyalar ve önbellek

CDN'de (`https://widget.selwise.com`) yalnızca `client.js` etiketini eklersiniz; geri kalanını widget gerektiğinde ve **gereken özellik açıksa** kendisi yükler. Parça adları içerik özetiyle birlikte (`selwise-search.1a2b3c4d.js`) yayınlanır.

| Dosya (parça) | Ne zaman yüklenir |
| --- | --- |
| `client.js` | Her zaman; ana giriş (gzip 50 KB bütçeli, bugün yaklaşık 25 KB) |
| `selwise-policies` | Deney, segment, sıklık sınırı ve çakışma çözümü (sayfa çizildikten sonra) |
| `selwise-renderers` | Kampanya şablonları gerektiğinde |
| `selwise-consent` | Çerez onayı banner'ı gerektiğinde |
| `selwise-datalayer`, `selwise-batcher`, `selwise-cart` | Veri katmanı köprüsü, olay toplama, mağaza sepetinin okunması |
| `selwise-search`, `selwise-reco` | Arama ya da öneri modülü açıkken |
| `selwise-enrichment`, `selwise-onsite`, `selwise-tabtalk`, `selwise-scenarios`, `selwise-push` | Yalnızca o özellik kanalda etkinse |
| `selwise-vendor`, `selwise-sanitize-css`, `selwise-sentry` | Parçalar arası paylaşılan kütüphane (HTML temizleyici dahil), CSS temizleyici, hata raporlama |
| `selwise-editor` | Yalnızca panelden açılan görsel editör oturumunda; alışverişçi indirmez |
| `selwise-sw.js` | Tarayıcı bildirimi için hizmet çalışanı; **sizin alan adınızın kökünden** sunulur, aşağıya bakın |

**Neyin ne kadar önbelleğe alındığı:**

| Dosya | Önbellek | Anlamı |
| --- | --- | --- |
| `client.js` | 5 dakika (`max-age=300`, `stale-while-revalidate=60`) | Adı hiç değişmez; yeni sürüm en geç birkaç dakikada ulaşır. Tarayıcıya giden değer, CDN'in ayarlarına göre daha uzun olabilir |
| Özetli parçalar (`ad.1a2b3c4d.js`) | 1 yıl, `immutable` | Dosya adı içeriğiyle değişir |
| `/v1/...` yolundaki her dosya | 1 yıl, `immutable` | Aşağıya bakın |
| Diğer dosyalar | 1 saat | `selwise-sw.js` dahil |

`/v1/client.js` adresi de vardır ve uzun önbelleğe alınır, ama bu bir sürüm **sabitleme** değildir: yeni sürümler aynı yola yayınlanır; yalnızca tarayıcı bir yıl boyunca yeniden sormaz. Bir parça adı değiştiğinde eski bir `client.js`'in istediği eski parça artık sunulmayabilir. Standart `/client.js` yolunu kullanın.

CDN dosyalarına `robots.txt` ile indekslemeye kapalıdır ve her kaynağa CORS yanıtı verilir (`crossorigin` öznitelikli bir `<link>` ya da `<script>` sorunsuz çalışır).

## Web bildirimi için service worker

Kanalda tarayıcı bildirimi (web push) kullanıyorsanız `selwise-sw.js` dosyasını **alan adınızın kökünden** (`https://magaza.com/selwise-sw.js`) sunmanız gerekir. Bir hizmet çalışanının kapsamı sunulduğu klasörden geniş olamaz ve bildirim her sayfada çalışmalıdır; bu yüzden CDN'imizden sunmak işe yaramaz (hizmet çalışanı bizim alan adımıza kaydolurdu). Dosyayı panelde **Ayarlar → Mesajlaşma Sağlayıcıları** (Settings → Messaging Providers) ekranındaki web bildirimi bölümündeki **Download selwise-sw.js** bağlantısından ya da `https://widget.selwise.com/selwise-sw.js` adresinden indirin. Dosya yalnızca iki iş yapar: bildirimi çizer ve tıklanınca bağlantıyı açar. `fetch` olaylarını **yakalamaz**, yani sitenizin önbelleğine ya da çevrimdışı davranışına dokunmaz.

İzin istemi hiçbir zaman sayfa yüklenirken çıkmaz; tarayıcılar bir siteye ömür boyu tek istem hakkı tanır. İstemi bir düğmeden çağırmak için `Selwise.requestPushPermission()` kullanılır, bkz. [JavaScript API](/docs/integration/javascript-api#bildirim-izni).

## CSP ve içerik güvenlik politikası

Siteniz bir `Content-Security-Policy` yayınlıyorsa widget'ın çalışması için şu kaynaklara izin vermeniz gerekir. Kodda ulaşılan alan adları yalnızca bunlardır:

| Yönerge | Gereken | Neden |
| --- | --- | --- |
| `script-src` | `https://widget.selwise.com` | `client.js` ve tüm tembel parçalar aynı kökten yüklenir |
| `connect-src` | `https://api.selwise.com` | Bütün API çağrıları (`fetch`, `sendBeacon`): yapılandırma, olaylar, sipariş, arama, öneri |
| `img-src` | Görsellerinizin ve ürün görsellerinizin ana bilgisayarları, `https://api.selwise.com` | Kampanya ve kart görselleri; panelden yüklenen görseller `api.selwise.com/api/v1/public/media/...` adresinden gelir |
| `style-src` | `'unsafe-inline'` | Widget `style` öğeleri ve satır içi `style` nitelikleri ekler (kampanya stilleri, zenginleştirme CSS'i) |
| `worker-src` | `'self'` | Yalnızca web bildirimi kullanıyorsanız: `/selwise-sw.js` kök hizmet çalışanı |

Ek olarak bazı özellikler satır içi kod gerektirir; **yalnızca onları kullanıyorsanız** izin verin:

| Özellik | Gereken | Neden |
| --- | --- | --- |
| Komut kuyruğu ve sipariş takibi snippet'i | `script-src` için `'unsafe-inline'` ya da bir `nonce`/hash | Sizin sayfanızdaki satır içi script'ler |
| [Özel Script'ler](/docs/custom-scripts/overview) | `script-src` için `'unsafe-inline'` | Widget bu script'leri sayfaya satır içi `script` öğesi olarak ekler; nonce taşıyamaz |
| Kampanya, öneri ya da ürün kartı **özel JavaScript** alanı ve özel sepete ekleme betiği | `script-src` için `'unsafe-eval'` | Bu alanlar `new Function` ile çalıştırılır |

Kullandığınız modüllere bakarak en dar kümeyi seçin: özel script ve özel JavaScript kullanmıyorsanız yalnızca ilk beş satır yeter. Bir politika ihlali tarayıcı konsolunda `Refused to load/connect ...` olarak görünür (bkz. [Takip Sorunları](/docs/troubleshooting/tracking-issues)).

Önerilen yöntem: **önce `Report-Only` modunda deneyin.** `Content-Security-Policy-Report-Only` ile bir hafta raporlama toplayın, widget'ın ihlal üretmediğini doğrulayın, sonra uygulayın.
