# JavaScript API

> Script'in window.Sayproof arayüzü, seçenekleri, event'leri ve kullanım örnekleri.

Kaynak: /tr/reference/javascript-api/

Script yüklendiğinde `window.Sayproof` nesnesini oluşturur, sayfadaki container'ları bulur ve sayfadaki değişiklikleri izlemeye başlar. Çoğu sitede bu arayüzü kullanmak gerekmez: container'ı eklemek, kaldırmak ya da attribute'larını değiştirmek yeterlidir. Bileşeni kodla yönetmeniz gerektiğinde aşağıdaki metotlar kullanılır.

## Script'in hazır olmasını beklemek

Script bir modül olarak yüklenir ve sizin kodunuz ondan önce çalışabilir. `window.Sayproof` henüz tanımlı değilse `sayproof:ready` event'ini bekleyin:

```js
function whenSayproofReady(callback) {
  if (window.Sayproof) callback(window.Sayproof);
  else window.addEventListener("sayproof:ready", () => callback(window.Sayproof), { once: true });
}
```

Bu sayfadaki örnekler bu yardımcı fonksiyonu kullanır.

## Metotlar

| Metot | İşlevi |
|---|---|
| `mount(container, options?)` | Container'a bileşeni bağlar. `options` değerleri container'ın attribute'larından önceliklidir. Container zaten bağlıysa bileşeni yeni seçeneklerle günceller. |
| `update(container, options)` | Yeni seçenekleri önceki seçeneklerle birleştirir ve bileşeni günceller. Oturum açmış müşterinin durumunu iletmek için de kullanılır. |
| `unmount(container)` | Bileşeni container'dan kaldırır. |
| `scan()` | Sayfayı yeniden tarar: yeni container'ları ve `data-review-order` öğelerini bağlar, sayfadan kaldırılanları temizler. |
| `write(container)` | Yorum yazma akışını açar. Akış açıldıysa `true`, açılmadıysa `false` döndürür. |
| `mountOrder(element, answer?)` | Sipariş detayındaki değerlendirme bölümünü öğeye kurar. `answer`, sunucunuzun `GET /v1/viewer/order` isteğine aldığı yanıttır; verilmezse öğenin içindeki `data-review-order-state` etiketi okunur. Aynı öğede yeniden çağrıldığında bölüm yeni yanıtla yeniden kurulur. |
| `version` | Sözleşme sürümü (`"3"`) |

:::caution[Öncelik sırası]
`mount` ya da `update` ile verilen bir seçenek, aynı alanın attribute değerinden önceliklidir ve metotlar yeniden kullanıldığında da korunur. Bir alanı (örneğin ürün kodunu) ya yalnızca attribute ile ya da yalnızca bu metotlarla yönetin; ikisini birlikte kullanırsanız attribute değişiklikleri etkisiz kalır.
:::

### Seçenekler

| Seçenek | Karşılık gelen attribute |
|---|---|
| `product` | `data-review-product` |
| `scope` | `data-review-scope` (`"variant"` ya da `"group"`) |
| `productName` | `data-review-product-name` |
| `locale` | `data-review-locale`. Hiçbir yerde verilmezse `<html lang>`, o da yoksa kanalın dili kullanılır. |
| `layout` | `data-review-layout` (`"list"` ya da `"grid"`) |
| `style` | `data-review-style` (`"cards"` ya da `"sidebar"`). Hiçbir yerde verilmezse kanalın panelde seçilen düzeni kullanılır. |
| `theme` | `data-review-theme` (`"warm"`, `"trust"`, `"editorial"`, `"minimal"`, `"soft"`, `"bold"`, `"natural"` ya da `"night"`). Hiçbir yerde verilmezse ya da tanınmayan bir değer verilirse kanalın panelde seçilen tasarımı kullanılır. |
| `mode` | `data-review-mode` (`"default"` ya da `"headless"`) |
| `gate` | `data-review-gate` |
| `siteKey` | `data-review-site-key` |
| `base` | `data-review-base` |
| `nonce` | Stil etiketlerine eklenecek nonce değeri |
| `viewer` | Oturum açmış müşterinin durumu: `{ state, token, products, reviews, limits, asker }`, `"pending"` ya da `null` |

### `write` metodunun `false` döndürdüğü durumlar

- Container hazır değilse (`data-review-ready` attribute'u yoksa).
- Sayfada açık ya da açılmakta olan bir dialog varsa.
- Oturum açmış müşteri bu ürün için daha önce yorum yazmışsa (`written`).
- Oturum açmış müşterinin durumu hâlâ bekleniyorsa (`data-review-viewer="pending"`).

Diğer durumlarda müşteri yorum yazabiliyorsa yorum formu, aksi hâlde önce sipariş doğrulaması açılır; doğrulama başarılı olursa aynı dialog içinde forma geçilir. Form, sipariş sunucuda doğrulanmadan hiçbir zaman açılmaz.

## Event'ler

| Event | Yayıldığı öğe | Zamanı |
|---|---|---|
| `sayproof:ready` | `window` | Script yüklendi; `window.Sayproof` kullanılabilir |
| `sayproof:submitted` | Container; sipariş detayında `data-review-order` öğesi (bubbling) | Yorum başarıyla gönderildi. Ürün sayfasında `event.detail.product` ürün kodunu; sipariş detayında `event.detail.order` sipariş numarasını, `event.detail.line` sipariş satırının kimliğini içerir. Sipariş detayında her ürün ayrı gönderildiği için event her ürün için ayrı yayılır. |

Gönderilen yorum onaylandıktan sonra yayınlanır; bu nedenle `sayproof:submitted` event'inde listeyi hemen yenilemeniz gerekmez.

## Davet bağlantıları

Davet bağlantısı token'ı adresin `#` işaretinden sonraki bölümünde taşır (`#review_token=…`); script eski davetlerdeki `?review_token=…` parametresini de okur. Script yüklenir yüklenmez bu değeri alır ve adres çubuğundan siler. `#` sonrasındaki bölüm sunuculara gönderilmez ve analiz araçlarının kaydettiği sayfa adresine (`page_location` gibi) girmez. Form, davetteki ürünü gösteren container'da, böyle bir container yoksa sayfadaki ilk container'da açılır. Bağlantı geçersizse ya da süresi dolmuşsa yorum yazma alanında açıklayıcı bir mesaj gösterilir.

## Sayfa değişikliklerinin izlenmesi

Script sayfadaki değişiklikleri kendisi algılar:

- `data-review-mount` attribute'unu taşıyan bir öğe sayfaya eklendiğinde bileşeni bağlar, kaldırıldığında temizler.
- Container'ın yapılandırma attribute'larından biri değiştiğinde (örneğin varyant seçimi) bileşeni günceller.
- Container'ın içine sunucudan yeni HTML geldiğinde (örneğin React'in container'ı yeniden oluşturması) bu içeriği devralır.
- `data-review-order` öğesi sayfaya eklendiğinde sipariş detayındaki değerlendirme bölümünü kurar.

Ürün değişirken eski içerik, yeni içerik yüklenene kadar etkileşime kapatılır (`inert`). Yeni yükleme başarısız olursa container'a `data-review-failed` attribute'u eklenir.

## Örnekler

### Bileşeni kodla bağlamak

Seçenekleri attribute yerine kodla vermek için:

```html
<div id="reviews" data-review-mount></div>

<script type="module">
  whenSayproofReady((sayproof) => {
    sayproof.mount(document.querySelector("#reviews"), {
      product: "URUN-38",
      scope: "variant",
      locale: "tr",
      layout: "list",
      style: "sidebar",
      theme: "trust",
    });
  });
</script>
```

Site anahtarı ve API adresi script etiketindeki `data-review-site-key` ve `data-review-base` değerlerinden alınır. Container'daki `data-review-mount` attribute'u, script'in container'ı izleyebilmesi ve davet bağlantılarının bu container'da açılabilmesi için gereklidir. Örneklerde `whenSayproofReady` fonksiyonunun sayfada tanımlı olduğu varsayılmıştır.

### Ürünü kodla değiştirmek

```js
const container = document.querySelector("#reviews");

document.querySelector("#size").addEventListener("change", (event) => {
  whenSayproofReady((sayproof) => sayproof.update(container, { product: event.target.value }));
});
```

### Tek sayfalı uygulamalarda (SPA) bağlama ve kaldırma

Container sayfaya eklendiğinde ve kaldırıldığında script bunu kendisi algılar. Bileşenin yaşam döngüsünü kodla yönetmek isterseniz React'te:

```tsx
import { useEffect, useRef } from "react";

export function Reviews({ product, locale }: { product: string; locale: string }) {
  const container = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const element = container.current;
    if (!element) return;
    whenSayproofReady((sayproof) => sayproof.mount(element, { product, locale }));
    return () => window.Sayproof?.unmount(element);
  }, [product, locale]);

  return <div ref={container} data-review-mount />;
}
```

Vue'da:

```vue
<script setup>
import { onBeforeUnmount, onMounted, ref, watch } from "vue";

const props = defineProps({ product: String, locale: String });
const container = ref(null);

onMounted(() => {
  whenSayproofReady((sayproof) => sayproof.mount(container.value, { product: props.product, locale: props.locale }));
});

watch(
  () => [props.product, props.locale],
  ([product, locale]) => window.Sayproof?.update(container.value, { product, locale })
);

onBeforeUnmount(() => window.Sayproof?.unmount(container.value));
</script>

<template>
  <div ref="container" data-review-mount />
</template>
```

### Sayfayı hemen yeniden taramak

Script değişiklikleri kendisi algıladığı için `scan()` genellikle gerekmez. Sayfanın büyük bir bölümünü değiştirdikten hemen sonra bağlama işleminin tamamlanmasını istiyorsanız kullanabilirsiniz:

```js
document.querySelector("#product-detail").innerHTML = html;
window.Sayproof?.scan();
```

### Kendi "Yorum yaz" düğmeniz

```js
const container = document.querySelector("#reviews");

document.querySelector("#write-review").addEventListener("click", () => {
  const opened = window.Sayproof?.write(container) ?? false;
  if (!opened) container.scrollIntoView({ behavior: "smooth", block: "start" });
});
```

### Gönderimi analiz aracınıza iletmek

```js
document.addEventListener("sayproof:submitted", (event) => {
  window.dataLayer?.push({ event: "review_submitted", product: event.detail.product });
});
```

### Oturum açmış müşterinin durumunu iletmek

```js
const container = document.querySelector("#reviews");

fetch(`/api/sayproof/viewer?product=${encodeURIComponent(container.dataset.reviewProduct)}`, { credentials: "same-origin" })
  .then((answer) => (answer.ok ? answer.json() : { state: "anonymous" }))
  .catch(() => ({ state: "anonymous" }))
  .then((viewer) => whenSayproofReady((sayproof) => sayproof.update(container, { viewer })));
```

Sunucu tarafı ve yanıt değerleri için: [Oturum açmış müşteri](/tr/integrate/signed-in-customers.md).

### Sipariş detayı yanıtını kodla vermek

Sipariş detayı sayfası tarayıcıda oluşturuluyorsa yanıtı kendi endpoint'inizden alıp `mountOrder` ile verin. Yanıtta ürün yoksa bölümü kurmayın:

```js
const element = document.querySelector("[data-review-order]");

fetch(`/api/sayproof/order?order=${encodeURIComponent(element.dataset.reviewOrder)}`, { credentials: "same-origin" })
  .then((answer) => (answer.ok ? answer.json() : null))
  .catch(() => null)
  .then((order) => {
    if (order?.lines?.length) whenSayproofReady((sayproof) => sayproof.mountOrder(element, order));
  });
```

`/api/sayproof/order`, oturumdaki e-posta adresiyle Sayproof'a soran kendi sunucu endpoint'inizdir: [Oturum açmış müşteri › Sipariş detayı sayfası](/tr/integrate/signed-in-customers.md#siparis-detayi-sayfasi).
