Artikel tentang: Overlay
Artikel ini juga tersedia di:

Cara Membuat Overlay Kustom


Mau stream kamu makin kece dengan overlay buatan sendiri? Custom overlay ini kayak kanvas kosong buat kamu berkreasi pake HTML. Bisa buat pesan spesial, animasi seru, atau branding yang bikin orang langsung inget sama kamu!


Apa Saja Jenis Overlay yang Dapat Dikustomisasi?


  1. Alert (Tidak termasuk media seperti Voice Note ataupun GIF)
  2. Media Share (Hanya bagian pesan, bagian media/video dan progress bar tidak dapat di custom)
  3. Leaderboard
  4. Timer (Akan re-rendered setiap kali waktu berubah)
  5. Soundboard
  6. Milestone
  7. Polling
  8. Running Text
  9. VIP Queue
  10. Song Share (Info lagu, antrian, dan player visual, progress bar, play/pause, cover art )



Tips Penulisan Kode HTML


  1. Gunakan struktur HTML standar: Selalu mulai dengan <html>, <head>, dan <body>.
  2. Jangan pake position: absolute di CSS Body: Pastikan body memiliki height yang pasti karena sistem overlay Tako akan mendeteksi ukuran body, jika ukuran body tidak dapat di deteksi maka overlay akan tidak tampil karena sistem overlay Tako menganggap ukuran tinggi body sebesar 0px apabila body menggunakan posisi absolute.
  3. Gunain ukuran fleksibel: Gunakan px, rem, atau em buat font atau elemen. Jangan gunakan vh atau vw.
  4. Biasakan gunakan ukuran rem karena agar mudah di scaling melalui pengaturan ukuran font di dashboard pengaturan overlay.
  5. Selalu tes di dashboard biar tampilan sesuai dengan harapan.
  6. Jangan pake komentar // di dalam <script>: Sistem overlay Tako menghapus semua baris baru (newline) dari kode kamu sebelum dirender. Komentar // cuma berhenti di baris baru — begitu newline-nya hilang, komentar itu bisa "menelan" sisa kode di bawahnya sampai akhir script, bikin logic sesudahnya gak jalan tanpa ada error yang kelihatan. Kalo mau komentar, pake /* ... */, atau lebih aman gak usah pake komentar sama sekali.
  7. Data JSON (array/objek) langsung ditulis literal, jangan dibungkus tanda kutip: Tulis const data = {{namaVariabel}}; — BUKAN const data = JSON.parse('{{namaVariabel}}'). Isi JSON udah pasti pake tanda kutip dua ("), dan itu bakal motong string JS kamu di tengah kalo dibungkus kutip lagi, bikin script error.
  8. Jangan kasih max-width fixed di container utama: Ukuran box overlay (lebar/tinggi) udah kamu tentuin sendiri lewat OBS Browser Source atau dashboard preview. Kalo kode kamu pake max-width tetap (misal 26rem), box-nya bakal mentok di situ dan nyisain ruang kosong kalo box asli lebih lebar. Pake width: 100% biar ngisi penuh ukuran box yang udah kamu atur.



Variabel untuk Setiap Overlay


Tiap overlay punya variabel yang bisa kamu pake biar tampilan dinamis tanpa edit manual. Berikut daftar lengkapnya, termasuk overlay yang mendukung dan contoh penggunaan:


⚠️ Pastikan tidak ada spasi antara kurung kurawal dengan nama variabel!


1. Alert & Media Share


Nama Variabel

Contoh Info

Keterangan

{{amount}}

15000

Jumlah donasi (angka mentah).

{{formattedAmount}}

IDR 15.000

Jumlah donasi yang sudah diformat.

{{message}}

Semangat streaming!

Pesan dari donatur.

{{gifterName}}

BudiGaming

Nama donatur.

{{gifterPicture}}

https://example.com/profile.jpg

Link foto profil donatur.

{{gifterBadges}}

VIP,TopDonator

Daftar badge donatur (nama doang, dipisah koma) — gak ada URL ikon dari sistem.

{{isGifterVerified}}

true atau false

Status verifikasi donatur (true jika terverifikasi).

{{mediaDuration}}

10 (dalam detik)

Durasi media pada alert/mediashare; jika tidak ada media, jadi durasi alertnya.


⚠️ Tako gak ngirim URL ikon badge. Kalo mau badge tampil sebagai gambar (bukan teks/tag), isi manual di BADGE_ICON_URLS dalam script di bawah: key = nama badge persis kayak yang keluar di {{gifterBadges}}, value = URL ikon badge itu. Badge yang gak ada di daftar itu otomatis fallback ke tag teks biasa.


Contoh kode di bawah udah diisiin 6 badge sistem resmi Tako (nama + URL):


Nama Badge

URL Ikon

Tako Verified Partner

https://tako.id/images/badges/partnered-creator.png

Tako Verified Creator

https://tako.id/images/badges/verified-creator.png

Rich Rich Club

https://tako.id/images/badges/king.png

Charity

https://tako.id/images/badges/charity.png

VTuber

https://tako.id/images/badges/vtuber.png

Tako Team

https://tako.id/images/badges/admin.png


Contoh Kode:


<html>
<head>
<style>
body { margin: 0; background: none; font-family: "Courier New", monospace; color: #1c1712; }
.ticket {
position: relative;
width: 100%;
box-sizing: border-box;
overflow: hidden;
background: #f2e9d3;
border: 2px solid #1c1712;
box-shadow: 0.2rem 0.25rem 0 0 #1c1712;
padding: 0.9rem 1rem 0.9rem 1.5rem;
}
.tab { position: absolute; left: 0; top: 0; bottom: 0; width: 0.55rem; background: #9c3b2e; border-right: 2px solid #1c1712; }
.grommet { position: absolute; left: 0.275rem; top: 0.85rem; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #f2e9d3; border: 1px solid #1c1712; transform: translate(-50%, 0); z-index: 2; }
.gifter-row { display: flex; align-items: center; gap: 0.6rem; }
.avatar { width: 2.6rem; height: 2.6rem; border-radius: 50%; border: 2px solid #1c1712; object-fit: cover; flex-shrink: 0; display: none; }
.avatar-fallback { width: 2.6rem; height: 2.6rem; border-radius: 50%; border: 2px solid #1c1712; background: #e8dab8; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; }
.gifter-info { flex: 1; min-width: 0; }
.gifter-name { font-weight: 700; font-size: 1.0625rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.badges { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; margin-top: 0.2rem; }
.badge-tag { font-size: 0.75rem; border: 1px solid #7a7160; color: #7a7160; padding: 0.05rem 0.35rem; }
.badge-icon { height: 1rem; width: auto; display: block; }
.amount { font-weight: 700; font-size: 1.125rem; color: #b6842c; flex-shrink: 0; }
.perf { border-bottom: 1px dashed #7a7160; margin: 0.6rem 0; }
.message { font-size: 1rem; color: #4a4335; }
.media-tag { display: inline-block; margin-top: 0.4rem; font-size: 0.75rem; color: #7a7160; border: 1px solid #7a7160; padding: 0.05rem 0.35rem; }
</style>
</head>
<body>
<div class="ticket">
<div class="tab"></div>
<div class="grommet"></div>

<div class="gifter-row">
<img class="avatar" id="avatar" alt="">
<span class="avatar-fallback" id="avatar-fallback">🎁</span>
<div class="gifter-info">
<div class="gifter-name" id="gifter-name">{{gifterName}}</div>
<div class="badges" id="badges"></div>
</div>
<div class="amount">{{formattedAmount}}</div>
</div>
<div class="perf"></div>
<div class="message" id="message">{{message}}</div>
<div class="media-tag" id="media-tag"></div>
</div>

<script>
const picture = "{{gifterPicture}}".trim();
const badgesRaw = "{{gifterBadges}}".trim();
const isVerified = "{{isGifterVerified}}" === "true";
const mediaDuration = "{{mediaDuration}}";

const BADGE_ICON_URLS = {
"Tako Verified Partner": "https://tako.id/images/badges/partnered-creator.png",
"Tako Verified Creator": "https://tako.id/images/badges/verified-creator.png",
"Rich Rich Club": "https://tako.id/images/badges/king.png",
"Charity": "https://tako.id/images/badges/charity.png",
"VTuber": "https://tako.id/images/badges/vtuber.png",
"Tako Team": "https://tako.id/images/badges/admin.png"
};

const avatar = document.getElementById("avatar");
const avatarFallback = document.getElementById("avatar-fallback");
const gifterName = document.getElementById("gifter-name");
const badgesEl = document.getElementById("badges");
const messageEl = document.getElementById("message");
const mediaTag = document.getElementById("media-tag");

if (picture && !picture.includes("{{")) {
avatar.src = picture;
avatar.style.display = "block";
avatarFallback.style.display = "none";
avatar.onerror = () => {
avatar.style.display = "none";
avatarFallback.style.display = "flex";
};
}

if (isVerified) gifterName.appendChild(document.createTextNode(" ✓"));

if (badgesRaw && !badgesRaw.includes("{{")) {
badgesRaw.split(",").filter(Boolean).forEach((name) => {
const iconUrl = BADGE_ICON_URLS[name];

if (iconUrl) {
const icon = document.createElement("img");
icon.className = "badge-icon";
icon.src = iconUrl;
icon.alt = name;
icon.title = name;
badgesEl.appendChild(icon);
} else {
const tag = document.createElement("span");
tag.className = "badge-tag";
tag.textContent = name;
badgesEl.appendChild(tag);
}
});
}

if (!messageEl.textContent.trim() || messageEl.textContent.includes("{{")) {
messageEl.style.display = "none";
}

if (mediaDuration && !mediaDuration.includes("{{") && Number(mediaDuration) > 0) {
mediaTag.textContent = "⏱ " + mediaDuration + "s";
} else {
mediaTag.style.display = "none";
}
</script>
</body>
</html>



2. Leaderboard


Nama Variabel

Contoh Info

Keterangan

{{title}}

Top Donatur Bulan Ini

Judul leaderboard dari pengaturan.

{{rankings}}

[{"name":"BudiGaming","picture":"https://example.com/profile.jpg","badges":"VIP,TopDonator","amount":15000,"formattedAmount":"Rp15.000"}, ...]

Daftar ranking (JSON): nama, foto, badge (nama doang, dipisah koma — gak ada URL ikon), jumlah donasi, jumlah donasi diformat.


Contoh Kode:


<html>
<head>
<style>
body { margin: 0; background: none; font-family: "Courier New", monospace; color: #1c1712; }
.ticket {
position: relative;
width: 100%;
box-sizing: border-box;
overflow: hidden;
background: #f2e9d3;
border: 2px solid #1c1712;
box-shadow: 0.2rem 0.25rem 0 0 #1c1712;
padding: 0.9rem 1rem 0.9rem 1.5rem;
}
.tab { position: absolute; left: 0; top: 0; bottom: 0; width: 0.55rem; background: #9c3b2e; border-right: 2px solid #1c1712; }
.grommet { position: absolute; left: 0.275rem; top: 0.85rem; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #f2e9d3; border: 1px solid #1c1712; transform: translate(-50%, 0); z-index: 2; }
.title { font-size: 1.0625rem; font-weight: 700; }
.perf { border-bottom: 1px dashed #7a7160; margin: 0.6rem 0; }
.rank-row { display: flex; align-items: center; gap: 0.6rem; font-size: 1rem; padding: 0.35rem 0; border-bottom: 1px dashed #e8dab8; }
.rank-row:last-child { border-bottom: none; }
.rank-num { width: 1.6rem; font-weight: 700; color: #b6842c; flex-shrink: 0; }
.rank-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rank-badges { display: flex; align-items: center; gap: 0.2rem; flex-shrink: 0; }
.rank-badge-tag { font-size: 0.75rem; border: 1px solid #7a7160; color: #7a7160; padding: 0.05rem 0.35rem; }
.rank-badge-icon { height: 0.9375rem; width: auto; display: block; }
.rank-amount { font-weight: 700; color: #7a7160; flex-shrink: 0; }
</style>
</head>
<body>
<div class="ticket">
<div class="tab"></div>
<div class="grommet"></div>

<div class="title" id="lb-title">{{title}}</div>
<div class="perf"></div>
<div id="lb-list"></div>
</div>

<script>
const rankings = {{rankings}};
const list = document.getElementById("lb-list");

const BADGE_ICON_URLS = {
"Tako Verified Partner": "https://tako.id/images/badges/partnered-creator.png",
"Tako Verified Creator": "https://tako.id/images/badges/verified-creator.png",
"Rich Rich Club": "https://tako.id/images/badges/king.png",
"Charity": "https://tako.id/images/badges/charity.png",
"VTuber": "https://tako.id/images/badges/vtuber.png",
"Tako Team": "https://tako.id/images/badges/admin.png"
};

rankings.forEach((r, i) => {
const row = document.createElement("div");
row.className = "rank-row";

const num = document.createElement("span");
num.className = "rank-num";
num.textContent = "#" + (i + 1);

const name = document.createElement("span");
name.className = "rank-name";
name.textContent = r.name;

const badges = document.createElement("div");
badges.className = "rank-badges";
(r.badges || "").split(",").filter(Boolean).forEach((badgeName) => {
const iconUrl = BADGE_ICON_URLS[badgeName];

if (iconUrl) {
const icon = document.createElement("img");
icon.className = "rank-badge-icon";
icon.src = iconUrl;
icon.alt = badgeName;
icon.title = badgeName;
badges.appendChild(icon);
} else {
const tag = document.createElement("span");
tag.className = "rank-badge-tag";
tag.textContent = badgeName;
badges.appendChild(tag);
}
});

const amount = document.createElement("span");
amount.className = "rank-amount";
amount.textContent = r.formattedAmount;

row.appendChild(num);
row.appendChild(name);
row.appendChild(badges);
row.appendChild(amount);
list.appendChild(row);
});
</script>
</body>
</html>



3. Milestone


Nama Variabel

Contoh Info

Keterangan

{{title}}

Keliling Nusantara

Judul milestone dari pengaturan.

{{currentAmount}}

75000

Total donasi terkumpul dari semua langkah (angka mentah).

{{formattedCurrentAmount}}

IDR 75.000

Total donasi terkumpul, diformat.

{{targetAmount}}

100000

Total target dari semua langkah (angka mentah).

{{formattedTargetAmount}}

IDR 100.000

Total target, diformat.

{{overallPercentage}}

75

Persentase progres keseluruhan (0-100, bisa lebih dari 100 kalo kelebihan).

{{stepProgress}}

25000

Progres dalam langkah yang sedang aktif saja (angka mentah).

{{formattedStepProgress}}

IDR 25.000

Progres langkah aktif, diformat.

{{stepTarget}}

50000

Target langkah yang sedang aktif (angka mentah).

{{formattedStepTarget}}

IDR 50.000

Target langkah aktif, diformat.

{{percentage}}

50

Persentase progres langkah aktif (0-100).

{{stepIndex}}

2

Nomor urut langkah aktif (mulai dari 1).

{{stepCount}}

4

Total jumlah langkah.

{{stepTitle}}

Langkah 2: Bali

Judul langkah yang sedang aktif (kosong kalo gak diset).

{{steps}} / {{milestoneSteps}}

[{"title":"Langkah 1","target":25000,"currentAmount":25000,"percentage":100,"isActive":false}, ...]

Daftar semua langkah (JSON), tiap item punya formattedTarget/formattedCurrentAmount.


Contoh Kode:


<html>
<head>
<style>
body { margin: 0; background: none; font-family: "Courier New", monospace; color: #1c1712; }
.ticket {
position: relative;
width: 100%;
box-sizing: border-box;
overflow: hidden;
background: #f2e9d3;
border: 2px solid #1c1712;
box-shadow: 0.2rem 0.25rem 0 0 #1c1712;
padding: 0.9rem 1rem 0.9rem 1.5rem;
}
.tab { position: absolute; left: 0; top: 0; bottom: 0; width: 0.55rem; background: #9c3b2e; border-right: 2px solid #1c1712; }
.grommet { position: absolute; left: 0.275rem; top: 0.85rem; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #f2e9d3; border: 1px solid #1c1712; transform: translate(-50%, 0); z-index: 2; }
.title { font-size: 1.0625rem; font-weight: 700; }
.perf { border-bottom: 1px dashed #7a7160; margin: 0.6rem 0; }
.bar-bg { height: 0.7rem; background: #e8dab8; border: 1px solid #1c1712; }
.bar-fill { height: 100%; background: #b6842c; }
.amounts { display: flex; justify-content: space-between; font-size: 1rem; font-weight: 700; margin-top: 0.45rem; }
.meta { font-size: 0.8125rem; color: #7a7160; margin-top: 0.45rem; }
</style>
</head>
<body>
<div class="ticket">
<div class="tab"></div>
<div class="grommet"></div>

<div class="title" id="ms-title">{{title}}</div>
<div class="perf"></div>
<div class="bar-bg">
<div class="bar-fill" id="bar-fill" style="width: {{percentage}}%"></div>
</div>
<div class="amounts">
<span id="current">{{formattedStepProgress}}</span>
<span id="target">{{formattedStepTarget}}</span>
</div>
<div class="meta">Langkah {{stepIndex}} / {{stepCount}}</div>
</div>
</body>
</html>



4. Polling


Nama Variabel

Contoh Info

Keterangan

{{title}}

Pilih Game Selanjutnya!

Judul polling dari pengaturan.

{{pollingOptions}}

[{"id":1,"name":"Game A","totalAmount":5000,"formattedTotalAmount":"Rp5.000"}, ...]

Daftar opsi polling (JSON): ID, nama, jumlah donasi, jumlah donasi diformat.

{{startAt}}

2025-07-08

Tanggal mulai polling.

{{startTime}}

09:30

Waktu mulai polling.

{{endAt}}

2025-07-08

Tanggal selesai polling.

{{endTime}}

12:30

Waktu selesai polling.


Contoh Kode:


<html>
<head>
<style>
body { margin: 0; background: none; font-family: "Courier New", monospace; color: #1c1712; }
.ticket {
position: relative;
width: 100%;
box-sizing: border-box;
overflow: hidden;
background: #f2e9d3;
border: 2px solid #1c1712;
box-shadow: 0.2rem 0.25rem 0 0 #1c1712;
padding: 0.9rem 1rem 0.9rem 1.5rem;
}
.tab { position: absolute; left: 0; top: 0; bottom: 0; width: 0.55rem; background: #9c3b2e; border-right: 2px solid #1c1712; }
.grommet { position: absolute; left: 0.275rem; top: 0.85rem; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #f2e9d3; border: 1px solid #1c1712; transform: translate(-50%, 0); z-index: 2; }
.title { font-size: 1.0625rem; font-weight: 700; }
.perf { border-bottom: 1px dashed #7a7160; margin: 0.6rem 0; }
.poll-row { display: flex; align-items: center; gap: 0.6rem; font-size: 1rem; padding: 0.35rem 0; border-bottom: 1px dashed #e8dab8; }
.poll-row:last-child { border-bottom: none; }
.poll-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.poll-amount { font-weight: 700; color: #7a7160; flex-shrink: 0; }
.meta { font-size: 0.8125rem; color: #7a7160; margin-top: 0.55rem; }
</style>
</head>
<body>
<div class="ticket">
<div class="tab"></div>
<div class="grommet"></div>

<div class="title" id="poll-title">{{title}}</div>
<div class="perf"></div>
<div id="poll-list"></div>
<div class="meta">{{startAt}} {{startTime}} — {{endAt}} {{endTime}}</div>
</div>

<script>
const options = {{pollingOptions}};
const list = document.getElementById("poll-list");

options.forEach((o) => {
const row = document.createElement("div");
row.className = "poll-row";

const name = document.createElement("span");
name.className = "poll-name";
name.textContent = o.name;

const amount = document.createElement("span");
amount.className = "poll-amount";
amount.textContent = o.formattedTotalAmount;

row.appendChild(name);
row.appendChild(amount);
list.appendChild(row);
});
</script>
</body>
</html>



5. Running Text


Nama Variabel

Contoh Info

Keterangan

{{texts}}

[{"title":"Selamat datang!","backgroundColor":"#333","textColor":"#FFF"}, ...]

Daftar teks tambahan (JSON): judul, warna latar, warna teks.

{{gifts}}

[{"gifterName":"BudiGaming","amount":15000,"formattedAmount":"Rp15.000"}, ...]

Daftar donasi (JSON): nama donatur, jumlah donasi, jumlah donasi diformat.


Contoh Kode:


<html>
<head>
<style>
body { margin: 0; background: none; font-family: "Courier New", monospace; color: #1c1712; overflow: hidden; }
.ticker {
position: relative;
width: 100%;
box-sizing: border-box;
background: #f2e9d3;
border-top: 2px solid #1c1712;
border-bottom: 2px solid #1c1712;
padding: 0.6rem 0 0.6rem 1.4rem;
overflow: hidden;
white-space: nowrap;
}
.tab { position: absolute; left: 0; top: 0; bottom: 0; width: 0.55rem; background: #9c3b2e; border-right: 2px solid #1c1712; }
.grommet { position: absolute; left: 0.275rem; top: 50%; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #f2e9d3; border: 1px solid #1c1712; transform: translate(-50%, -50%); z-index: 2; }
.ticker-track { display: inline-flex; gap: 1.5rem; animation: scroll 18s linear infinite; }
.ticker-item { font-size: 1rem; font-weight: 700; flex-shrink: 0; }
.ticker-item.gift { color: #9c3b2e; }
@keyframes scroll {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
</style>
</head>
<body>
<div class="ticker">
<div class="tab"></div>
<div class="grommet"></div>
<div class="ticker-track" id="track"></div>
</div>

<script>
const texts = {{texts}};
const gifts = {{gifts}};
const track = document.getElementById("track");

function buildItems() {
const frag = document.createDocumentFragment();

texts.forEach((t) => {
const item = document.createElement("span");
item.className = "ticker-item";
item.style.color = t.textColor || "#1c1712";
item.textContent = t.title;
frag.appendChild(item);
});

gifts.forEach((g) => {
const item = document.createElement("span");
item.className = "ticker-item gift";
item.textContent = g.gifterName + " — " + g.formattedAmount;
frag.appendChild(item);
});

return frag;
}

track.appendChild(buildItems());
track.appendChild(buildItems());
</script>
</body>
</html>


Dua kali buildItems() di-append itu buat scroll seamless (dua salinan isi bersebelahan, translateX(-50%) berhenti pas salinan kedua persis nyampe posisi salinan pertama). Overlay ini gak ada progress-tick per-250ms kayak Song Share, jadi CSS animation loop aman jalan terus tanpa restart.



6. Soundboard


Nama Variabel

Contoh Info

Keterangan

{{amount}}

15000

Jumlah donasi (angka mentah).

{{formattedAmount}}

Rp15.000

Jumlah donasi yang diformat.

{{soundName}}

Explosion

Nama efek suara yang dipilih.

{{gifterName}}

BudiGaming

Nama donatur.

{{gifterPicture}}

https://example.com/profile.jpg

Link foto profil donatur.

{{gifterBadges}}

VIP,TopDonator

Daftar badge donatur (nama doang, dipisah koma) — gak ada URL ikon dari sistem.

{{isGifterVerified}}

true atau false

Status verifikasi donatur (true jika terverifikasi).


Contoh Kode:


<html>
<head>
<style>
body { margin: 0; background: none; font-family: "Courier New", monospace; color: #1c1712; }
.ticket {
position: relative;
width: 100%;
box-sizing: border-box;
overflow: hidden;
background: #f2e9d3;
border: 2px solid #1c1712;
box-shadow: 0.2rem 0.25rem 0 0 #1c1712;
padding: 0.9rem 1rem 0.9rem 1.5rem;
}
.tab { position: absolute; left: 0; top: 0; bottom: 0; width: 0.55rem; background: #9c3b2e; border-right: 2px solid #1c1712; }
.grommet { position: absolute; left: 0.275rem; top: 0.85rem; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #f2e9d3; border: 1px solid #1c1712; transform: translate(-50%, 0); z-index: 2; }
.gifter-row { display: flex; align-items: center; gap: 0.6rem; }
.avatar { width: 2.6rem; height: 2.6rem; border-radius: 50%; border: 2px solid #1c1712; object-fit: cover; flex-shrink: 0; display: none; }
.avatar-fallback { width: 2.6rem; height: 2.6rem; border-radius: 50%; border: 2px solid #1c1712; background: #e8dab8; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; }
.gifter-info { flex: 1; min-width: 0; }
.gifter-name { font-weight: 700; font-size: 1.0625rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.badges { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; margin-top: 0.2rem; }
.badge-tag { font-size: 0.75rem; border: 1px solid #7a7160; color: #7a7160; padding: 0.05rem 0.35rem; }
.badge-icon { height: 1rem; width: auto; display: block; }
.amount { font-weight: 700; font-size: 1.125rem; color: #b6842c; flex-shrink: 0; }
.perf { border-bottom: 1px dashed #7a7160; margin: 0.6rem 0; }
.sound-name { font-size: 1.0625rem; font-weight: 700; }
</style>
</head>
<body>
<div class="ticket">
<div class="tab"></div>
<div class="grommet"></div>

<div class="gifter-row">
<img class="avatar" id="avatar" alt="">
<span class="avatar-fallback" id="avatar-fallback">🔊</span>
<div class="gifter-info">
<div class="gifter-name" id="gifter-name">{{gifterName}}</div>
<div class="badges" id="badges"></div>
</div>
<div class="amount">{{formattedAmount}}</div>
</div>
<div class="perf"></div>
<div class="sound-name">🔈 {{soundName}}</div>
</div>

<script>
const picture = "{{gifterPicture}}".trim();
const badgesRaw = "{{gifterBadges}}".trim();
const isVerified = "{{isGifterVerified}}" === "true";

const BADGE_ICON_URLS = {
"Tako Verified Partner": "https://tako.id/images/badges/partnered-creator.png",
"Tako Verified Creator": "https://tako.id/images/badges/verified-creator.png",
"Rich Rich Club": "https://tako.id/images/badges/king.png",
"Charity": "https://tako.id/images/badges/charity.png",
"VTuber": "https://tako.id/images/badges/vtuber.png",
"Tako Team": "https://tako.id/images/badges/admin.png"
};

const avatar = document.getElementById("avatar");
const avatarFallback = document.getElementById("avatar-fallback");
const gifterName = document.getElementById("gifter-name");
const badgesEl = document.getElementById("badges");

if (picture && !picture.includes("{{")) {
avatar.src = picture;
avatar.style.display = "block";
avatarFallback.style.display = "none";
avatar.onerror = () => {
avatar.style.display = "none";
avatarFallback.style.display = "flex";
};
}

if (isVerified) gifterName.appendChild(document.createTextNode(" ✓"));

if (badgesRaw && !badgesRaw.includes("{{")) {
badgesRaw.split(",").filter(Boolean).forEach((name) => {
const iconUrl = BADGE_ICON_URLS[name];

if (iconUrl) {
const icon = document.createElement("img");
icon.className = "badge-icon";
icon.src = iconUrl;
icon.alt = name;
icon.title = name;
badgesEl.appendChild(icon);
} else {
const tag = document.createElement("span");
tag.className = "badge-tag";
tag.textContent = name;
badgesEl.appendChild(tag);
}
});
}
</script>
</body>
</html>



7. Timer


Nama Variabel

Contoh Info

Keterangan

{{title}}

Event Dimulai!

Judul timer dari pengaturan.

{{timeLeft}}

05:30

Sisa waktu dalam format MM:SS (atau 00:00 jika habis).

{{isEnabled}}

true atau false

Status timer (true jika aktif).

{{options}}

[{"durationAdded":300000,"minimumGiftAmount":10000}, ...]

Daftar opsi timer (JSON): durasi tambahan (ms), jumlah donasi minimum untuk menambah waktu.


Contoh Kode:


<html>
<head>
<style>
body { margin: 0; background: none; font-family: "Courier New", monospace; color: #1c1712; }
.ticket {
position: relative;
width: 100%;
box-sizing: border-box;
overflow: hidden;
background: #f2e9d3;
border: 2px solid #1c1712;
box-shadow: 0.2rem 0.25rem 0 0 #1c1712;
padding: 0.9rem 1rem 0.9rem 1.5rem;
text-align: center;
}
.tab { position: absolute; left: 0; top: 0; bottom: 0; width: 0.55rem; background: #9c3b2e; border-right: 2px solid #1c1712; }
.grommet { position: absolute; left: 0.275rem; top: 0.85rem; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #f2e9d3; border: 1px solid #1c1712; transform: translate(-50%, 0); z-index: 2; }
.row-head { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; text-align: left; }
.title { flex: 1; min-width: 0; font-size: 1.0625rem; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.status { flex-shrink: 0; font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; color: #7a7160; border: 1px solid #7a7160; padding: 0.1rem 0.4rem; }
.perf { border-bottom: 1px dashed #7a7160; margin: 0.6rem 0; }
.countdown { font-size: 2.25rem; font-weight: 700; letter-spacing: 0.05em; }
</style>
</head>
<body>
<div class="ticket">
<div class="tab"></div>
<div class="grommet"></div>

<div class="row-head">
<span class="title" id="timer-title">{{title}}</span>
<span class="status" id="status-el">Active</span>
</div>
<div class="perf"></div>
<div class="countdown">{{timeLeft}}</div>
</div>

<script>
const isEnabled = "{{isEnabled}}" === "true";
document.getElementById("status-el").textContent = isEnabled ? "Active" : "Inactive";
</script>
</body>
</html>



8. VIP Queue


Nama Variabel

Contoh Info

Keterangan

{{title}}

Antrian VIP

Judul dari pengaturan.

{{totalEntries}}

7

Total jumlah orang dalam antrian.

{{hiddenCount}}

2

Jumlah entri yang gak ditampilin karena kelebihan limit (displayedQueueLimit di pengaturan).

{{showFields}}

"true" atau "false" (string)

Status apakah custom field (misal alamat, catatan) ditampilkan.

{{visibleEntries}}

[{"index":1,"id":"1","name":"BudiGaming","picture":"https://example.com/profile.jpg","badges":"VIP,TopDonator","badgeItems":[{"url":"https://tako.id/images/badges/verified-creator.png","title":"Verified Creator"}],"isVerified":true,"amount":15000,"formattedAmount":"Rp15.000","fields":[{"label":"Alamat","value":"Jl. Merdeka 1"}]}, ...]

Daftar antrian yang sudah dipotong sesuai limit tampilan (JSON) — dipake buat render. Tiap entri punya badgeItems: array badge asli (ikon + judul), ini yang dipake buat nampilin badge sebagai gambar, bukan cuma teks.

{{entries}} / {{queue}}

sama struktur kayak visibleEntries

Daftar semua antrian (JSON), belum dipotong limit.

{{fields}}

[{"label":"Alamat","value":"Jl. Merdeka 1"}, ...]

Semua custom field dari semua entri, digabung jadi satu array datar (JSON).


Contoh Kode:


<html>
<head>
<style>
body { margin: 0; background: none; font-family: "Courier New", monospace; color: #1c1712; }
.ticket {
position: relative;
width: 100%;
box-sizing: border-box;
overflow: hidden;
background: #f2e9d3;
border: 2px solid #1c1712;
box-shadow: 0.2rem 0.25rem 0 0 #1c1712;
padding: 0.9rem 1rem 0.9rem 1.5rem;
}
.tab { position: absolute; left: 0; top: 0; bottom: 0; width: 0.55rem; background: #9c3b2e; border-right: 2px solid #1c1712; }
.grommet { position: absolute; left: 0.275rem; top: 0.85rem; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #f2e9d3; border: 1px solid #1c1712; transform: translate(-50%, 0); z-index: 2; }
.row-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.title { font-size: 1.0625rem; font-weight: 700; }
.count-badge { font-size: 0.875rem; font-weight: 700; color: #b6842c; border: 1px solid #7a7160; padding: 0.05rem 0.45rem; border-radius: 999px; flex-shrink: 0; }
.perf { border-bottom: 1px dashed #7a7160; margin: 0.6rem 0; }
.queue-list { display: flex; flex-direction: column; gap: 0.5rem; }
.queue-row { display: flex; align-items: center; gap: 0.5rem; }
.queue-num { width: 1.5rem; height: 1.5rem; border-radius: 50%; background: #e8dab8; border: 1px solid #1c1712; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 0.75rem; font-weight: 700; }
.queue-avatar { width: 1.6rem; height: 1.6rem; border-radius: 50%; border: 1px solid #1c1712; object-fit: cover; flex-shrink: 0; display: none; }
.queue-name { flex: 1; min-width: 0; font-size: 1rem; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.queue-badges { display: flex; align-items: center; gap: 0.2rem; flex-shrink: 0; }
.queue-badge-icon { height: 1.0625rem; width: auto; display: block; }
.queue-amount { font-size: 0.875rem; font-weight: 700; color: #7a7160; flex-shrink: 0; }
.queue-fields { font-size: 0.75rem; color: #7a7160; padding-left: 2.1rem; }
.queue-empty { font-size: 1rem; font-style: italic; color: #7a7160; }
.hidden-note { font-size: 0.8125rem; text-align: center; color: #7a7160; font-weight: 700; margin-top: 0.3rem; }
</style>
</head>
<body>
<div class="ticket">
<div class="tab"></div>
<div class="grommet"></div>

<div class="row-head">
<div class="title" id="queue-title">{{title}}</div>
<div class="count-badge" id="count-badge">{{totalEntries}}</div>
</div>
<div class="perf"></div>
<div class="queue-list" id="queue-list"></div>
<div class="hidden-note" id="hidden-note"></div>
</div>

<script>
const entries = {{visibleEntries}};
const hiddenCount = {{hiddenCount}};
const showFields = "{{showFields}}" === "true";

const list = document.getElementById("queue-list");
const hiddenNote = document.getElementById("hidden-note");

if (entries.length === 0) {
const empty = document.createElement("p");
empty.className = "queue-empty";
empty.textContent = "Belum ada antrian.";
list.appendChild(empty);
}

entries.forEach((entry) => {
const row = document.createElement("div");
row.className = "queue-row";

const num = document.createElement("div");
num.className = "queue-num";
num.textContent = entry.index;

const avatar = document.createElement("img");
avatar.className = "queue-avatar";
if (entry.picture) {
avatar.src = entry.picture;
avatar.style.display = "block";
avatar.onerror = () => { avatar.style.display = "none"; };
}

const name = document.createElement("span");
name.className = "queue-name";
name.textContent = entry.name + (entry.isVerified ? " ✓" : "");

const badgesEl = document.createElement("div");
badgesEl.className = "queue-badges";
(entry.badgeItems || []).forEach((badge) => {
if (!badge.url) return;
const icon = document.createElement("img");
icon.className = "queue-badge-icon";
icon.src = badge.url;
icon.alt = badge.title || "";
icon.title = badge.title || "";
badgesEl.appendChild(icon);
});

const amount = document.createElement("span");
amount.className = "queue-amount";
amount.textContent = entry.formattedAmount;

row.appendChild(num);
row.appendChild(avatar);
row.appendChild(name);
row.appendChild(badgesEl);
row.appendChild(amount);
list.appendChild(row);

if (showFields && entry.fields && entry.fields.length > 0) {
const fieldsRow = document.createElement("div");
fieldsRow.className = "queue-fields";
fieldsRow.textContent = entry.fields.map((f) => f.label + ": " + (f.value || "-")).join(" • ");
list.appendChild(fieldsRow);
}
});

if (hiddenCount > 0) {
hiddenNote.textContent = "+" + hiddenCount + " lainnya menunggu";
}
</script>
</body>
</html>



9. Song Share


Nama Variabel

Contoh Info

Keterangan

{{title}} / {{songTitle}}

Judul Lagu

Judul lagu yang sedang diputar.

{{songArtist}}

Nama Artis

Nama artis lagu yang sedang diputar.

{{songCoverArtUrl}}

https://example.com/cover.jpg

Link cover art lagu yang sedang diputar.

{{requesterName}}

BudiGaming

Nama pe-request lagu.

{{requesterPicture}}

https://example.com/profile.jpg

Link foto profil pe-request.

{{requesterBadges}}

VIP,TopDonator

Daftar badge pe-request (nama doang, dipisah koma) — gak ada URL ikon dari sistem buat baris "Now Playing" ini. Isi manual di BADGE_ICON_URLS dalam script kalo mau tampil sebagai gambar — kode di bawah udah diisiin 6 badge sistem resmi Tako, liat tabelnya di bagian Alert (§1).

{{isRequesterVerified}}

true atau false

Status verifikasi pe-request.

{{duration}}

215 (dalam detik)

Durasi lagu (angka mentah).

{{formattedDuration}}

03:35

Durasi lagu yang sudah diformat.

{{elapsed}}

42 (dalam detik)

Waktu lagu yang sudah berjalan (angka mentah).

{{formattedElapsed}}

00:42

Waktu lagu yang sudah berjalan, diformat.

{{progressPercent}}

19

Persentase progres lagu (0-100) — pakai buat bikin progress bar sendiri.

{{isPlaying}}

true atau false

Status lagu sedang diputar.

{{isPaused}}

true atau false

Status lagu sedang di-pause.

{{isInGap}}

true atau false

Status sedang dalam jeda antar lagu.

{{gapRemaining}}

3 (dalam detik)

Sisa waktu jeda antar lagu.

{{gapText}}

Lagu Berikutnya Pada 00:03

Teks status jeda antar lagu.

{{error}}

Lagu gagal diputar

Pesan error jika ada, kosong jika tidak ada.

{{nowPlaying}}

{"id":"1","title":"Judul Lagu","artist":"Nama Artis","coverArtUrl":"...","duration":215,"formattedDuration":"03:35","sender":{"name":"BudiGaming"},...}

Objek (JSON) lagu yang sedang diputar, null jika tidak ada.

{{queue}} / {{queues}}

[{"id":"2","title":"Lagu Antrian","artist":"Artis Lain","duration":180,"senderName":"Pendukung Lain","senderBadges":"VIP,TopDonator","senderBadgeItems":[{"url":"https://tako.id/images/badges/verified-creator.png","title":"Verified Creator"}],...}, ...]

Daftar antrian lagu berikutnya (JSON). Tiap item punya senderBadgeItems — array badge asli (ikon + judul) buat requester lagu itu, ini yang beneran bisa dirender sebagai gambar.


Contoh Kode:


<html>
<head>
<style>
body { margin: 0; background: none; font-family: "Courier New", monospace; color: #1c1712; }
.ticket {
position: relative;
width: 100%;
box-sizing: border-box;
overflow: hidden;
background: #f2e9d3;
border: 2px solid #1c1712;
box-shadow: 0.2rem 0.25rem 0 0 #1c1712;
padding: 0.9rem 1rem 0.9rem 1.5rem;
}
.tab { position: absolute; left: 0; top: 0; bottom: 0; width: 0.55rem; background: #9c3b2e; border-right: 2px solid #1c1712; }
.grommet { position: absolute; left: 0.275rem; top: 0.85rem; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #f2e9d3; border: 1px solid #1c1712; transform: translate(-50%, 0); z-index: 2; }
.row-head { display: flex; justify-content: flex-end; margin-bottom: 0.5rem; }
.status { font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; color: #7a7160; border: 1px solid #7a7160; padding: 0.1rem 0.4rem; }
.error-banner { font-size: 0.8125rem; background: #9c3b2e; color: #f2e9d3; padding: 0.35rem 0.5rem; margin-bottom: 0.5rem; display: none; }
.gap-banner { font-size: 0.9375rem; color: #7a7160; padding: 0.4rem 0; display: none; }
.now-playing { display: flex; gap: 0.75rem; }
.cover { position: relative; width: 3.4rem; height: 3.4rem; flex-shrink: 0; background: #e8dab8; border: 2px solid #1c1712; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; color: #7a7160; }
.cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: none; }
.info { flex: 1; min-width: 0; }
.title { font-size: 1.0625rem; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.title.idle { font-weight: 400; color: #7a7160; }
.artist { font-size: 0.9375rem; color: #7a7160; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 0.35rem; }
.requester { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; font-size: 0.8125rem; color: #7a7160; margin-bottom: 0.45rem; }
.requester img { width: 1.1rem; height: 1.1rem; border-radius: 50%; flex-shrink: 0; display: none; }
.requester .badge-tag { font-size: 0.75rem; border: 1px solid #7a7160; padding: 0.05rem 0.35rem; }
.requester .badge-icon { height: 0.9375rem; width: auto; display: block; }
.progress-row { display: flex; align-items: center; gap: 0.5rem; }
.bar-bg { flex: 1; height: 0.45rem; background: #e8dab8; border: 1px solid #1c1712; }
.bar-fill { height: 100%; background: #b6842c; }
.time { font-size: 0.8125rem; color: #7a7160; flex-shrink: 0; }
.perf { border-bottom: 1px dashed #1c1712; margin: 0.65rem 0 0.5rem; }
.setlist-label { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: #7a7160; margin-bottom: 0.4rem; }
.setlist { display: none; }
.setlist-row { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9375rem; padding: 0.25rem 0; }
.setlist-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.setlist-badges { display: flex; align-items: center; gap: 0.2rem; flex-shrink: 0; }
.setlist-badge-icon { height: 0.9375rem; width: auto; display: block; }
.setlist-time { color: #7a7160; flex-shrink: 0; }
</style>
</head>
<body>
<div class="ticket">
<div class="tab"></div>
<div class="grommet"></div>

<div class="row-head">
<span class="status" id="status-el">Now Playing</span>
</div>

<div class="error-banner" id="error-banner"></div>
<div class="gap-banner" id="gap-banner"></div>

<div id="player-body">
<div class="now-playing">
<div class="cover" id="cover">
<span id="cover-fallback"></span>
<img id="cover-img" alt="">
</div>

<div class="info">
<div class="title" id="title-el">{{songTitle}}</div>
<div class="artist" id="artist-el">{{songArtist}}</div>

<div class="requester" id="requester-row">
<img id="requester-pic" alt="">
<span id="requester-name">{{requesterName}}</span>
<span id="requester-verified"></span>
<span id="requester-badges"></span>
</div>

<div class="progress-row" id="progress-row">
<div class="bar-bg">
<div class="bar-fill" style="width: {{progressPercent}}%"></div>
</div>
<div class="time" id="time-el" data-elapsed="{{elapsed}}" data-duration="{{duration}}">{{formattedElapsed}} / {{formattedDuration}}</div>
</div>
</div>
</div>
</div>

<div id="setlist-wrap">
<div class="perf" id="setlist-perf" style="display:none"></div>
<div class="setlist" id="setlist">
<div class="setlist-label" id="setlist-label">Up Next</div>
<div id="setlist-body"></div>
</div>
</div>
</div>

<script>
const isPlaying = "{{isPlaying}}" === "true";
const isPaused = "{{isPaused}}" === "true";
const isInGap = "{{isInGap}}" === "true";
const gapText = "{{gapText}}";
const errorText = "{{error}}";
const coverUrl = "{{songCoverArtUrl}}".trim();
const requesterPicture = "{{requesterPicture}}".trim();
const requesterBadges = "{{requesterBadges}}".trim();
const isRequesterVerified = "{{isRequesterVerified}}" === "true";

const BADGE_ICON_URLS = {
"Tako Verified Partner": "https://tako.id/images/badges/partnered-creator.png",
"Tako Verified Creator": "https://tako.id/images/badges/verified-creator.png",
"Rich Rich Club": "https://tako.id/images/badges/king.png",
"Charity": "https://tako.id/images/badges/charity.png",
"VTuber": "https://tako.id/images/badges/vtuber.png",
"Tako Team": "https://tako.id/images/badges/admin.png"
};

const titleEl = document.getElementById("title-el");
const artistEl = document.getElementById("artist-el");
const coverImg = document.getElementById("cover-img");
const coverFallback = document.getElementById("cover-fallback");
const statusEl = document.getElementById("status-el");
const errorBanner = document.getElementById("error-banner");
const gapBanner = document.getElementById("gap-banner");
const playerBody = document.getElementById("player-body");
const requesterRow = document.getElementById("requester-row");
const requesterPic = document.getElementById("requester-pic");
const requesterVerified = document.getElementById("requester-verified");
const requesterBadgesEl = document.getElementById("requester-badges");
const progressRow = document.getElementById("progress-row");
const setlistPerf = document.getElementById("setlist-perf");
const setlist = document.getElementById("setlist");
const setlistLabel = document.getElementById("setlist-label");
const setlistBody = document.getElementById("setlist-body");

const titleText = titleEl.textContent.trim();
const isIdle = !titleText || titleText === "{{" + "songTitle" + "}}";

if (errorText && !errorText.includes("{{")) {
errorBanner.textContent = "⚠ " + errorText;
errorBanner.style.display = "block";
}

if (isInGap) {
playerBody.style.display = "none";
gapBanner.textContent = gapText || "Menyiapkan lagu berikutnya...";
gapBanner.style.display = "block";
statusEl.textContent = "Gap";
} else if (isIdle) {
titleEl.textContent = "Belum ada lagu diputar";
titleEl.classList.add("idle");
artistEl.textContent = "Kirim hadiah untuk request lagu";
requesterRow.style.display = "none";
progressRow.style.display = "none";
coverFallback.style.display = "flex";
statusEl.textContent = "Idle";
} else {
statusEl.textContent = isPaused ? "Paused" : isPlaying ? "Now Playing" : "Buffering";

if (coverUrl && !coverUrl.includes("{{")) {
coverImg.src = coverUrl;
coverImg.style.display = "block";
coverFallback.style.display = "none";
coverImg.onerror = () => {
coverImg.style.display = "none";
coverFallback.style.display = "flex";
};
}

if (requesterPicture && !requesterPicture.includes("{{")) {
requesterPic.src = requesterPicture;
requesterPic.style.display = "block";
}

if (isRequesterVerified) requesterVerified.textContent = "✓";

if (requesterBadges) {
requesterBadges.split(",").filter(Boolean).forEach((name) => {
const iconUrl = BADGE_ICON_URLS[name];

if (iconUrl) {
const icon = document.createElement("img");
icon.className = "badge-icon";
icon.src = iconUrl;
icon.alt = name;
icon.title = name;
requesterBadgesEl.appendChild(icon);
} else {
const tag = document.createElement("span");
tag.className = "badge-tag";
tag.textContent = name;
requesterBadgesEl.appendChild(tag);
}
});
}
}

try {
const queueData = {{queue}};

if (Array.isArray(queueData) && queueData.length > 0) {
setlistPerf.style.display = "block";
setlist.style.display = "block";
setlistLabel.textContent = "Up Next (" + queueData.length + ")";

queueData.forEach((song, i) => {
const row = document.createElement("div");
row.className = "setlist-row";

const name = document.createElement("span");
name.className = "setlist-name";
name.textContent = (i + 1) + ". " + song.title + " — " + song.artist;

const badgesEl = document.createElement("div");
badgesEl.className = "setlist-badges";
(song.senderBadgeItems || []).forEach((badge) => {
if (!badge.url) return;
const icon = document.createElement("img");
icon.className = "setlist-badge-icon";
icon.src = badge.url;
icon.alt = badge.title || "";
icon.title = badge.title || "";
badgesEl.appendChild(icon);
});

const duration = document.createElement("span");
duration.className = "setlist-time";
duration.textContent = song.formattedDuration;

row.appendChild(name);
row.appendChild(badgesEl);
row.appendChild(duration);
setlistBody.appendChild(row);
});
}
} catch (e) {}
</script>
</body>
</html>



Informasi Tambahan yang Mungkin Muncul


  • "⚠ Ini pesan uji coba": Muncul ketika overlay di tes atau preview.
  • "⛔ Dikirim oleh Admin": Muncul ketika hadiah dikirim oleh tim/admin Tako.



Cara Mengimplementasikan/Membuat Custom Overlay


  1. Masuk Dashboard Kreator
  2. Cari Menu "Overlays" di Bagian Kiri
  3. Pilih Overlay (contoh: Alert)
  4. Di bagian "Tema", ubah ke "Custom HTML".
  5. Copy-paste kode yang udah kamu bikin ke kolom/textarea yang muncul.
  6. Cek Preview pada bagian atas.


Diperbarui pada: 04/08/2026

Apakah artikel ini berguna?

Bagikan umpan balik Anda

Membatalkan

Terima kasih!