# Content Security Policy

> Directive CSP yang perlu diizinkan agar widget Webchat tampil di website Anda.


Jika website Anda memakai Content Security Policy (CSP), browser memblokir widget sampai sumbernya diizinkan. Tambahkan sumber berikut ke policy yang sudah ada. Jangan mengganti seluruh policy Anda dengan contoh di halaman ini.

## Directive yang dibutuhkan

| Directive | Sumber | Untuk |
|---|---|---|
| `script-src` | `https://app.csku.ai` | `widget.js` |
| `style-src` | `https://app.csku.ai` | `widget.css` |
| `frame-src` | `https://app.csku.ai` | Jendela chat (iframe) |
| `connect-src` | `https://api.csku.ai` | Mengambil warna, posisi, dan logo dari dashboard |
| `img-src` | `https://cdn.aplikasikreasi.id` | Logo di tombol widget |

Baris `window.cskuSettings = ...` adalah script inline. Izinkan dengan salah satu cara di [Script inline](#script-inline).

Pemeriksaan anti-spam (Cloudflare Turnstile) berjalan di dalam iframe CSKU, jadi website Anda tidak perlu mengizinkan `challenges.cloudflare.com`.

## Contoh header

Contoh ini memakai nonce untuk script inline. Ganti `RANDOM_NONCE` dengan nilai acak baru di setiap respons.

```http
Content-Security-Policy: default-src 'self'; script-src 'self' https://app.csku.ai 'nonce-RANDOM_NONCE'; style-src 'self' https://app.csku.ai; frame-src https://app.csku.ai; connect-src 'self' https://api.csku.ai; img-src 'self' https://cdn.aplikasikreasi.id
```

```html
<script nonce="RANDOM_NONCE">window.cskuSettings = {"channelKey": "<ID_CHANNEL>", "position": "right"};</script>
<script src="https://app.csku.ai/widget/widget.js" async></script>
```

## Contoh meta tag

Jika Anda tidak bisa mengatur header server, pakai tag `<meta>` di `<head>`:

```html
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://app.csku.ai 'unsafe-inline'; style-src 'self' https://app.csku.ai; frame-src https://app.csku.ai; connect-src 'self' https://api.csku.ai; img-src 'self' https://cdn.aplikasikreasi.id">
```

## Script inline

Pilih salah satu:

- **Nonce.** Tambahkan `'nonce-<nilai>'` ke `script-src` dan atribut `nonce="<nilai>"` ke tag settings. Nilai harus acak dan baru di setiap respons.
- **Hash.** Tambahkan hash SHA-256 isi script settings ke `script-src`, misalnya `'sha256-...'`. Hash berubah jika isi script berubah, termasuk spasi.
- **File eksternal.** Pindahkan baris settings ke file JavaScript di domain Anda, lalu muat sebelum `widget.js`. Tidak perlu mengubah `script-src` selain `'self'`.
- **`'unsafe-inline'`.** Paling mudah, tetapi melemahkan CSP untuk seluruh halaman. Hindari jika bisa.

Contoh file eksternal:

```js
// /js/csku-settings.js
window.cskuSettings = { channelKey: '<ID_CHANNEL>', position: 'right' }
```

```html
<script src="/js/csku-settings.js"></script>
<script src="https://app.csku.ai/widget/widget.js" async></script>
```

Muat file settings tanpa `async`, supaya selesai sebelum `widget.js` berjalan.

## Troubleshooting

Buka Console browser (F12). Pesan widget berawalan `[CSKU Webchat]`. Pelanggaran CSP muncul sebagai pesan "Refused to load ..." atau "Refused to execute inline script ...".

| Gejala | Penyebab | Solusi |
|---|---|---|
| `[CSKU Webchat] channelKey tidak valid atau belum diisi.` | `channelKey` kosong atau salah format, atau script settings diblokir CSP. | Salin ulang kode dari dashboard. Izinkan script inline. |
| `[CSKU Webchat] Gagal memuat widget.css.` | `style-src` belum mengizinkan `https://app.csku.ai`. | Tambahkan ke `style-src`. |
| `[CSKU Webchat] Loader harus dimuat lewat <script src="...">.` | `widget.js` disalin isinya ke script inline atau dimuat lewat cara lain. | Muat dengan `<script src="https://app.csku.ai/widget/widget.js" async>`. |
| `[CSKU Webchat] secretKey dan merchantId tidak dipakai lagi.` | Snippet versi lama. | Hapus `secretKey` dan `merchantId`, pakai `channelKey`. |
| Tombol muncul, jendela chat kosong | `frame-src` belum mengizinkan `https://app.csku.ai`. | Tambahkan ke `frame-src`. |
| Warna atau posisi tidak sesuai dashboard | `connect-src` belum mengizinkan `https://api.csku.ai`. | Tambahkan ke `connect-src`. |
| Logo tidak tampil di tombol | `img-src` belum mengizinkan `https://cdn.aplikasikreasi.id`. | Tambahkan ke `img-src`. |
| Tidak ada pesan, tombol tidak muncul | `script-src` memblokir `widget.js`. | Tambahkan `https://app.csku.ai` ke `script-src`. |

Jika `frame-src` tidak ada di policy Anda, browser memakai `child-src` lalu `default-src`. Tambahkan `https://app.csku.ai` di directive yang berlaku.
