LaravelBladeSlotPemula4 mnt baca

Slot dan Named Slot

Kirim banyak blok konten ke component via slot bernama.

Analogi: Amplop Berlubang vs Map Berkantong

Component sederhana dengan satu $slot itu seperti amplop berlubang satu: apa pun yang kamu selipkan, keluarnya dari lubang yang sama. Cukup untuk kartu ucapan biasa.

Tapi bagaimana dengan undangan resmi yang punya tiga bagian terpisah: kop surat di atas, isi di tengah, tanda tangan di bawah? Satu lubang tidak cukup. Kamu butuh map berkantong banyak, setiap kantong punya labelnya sendiri. Itulah named slot: $slot untuk isi utama, plus slot bernama seperti $header dan $footer untuk bagian-bagian khusus.

Kenapa Named Slot Ada?

Satu $slot memaksa semua konten masuk ke satu titik. Untuk component kompleks seperti modal, kartu profil, atau panel admin, kamu butuh menaruh potongan konten yang berbeda di posisi yang berbeda dalam satu component. Alternatifnya adalah mengoper semuanya sebagai atribut string, yang cepat menjadi tidak terbaca begitu isinya berupa HTML panjang.

Named slot memberi setiap "kantong" nama, sehingga component tahu persis potongan mana harus dirender di mana.

Contoh 1: Mengingat Kembali $slot Tunggal

File: resources/views/components/card.blade.php

php
@props(['title'])

<div class="card">
    <h3>{{ $title }}</h3>
    <div class="card-body">
        {{ $slot }}
    </div>
</div>

Pemakaian:

php
<x-card title="Tips Hari Ini">
    <p>Minum air putih yang cukup itu penting.</p>
    <p>Ini semua masuk ke <code>$slot</code>.</p>
</x-card>

Semua yang ditulis di antara <x-card> dan </x-card> mengalir ke $slot. Sederhana dan cukup untuk 80% kasus.

Contoh 2: Modal dengan Named Slot

File: resources/views/components/modal.blade.php

php
<div class="modal-backdrop">
    <div class="modal">
        <div class="modal-header">
            {{ $header }}
        </div>

        <div class="modal-body">
            {{ $slot }}
        </div>

        <div class="modal-footer">
            {{ $footer }}
        </div>
    </div>
</div>

Pemakaian:

File: resources/views/posts/index.blade.php

php
<x-modal>
    <x-slot:header>
        <h2>Hapus Artikel?</h2>
    </x-slot:header>

    <p>Artikel yang dihapus tidak bisa dikembalikan.</p>

    <x-slot:footer>
        <button class="btn-secondary">Batal</button>
        <button class="btn-danger">Ya, Hapus</button>
    </x-slot:footer>
</x-modal>

Perhatikan polanya:

  • <x-slot:header>...</x-slot:header> mengisi variabel $header di component.
  • <x-slot:footer>...</x-slot:footer> mengisi variabel $footer.
  • Paragraf yang ditulis di luar tag x-slot masuk ke $slot utama (bagian body).

Nama slot bebas kamu tentukan: sidebar, actions, toolbar, apa pun yang masuk akal untuk component-mu.

Kesalahan Umum Pemula

1. Salah: mengira semua isi masuk ke slot bernama

php
<x-modal>
    <h2>Hapus Artikel?</h2>  {{-- ini masuk ke $slot, BUKAN $header! --}}
    <p>Artikel yang dihapus tidak bisa dikembalikan.</p>
</x-modal>

Tanpa pembungkus <x-slot:header>, judul di atas masuk ke $slot utama dan dirender di bagian body. Hasilnya: header modal kosong, body berisi dua-duanya.

Benar:

php
<x-modal>
    <x-slot:header>
        <h2>Hapus Artikel?</h2>
    </x-slot:header>

    <p>Artikel yang dihapus tidak bisa dikembalikan.</p>
</x-modal>

2. Salah: typo pada nama slot

php
<x-modal>
    <x-slot:heder>   {{-- typo: 'heder' bukan 'header' --}}
        <h2>Hapus?</h2>
    </x-slot:heder>
</x-modal>

Component mencari $header, tapi yang terisi $heder. Header tampil kosong tanpa error yang jelas. Nama slot itu case-sensitive dan harus sama persis.

Benar: pastikan ejaan <x-slot:header> sama dengan {{ $header }} di component.

3. Salah: memakai named slot untuk konten satu baris pendek

php
<x-card>
    <x-slot:title>Judul</x-slot:title>  {{-- berlebihan --}}
    <p>Isi kartu.</p>
</x-card>

Untuk teks pendek, atribut biasa (<x-card title="Judul">) jauh lebih ringkas. Named slot diperuntukkan bagi blok HTML yang panjang atau kompleks. Pilih alat yang proporsional.

Catatan teknis: Di dalam component, kamu bisa mengecek apakah sebuah slot diisi dengan $slot->isNotEmpty() atau isset($header). Ini berguna untuk merender bagian header/footer secara kondisional: kalau pemakai tidak mengisi slot footer, jangan tampilkan div footer kosong.

Slot Bersyarat dan Konten Default

Kadang slot boleh dikosongkan pemakai. Component yang baik tidak merender div kosong sia-sia:

File: resources/views/components/card.blade.php

php
@props(['title'])

<div class="card">
    <h3>{{ $title }}</h3>

    @if ($slot->isNotEmpty())
        <div class="card-body">
            {{ $slot }}
        </div>
    @endif

    @isset($footer)
        <div class="card-footer">
            {{ $footer }}
        </div>
    @endisset
</div>

$slot->isNotEmpty() mengecek apakah slot utama diisi, isset($footer) mengecek named slot. Kalau pemakai tidak mengisi footer, div footer tidak dirender sama sekali, HTML tetap bersih.

Kamu juga bisa memberi konten default saat slot kosong:

php
<div class="modal-footer">
    {{ $footer ?? 'Belum ada aksi.' }}
</div>

Pola ini membuat component-mu terasa "dewasa": fleksibel dipakai, tapi tidak pernah menghasilkan markup sampah.

Tantangan

Modal Konfirmasi

Buat component x-modal dengan named slot header dan footer plus $slot utama. Tampilkan modal konfirmasi hapus dengan judul, pesan, dan 2 tombol.