> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Buton odaklı onboarding karuseli oluşturma

> Buton navigasyonu ve otomatik kapatma özellikli HTML Uygulama İçi Mesajlar kullanarak çok adımlı bir onboarding akışı oluşturun.

## Genel Bakış

Bu eğitim, tek bir HTML Uygulama İçi Mesaj kullanarak **çok adımlı bir onboarding karuseli** oluşturmayı gösterir. Kaydırma hareketlerine dayanan geleneksel karusellerin aksine, bu yaklaşım **buton odaklı navigasyon** kullanır ve tüm adımları tek bir mesaj içinde tutar.

**Ne inşa edeceksiniz:**

* Görsel, metin ve butonlar içeren iki adımlı bir onboarding akışı
* Buton navigasyonu (ilerlemek için "İleri"ye, kapatmak için "Başla"ya dokunun)
* İlerleme gösterge noktaları
* Adımlar arası yumuşak geçiş efektleri

<Frame caption="Buton odaklı navigasyonlu onboarding karuseli örneği">
  <img src="https://mintcdn.com/onesignal/t_Vr4vLAhranGx-O/images/docs/onboarding-carousel-demo.gif?s=39418d8af9896323694f46f9cb6eebec" alt="Görsel, metin ve İleri butonu içeren karşılama ekranını gösteren onboarding karuseli" style={{width: '200px', maxWidth: '100%'}} width="768" height="1660" data-path="images/docs/onboarding-carousel-demo.gif" />
</Frame>

**Bu yaklaşımı ne zaman kullanmalısınız:**

* Kullanıcıları **kısa bir onboarding veya eğitim akışından** (2-5 adım) geçirmek istediğinizde
* Kullanıcıların devam etmek için **açıkça bir butona dokunmasını** gerektirdiğinizde (kaydırma hareketi yok)
* Basitlik için her şeyi **tek bir HTML Uygulama İçi Mesaj** içinde tutmak istediğinizde
* Akış tamamlandığında mesajı otomatik olarak kapatmak istediğinizde

<Info>
  Bu kılavuz tam kontrol için HTML Uygulama İçi Mesaj kullanır. Ayrıca [sürükle-bırak düzenleyiciyle kart tabanlı onboarding akışları oluşturabilirsiniz](./design-your-in-app-message#carousels)—bu kartlar kaydırılabilir ancak daha az özelleştirme sunar.
</Info>

***

## Ön Koşullar

Başlamadan önce, aşağıdakilere sahip olduğunuzdan emin olun:

* Uygulama İçi Mesajlar etkinleştirilmiş aktif bir OneSignal uygulaması
* [HTML Uygulama İçi Mesajları oluşturma veya düzenleme izni](./manage-team-members#team-members)
* Mobil uygulamanızda [Mobile SDK](./mobile-sdk-setup) kurulu
* HTML, CSS ve JavaScript hakkında temel anlayış

***

## Çok Adımlı Akış Nasıl Çalışır

Koda geçmeden önce teknik yaklaşımı anlamak önemlidir. Bu uygulama, birden fazla ayrı mesaj yüklemek yerine **içeriği gösterip gizleyerek** adımlar arasında geçiş yapan **tek bir HTML Uygulama İçi Mesaj** kullanır.

Mimari **dört temel bileşene** dayanır:

<Steps>
  <Step title="Her adım için kart konteynerleri">
    Her adım `card` sınıfı ve benzersiz bir ID ile bir `<div>` içine sarılır:

    ```html theme={null}
    <div id="card-0" class="card active">...</div>
    <div id="card-1" class="card">...</div>
    ```

    * Tüm kartlar DOM'da aynı anda bulunur
    * Aynı anda yalnızca bir kart görünür (`active` sınıfıyla kontrol edilir)
  </Step>

  <Step title="CSS görünürlük kontrolü">
    CSS, opaklık ve pointer olaylarını kullanarak göster/gizle mantığını yönetir:

    ```css theme={null}
    .card {
      opacity: 0;
      pointer-events: none;  /* Gizli kartlarla etkileşimi engeller */
      transition: opacity .25s ease;
    }

    .card.active {
      opacity: 1;
      pointer-events: auto;  /* Görünür kartla etkileşime izin verir */
    }
    ```

    **Bu neden önemli:**

    * `opacity: 0` kartı görsel olarak gizler ancak düzende tutar
    * `pointer-events: none` gizli kartlara yanlışlıkla tıklamayı engeller
    * `transition` yumuşak geçiş efektleri oluşturur
  </Step>

  <Step title="JavaScript durum yönetimi">
    `setActive(i)` fonksiyonu hangi kartın görünür olduğunu kontrol eder:

    ```javascript theme={null}
    function setActive(i) {
      // Kart görünürlüğünü güncelle
      document.getElementById("card-0").className = i === 0 ? "card active" : "card";
      document.getElementById("card-1").className = i === 1 ? "card active" : "card";

      // İlerleme noktalarını güncelle
      var dots = document.getElementById("dots").children;
      dots[0].classList.toggle("active", i === 0);
      dots[1].classList.toggle("active", i === 1);
    }
    ```

    Bu fonksiyon:

    * Tüm kartlardan `active`'i kaldırır
    * Hedef karta `active` ekler
    * İlerleme gösterge noktalarını günceller
  </Step>

  <Step title="Buton olay dinleyicileri">
    Butonlar navigasyonu veya kapatmayı tetikler:

    ```javascript theme={null}
    // Sonraki adıma ilerle
    document.getElementById("next-0").addEventListener("click", function () {
      setActive(1);
    });

    // Uygulama İçi Mesajı kapat
    document.getElementById("done").addEventListener("click", function (e) {
      if (window.OneSignalIamApi && OneSignalIamApi.close) {
        OneSignalIamApi.close(e);
      }
    });
    ```

    **Önemli:** `OneSignalIamApi.close(e)` HTML içinden Uygulama İçi Mesajı kapatan OneSignal SDK yöntemidir.
  </Step>
</Steps>

<Note>
  **Önemli nokta:** Bu, bir Uygulama İçi Mesaj içindeki **tek sayfa uygulama (SPA)** modelidir. Tüm içerik bir kez yüklenir ve JavaScript yeniden yükleme olmadan durum değişikliklerini yönetir.
</Note>

***

## Adım 1: Yeni bir HTML Uygulama İçi Mesaj Oluşturun

1. OneSignal panelinde **Messages → In-App Messages** bölümüne gidin
2. **New In-App Message** öğesine tıklayın
3. Mesaj türü olarak **HTML** seçin
4. **Full Screen** veya **Large** düzeni seçin (görsel etki için onboarding'de önerilir)
5. HTML düzenleyiciye devam edin

<Note>
  HTML düzenleyici önizlemesi çalışma zamanı davranışını tam olarak yansıtmayabilir. Animasyonları, buton davranışını ve kapatma işlemini doğrulamak için her zaman gerçek bir cihazda veya test kullanıcısında test edin.
</Note>

***

## Adım 2: HTML Şablonunu Ekleyin

Düzenleyici içeriğini aşağıdaki şablonla değiştirin. Bu şablon şunları içerir:

* **Bağımsız kod:** Tüm HTML, CSS ve JavaScript tek bir dosyada
* **Buton odaklı navigasyon:** Kaydırma hareketi yok (cihazlar arasında daha güvenilir)
* **Geçiş efektleri:** Adımlar arası yumuşak opaklık değişimleri
* **OneSignal SDK entegrasyonu:** Mesajı kapatmak için `OneSignalIamApi.close(e)` kullanır
* **Mobil optimize:** Viewport meta etiketi ile duyarlı düzen

<Accordion title="Tam HTML şablonunu görüntüle">
  ```html theme={null}
  <!doctype html>
  <html>
  <head>
    <meta charset="UTF-8" />
    <!-- viewport-fit=cover çentikli cihazlarda güvenli alan kapsamını sağlar -->
    <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
    <style>
      /* Temel stiller - sıfırlama ve sistem fontu */
      html, body {
        margin: 0;
        padding: 0;
        background: #ffffff;
        font-family: -apple-system, system-ui;
      }

      /* Dolgulu ana konteyner */
      .wrap {
        padding: 28px 22px 24px;
      }

      /* Sahne konteyneri - tüm kartları aynı konumda tutar */
      .stage {
        position: relative;
        min-height: 74vh;  /* Yeterli dikey alan sağlar */
      }

      /* Kart - onboarding akışının her adımı */
      .card {
        position: absolute;  /* Tüm kartlar aynı konumda üst üste gelir */
        inset: 0;            /* Sahneyi tam kaplar */
        display: flex;
        flex-direction: column;
        align-items: center;
        opacity: 0;               /* Varsayılan olarak gizli */
        pointer-events: none;     /* Gizliyken tıklamayı engeller */
        transition: opacity .25s ease;  /* Yumuşak geçiş efekti */
      }

      /* Aktif kart görünür ve etkileşimli */
      .card.active {
        opacity: 1;
        pointer-events: auto;
      }

      /* Tipografi */
      h1 {
        margin: 44px 0 12px;
        font-size: 26px;
        text-align: center;
      }

      p {
        margin: 0;
        color: #6b7280;
        text-align: center;
        max-width: 260px;
        line-height: 1.35;
      }

      /* Görsel konteyneri - yuvarlatılmış köşeli kare */
      .image {
        width: 240px;
        height: 240px;
        border-radius: 16px;
        margin: 24px 0 12px;
        background-size: cover;
        background-position: center;
      }

      /* Ana buton */
      .btn {
        margin-top: auto;  /* Butonu kartın altına iter */
        width: 100%;
        max-width: 260px;
        height: 52px;
        border: 0;
        border-radius: 12px;
        background: #3b82f6;  /* Mavi - markanıza göre özelleştirin */
        color: #fff;
        font-size: 18px;
        font-weight: 600;
      }

      /* İlerleme gösterge noktaları */
      .dots {
        display: flex;
        justify-content: center;
        gap: 8px;
        padding: 12px 0 8px;
      }

      .dot {
        width: 8px;
        height: 8px;
        border-radius: 999px;
        background: #d1d5db;  /* Pasif nokta rengi */
      }

      .dot.active {
        background: #6b7280;  /* Aktif nokta rengi */
        transform: scale(1.15);  /* Aktifken biraz daha büyük */
      }
    </style>
  </head>

  <body>
    <div class="wrap">
      <div class="stage">

        <!-- ADIM 1: Karşılama kartı ("active" sınıfıyla görünür başlar) -->
        <div id="card-0" class="card active">
          <h1>Hoş Geldiniz</h1>
          <div
            class="image"
            style="background-image: url('https://images.pexels.com/photos/6153129/pexels-photo-6153129.jpeg');">
          </div>
          <p>Dakikalar içinde sakin bir günlük alışkanlık oluşturun.</p>
          <button
            id="next-0"
            class="btn"
            data-onesignal-unique-label="onboarding_next_0">
            İleri
          </button>
        </div>

        <!-- ADIM 2: Nefes kartı (gizli başlar, kullanıcı "İleri"ye dokunduğunda görünür) -->
        <div id="card-1" class="card">
          <h1>Nefes Alın</h1>
          <div
            class="image"
            style="background-image: url('https://images.pexels.com/photos/417173/pexels-photo-417173.jpeg');">
          </div>
          <p>Sıfırlanmaya ihtiyaç duyduğunuzda rehberli nefes egzersizi.</p>
          <button
            id="done"
            class="btn"
            data-onesignal-unique-label="onboarding_done">
            Başla
          </button>
        </div>

      </div>

      <!-- İlerleme göstergesi: 2 nokta, ilki aktif başlar -->
      <div class="dots" id="dots">
        <div class="dot active"></div>
        <div class="dot"></div>
      </div>
    </div>

    <script>
      (function () {
        /**
         * "active" sınıfını değiştirerek kartlar arasında geçiş yap
         * @param {number} i - Gösterilecek kartın indeksi (0 veya 1)
         */
        function setActive(i) {
          // Kart görünürlüğünü güncelle
          document.getElementById("card-0").className = i === 0 ? "card active" : "card";
          document.getElementById("card-1").className = i === 1 ? "card active" : "card";

          // İlerleme noktalarını güncelle
          var dots = document.getElementById("dots").children;
          dots[0].classList.toggle("active", i === 0);
          dots[1].classList.toggle("active", i === 1);
        }

        // Buton: İleri (kart 0 → kart 1)
        document.getElementById("next-0").addEventListener("click", function () {
          setActive(1);
        });

        // Buton: Başla (Uygulama İçi Mesajı kapatır)
        document.getElementById("done").addEventListener("click", function (e) {
          // OneSignal IAM API'sinin kullanılabilir olup olmadığını kontrol et
          if (window.OneSignalIamApi && OneSignalIamApi.close) {
            OneSignalIamApi.close(e);  // Mesajı kapat
          }
        });
      })();
    </script>
  </body>
  </html>
  ```
</Accordion>

***

## Adım 3: İçeriğinizi Özelleştirin

### Güvenle özelleştirilebilir

İşlevselliği bozmadan bu öğeleri değiştirebilirsiniz:

**İçerik:**

* `<h1>` etiketlerindeki başlık metni
* `<p>` etiketlerindeki gövde metni
* Buton etiketleri (`İleri`, `Başla`)
* `background-image: url('...')` stillerindeki görsel URL'leri

**Görsel stil:**

* Renkler: `.btn` arka planını, metin rengini veya nokta renklerini değiştirin
* Boşluk: Padding ve marjları ayarlayın
* Tipografi: font-family, font-size, font-weight değiştirin
* Kenar yarıçapı: Butonlar ve görseller için `border-radius` değerlerini güncelleyin

### Daha fazla adım ekleme

Üçüncü bir adım eklemek için bu kalıbı izleyin:

1. **HTML kartı ekleyin:**

```html theme={null}
<div id="card-2" class="card">
  <h1>Başlığınız</h1>
  <div class="image" style="background-image: url('gorsel-url');"></div>
  <p>Açıklamanız</p>
  <button id="next-2" class="btn">İleri</button>
</div>
```

2. **İlerleme noktası ekleyin:**

```html theme={null}
<div class="dots" id="dots">
  <div class="dot active"></div>
  <div class="dot"></div>
  <div class="dot"></div> <!-- Yeni nokta -->
</div>
```

3. **`setActive()` fonksiyonunu güncelleyin:**

```javascript theme={null}
function setActive(i) {
  document.getElementById("card-0").className = i === 0 ? "card active" : "card";
  document.getElementById("card-1").className = i === 1 ? "card active" : "card";
  document.getElementById("card-2").className = i === 2 ? "card active" : "card"; // Yeni kart

  var dots = document.getElementById("dots").children;
  dots[0].classList.toggle("active", i === 0);
  dots[1].classList.toggle("active", i === 1);
  dots[2].classList.toggle("active", i === 2); // Yeni nokta
}
```

4. **Önceki adımın buton ID'sini güncelleyin:**
   Kart 1'in butonunda `id="done"`'ı `id="next-1"` olarak değiştirin, ardından tıklama dinleyicisi ekleyin:

```javascript theme={null}
document.getElementById("next-1").addEventListener("click", function () {
  setActive(2);
});
```

5. **Yeni son karta (card-2) kapatma butonu ekleyin:**

```javascript theme={null}
document.getElementById("done").addEventListener("click", function (e) {
  if (window.OneSignalIamApi && OneSignalIamApi.close) {
    OneSignalIamApi.close(e);
  }
});
```

<Warning>
  Onboarding akışlarını kısa tutun (maksimum 2-4 adım). Kullanıcılar uzun akışlarda hızla vazgeçer. [Tıklama takibi](./in-app-message-api#click-name) ile tamamlanma oranlarını test edin.
</Warning>

***

## Adım 4: Uygulama İçi Mesajı Test Edin

### Test kontrol listesi

1. OneSignal panelinde mesajı **kaydedin**
2. **Teslimat ayarlarını yapılandırın:**
   * Tetikleme koşullarını ayarlayın (örn., oturum başlangıcı, belirli sayfa görüntüleme)
   * Hedef kitlenizi seçin veya bir test kullanıcısı belirleyin
3. **Test cihazına gönderin:**
   * Üretim kullanıcılarını etkilemeden önizlemek için [Test Kullanıcıları](./test-users) kullanın
   * Uygulamanızı fiziksel bir cihaza yükleyin (doğru davranış için simülatörler yerine önerilir)
4. **İşlevselliği doğrulayın:**
   * ✓ İlk kart doğru içerikle görünüyor
   * ✓ "İleri" butonu kart 2'ye ilerliyor
   * ✓ İlerleme noktaları doğru güncelleniyor
   * ✓ Geçiş efektleri yumuşak
   * ✓ "Başla" butonu mesajı kapatıyor
   * ✓ Mesaj hemen tekrar görünmüyor (frekans sınırlama ayarlarını kontrol edin)

<Note>
  Simülatörler/emülatörler özellikle dokunma etkileşimleri ve SDK entegrasyonları için gerçek cihaz davranışını doğru yansıtmayabilir. Üretime çıkmadan önce her zaman fiziksel cihazlarda test edin.
</Note>

### Yaygın sorunları giderme

| Sorun                          | Olası neden                             | Çözüm                                                                                                                          |
| ------------------------------ | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Mesaj görünmüyor               | Tetikleme koşulları karşılanmadı        | [Uygulama İçi Mesaj Tetikleyicilerini](./iam-triggers) kontrol edin ve test kullanıcınızın kriterleri karşıladığını doğrulayın |
| Butonlar çalışmıyor            | JavaScript hataları veya ID uyuşmazlığı | Tarayıcı konsolunda hataları kontrol edin; buton ID'lerinin olay dinleyici ID'leriyle eşleştiğini doğrulayın                   |
| Görseller yüklenmiyor          | CORS sorunları veya geçersiz URL'ler    | HTTPS URL'leri kullanın; önce görsel URL'lerini bir tarayıcıda test edin                                                       |
| Mesaj görünüyor ama kapanmıyor | OneSignal SDK yüklenmedi                | [Mobile SDK kurulumunun](./mobile-sdk-setup) tamamlandığını doğrulayın                                                         |

***

## Sonraki Adımlar

**Kullanıcı etkileşimini takip edin:**

* Adımlar arası vazgeçmeyi ölçmek için [`data-onesignal-unique-label`](./in-app-message-api#click-name) niteliklerini kullanarak tıklama takibi ekleyin (şablonda zaten dahil)
* **Messages → In-App Messages → \[Mesajınız] → Analytics** bölümünde tıklama analizlerini görüntüleyin

**Deneyimi kişiselleştirin:**

* Onboarding'i tamamlayan [kullanıcıları etiketleyin](./in-app-message-api#tag-user) (örn., `onboarding_completed: true`)
* Etiketleri kullanarak [kullanıcıları segmentleyin](./segmentation) ve onboarding akışının tekrar gösterilmesini engelleyin
* Gelecekteki mesajlarda içeriği kişiselleştirmek için [kullanıcı verisi ekleyin](./add-user-data-tags)

**Gelişmiş özelleştirme:**

* Kapatma sonrası kullanıcıları belirli bir ekrana [derin bağlantı](./deep-linking#send-in-app-messages-with-deep-links) ile yönlendirin
* Başlıkları kullanıcı adları veya niteliklerle kişiselleştirmek için [Liquid sözdizimi](./using-liquid-syntax) kullanın
* Tamamlanma oranlarını optimize etmek için farklı onboarding akışlarıyla A/B testi uygulayın
