Template adalah bagian markup di file .svelte: HTML biasa, ditambah kurung kurawal {} sebagai tempat nilai dari JavaScript masuk. Bayangin papan menu Warung Bu Sri. Tulisan "Nasi Goreng" dan "Rp" dicat permanen, tapi di sebelahnya ada kotak kapur kosong yang tiap pagi diisi harga hari itu. Papannya gak dicat ulang tiap harga berubah, cuma kotaknya yang diisi. Di Svelte, HTML-nya adalah papan, dan {harga} adalah kotak kapur yang diisi nilai variabel harga.
🧪 Tebakan cepat:
let catatan = "<b>Pedas</b> level 3", lalu markupnya<p>{catatan}</p>. Di halaman, kata "Pedas" tampil tebal, atau tanda<b>-nya ikut tampil sebagai teks? Jawabannya ada di bagian "{@html}: menampilkan HTML mentah".
Kurung kurawal: nilai dari JavaScript
Variabel yang kamu tulis di <script> langsung bisa dipakai di markup. Bungkus dengan kurung kurawal, dan Svelte menaruh nilainya di situ:
<script>
let nama = "Nasi Goreng"
let harga = 15000
</script>
<h2>{nama}</h2>
<p>Rp {harga.toLocaleString("id-ID")}</p>
<p>Dua porsi: Rp {(harga * 2).toLocaleString("id-ID")}</p>
<p>{nama.toUpperCase()}</p>
Hasilnya di halaman:
| Markup | Tampil |
|---|---|
<h2>{nama}</h2> |
Nasi Goreng |
Rp {harga.toLocaleString("id-ID")} |
Rp 15.000 |
Dua porsi: Rp {(harga * 2).toLocaleString("id-ID")} |
Dua porsi: Rp 30.000 |
{nama.toUpperCase()} |
NASI GORENG |
- Di dalam
{}boleh ekspresi JavaScript apa pun, yaitu kode yang menghasilkan nilai: variabel, hitungan, atau pemanggilan method. toLocaleString("id-ID")memformat angka gaya Indonesia, dengan titik ribuan:15000jadi15.000.- Pernyataan seperti
if,for, atauletgak boleh di dalam{}. Untuk percabangan dan perulangan, Svelte punya blok{#if}dan{#each}, dibahas di pelajaran berikutnya. - Cukup satu pasang kurung kurawal.
{{nama}}(gaya Vue) di Svelte malah dibaca sebagai objek, dan halamannya menampilkan[object Object].
Latihan kedua memakai pola yang sama dengan nama pelanggan: let nama = "Budi", lalu <h2>{nama}</h2> menampilkan Budi. Namanya dibaca dari variabel, bukan diketik ulang di dalam <h2>.
Teks tetap cukup ditulis apa adanya
Kurung kurawal cuma perlu untuk nilai yang datang dari JavaScript. Teks yang gak pernah berubah ditulis langsung, seperti HTML biasa:
<h1>Belajar Svelte</h1>
<p>Svelte adalah compiler.</p>
Ini jawaban latihan pertama: <h1> berisi Belajar Svelte dan <p> berisi Svelte adalah compiler., tanpa <script> sama sekali. Kalau mau, <h1>Belajar {topik}</h1> dengan let topik = "Svelte" memberi hasil yang sama persis.
Atribut dinamis
Nilai atribut juga bisa diambil dari variabel:
<script>
let src = "/nasi-goreng.jpg"
let nama = "Nasi Goreng"
let href = "https://wa.me/6281200000000"
</script>
<img src={src} alt={nama} />
<img {src} alt="Foto {nama}" />
<a {href}>Pesan lewat WhatsApp</a>
src={src}: nilai atributsrcdiambil dari variabelsrc. Tanpa tanda kutip.{src}adalah singkatan darisrc={src}. Singkatan ini cuma jalan kalau nama variabelnya sama persis dengan nama atributnya.alt="Foto {nama}": teks dan kurung kurawal boleh dicampur di dalam tanda kutip. Hasilnyaalt="Foto Nasi Goreng".<a {href}>sama dengan<a href={href}>: tombol pesan warung mengarah kehttps://wa.me/6281200000000.- Kalau
altdihapus, compiler memberi warning:A11y: <img> element should have an alt attribute. Svelte ikut menjaga aksesibilitas.
{@html}: menampilkan HTML mentah
<script>
let catatan = "<b>Pedas</b> level 3"
</script>
<p>{catatan}</p>
<p>{@html catatan}</p>
| Markup | Tampil |
|---|---|
<p>{catatan}</p> |
<b>Pedas</b> level 3, tanda <b> ikut tampil sebagai teks |
<p>{@html catatan}</p> |
Pedas level 3, dengan "Pedas" tebal |
{catatan} selalu dianggap teks. Svelte mengubah < jadi < sebelum menaruhnya, jadi tanda <b> tampil apa adanya dan gak pernah jadi elemen. Itu jawaban tebakannya. {@html catatan} sebaliknya: isinya dimasukkan sebagai HTML sungguhan.
Hati-hati: kalau isi {@html} datang dari pengguna, misalnya catatan yang diketik pembeli, orang bisa mengirim <img src=x onerror="..."> dan menjalankan JavaScript di halamanmu. Serangan ini namanya XSS. Pakai {@html} cuma untuk HTML yang kamu percaya, misalnya konten milikmu sendiri.
Svelte 4 dan Svelte 5
Semua sintaks di pelajaran ini sama persis di Svelte 4 dan Svelte 5. Satu beda kecil: kalau nilainya null atau undefined, Svelte 4 menampilkan tulisan null atau undefined, sedangkan Svelte 5 gak menampilkan apa-apa.
⚠️ Jebakan yang sering ketemu
- Mengetik ulang nilainya.
<h2>Budi</h2>terlihat sama dengan<h2>{nama}</h2>, tapi gak mengikuti variabelnya. Latihan kedua memeriksa bahwa isi<h2>dimulai dengan kurung kurawal. - Komentar di dalam kurung kurawal.
{/* ... */}(gaya JSX) bikin compile error di Svelte 4:Unexpected block closing tag. Komentar di markup ditulis<!-- ... -->, seperti komentar TODO di<h2>kode awal latihan kedua: ganti komentar itu dengan{nama}. - Singkatan dengan nama yang beda.
let link = "https://wa.me/6281200000000"lalu<a {link}>gak mengisihref. Hasilnya atribut bernamalink, dan tulisannya gak bisa diklik. Sama halnya<img {foto} />gak mengisisrc. Tulishref={link}atausrc={foto}. {@html}untuk teks dari pengguna. Teks biasa selalu pakai{...}, yang aman karena di-escape.
TL;DR: Di markup Svelte, {ekspresi} menaruh nilai JavaScript ke halaman: {nama}, {harga * 2}, {nama.toUpperCase()}, cukup satu pasang kurung kurawal. Teks tetap ditulis langsung tanpa kurung kurawal. Atribut memakai src={src}, dan singkatannya {src} cuma jalan kalau nama variabel sama dengan nama atribut. {nilai} selalu tampil sebagai teks yang di-escape, sedangkan {@html nilai} memasukkan HTML sungguhan, jadi jangan pakai untuk isi dari pengguna (XSS). Komentar di markup ditulis <!-- -->, bukan {/* */}.