← Semua pembelajaran / Laravel Nol → Enterprise
Fase 5 · API & Frontend

Livewire

Livewire membuat antarmuka dinamis tanpa meninggalkan PHP. Yang ditukar adalah perjalanan ke server untuk setiap interaksi — sangat sepadan untuk panel admin, perlu dipikirkan untuk halaman publik bertrafik tinggi.

Intisari

  • Satu komponen = satu kelas PHP + satu berkas Blade. Properti publik otomatis tersinkron dengan DOM.
  • Setiap aksi mengirim permintaan ke server, yang mengembalikan HTML dan menambalnya ke halaman.
  • wire:model.live mengirim pada setiap ketikan — hampir selalu perlu .debounce atau .blur.
  • Properti publik ikut terkirim ke browser dan bisa dimanipulasi. Jangan pernah menaruh rahasia atau nilai yang dipercaya di sana.
  • Cocok untuk area terautentikasi; untuk halaman baca publik, HTML statis lebih murah dan lebih mudah di-cache.

Bentuk sebuah komponen

composer require livewire/livewire
php artisan make:livewire CariArtikel
// app/Livewire/CariArtikel.php
class CariArtikel extends Component
{
    #[Url(as: 'q')]                       // tersinkron dengan query string
    public string $kata = '';

    public int $perHalaman = 20;

    public function render()
    {
        return view('livewire.cari-artikel', [
            'artikel' => Artikel::query()
                ->when($this->kata, fn ($q) => $q->where('judul', 'like', "%{$this->kata}%"))
                ->with('penulis')
                ->latest()
                ->paginate($this->perHalaman),
        ]);
    }
}
{{-- resources/views/livewire/cari-artikel.blade.php --}}
<div>
    <input type="search" wire:model.live.debounce.400ms="kata" placeholder="Cari…">

    <div wire:loading>Mencari…</div>

    @foreach ($artikel as $a)
        <article wire:key="artikel-{{ $a->id }}">{{ $a->judul }}</article>
    @endforeach

    {{ $artikel->links() }}
</div>
<livewire:cari-artikel />

wire:model.live tanpa debounce adalah kesalahan pertama semua orang. Ia mengirim satu permintaan HTTP untuk setiap ketikan. Mengetik "jakarta" berarti tujuh permintaan dan tujuh query database. Dengan .debounce.400ms, hanya jeda mengetik yang memicu permintaan. Untuk field yang tidak butuh umpan balik seketika, wire:model.blur lebih hemat lagi.

Model mentalnya

1. Server merender komponen jadi HTML biasa (kunjungan pertama)
2. Pengguna berinteraksi
3. Livewire mengirim POST berisi seluruh state komponen
4. Server membangun ulang komponen, menjalankan aksinya, merender ulang
5. Livewire menghitung selisih HTML-nya, lalu menambal DOM
KonsekuensiArtinya bagimu
Setiap interaksi = satu permintaanLatensi jaringan terasa; server ikut bekerja
State dikirim bolak-balikJaga properti publik tetap kecil
Komponen dibangun ulang tiap kalirender() berjalan berkali-kali — jaga query-nya tetap murah
Tidak ada state gandaTidak ada sinkronisasi frontend/backend yang bisa menyimpang
Halaman butuh PHP untuk berubahTidak bisa disajikan penuh dari CDN

Properti publik tidak pernah dipercaya

class UbahArtikel extends Component
{
    public Artikel $artikel;
    public string $judul = '';

    public function simpan(): void
    {
        // WAJIB — properti publik datang dari browser dan bisa diubah siapa pun
        $this->authorize('update', $this->artikel);

        $this->validate(['judul' => ['required', 'max:200']]);

        $this->artikel->update(['judul' => $this->judul]);

        $this->dispatch('artikel-tersimpan');
    }
}

Ini kesalahan keamanan paling umum di Livewire. Properti publik diserialisasi ke halaman dan dikirim balik dari browser — termasuk $this->artikel->id. Penyerang bisa menggantinya ke artikel milik orang lain. Otorisasi harus dilakukan di dalam setiap aksi, bukan hanya saat komponen pertama dirender. Untuk nilai yang tidak boleh diubah klien, gunakan properti #[Locked].

Kapan Livewire tepat

KasusCocok?Alasan
Panel admin, CMS, dasborSangatPengguna sedikit, interaksi kaya, kecepatan pengembangan tinggi
Form bertahap, filter tabelSangatTidak perlu menduplikasi validasi di frontend
Komentar, tombol sukaYaInteraksi kecil di dalam halaman statis
Halaman artikel publikTidak perluBlade biasa bisa di-cache penuh di CDN
Interaksi yang harus instan (menggeser, menggambar)TidakPerjalanan ke server terasa; pakai Alpine atau JS biasa

Pola yang paling sehat: campur. Halaman publik memakai Blade statis yang bisa di-cache penuh, sementara bagian interaktif — kotak pencarian, komentar — dipasang sebagai komponen Livewire di dalamnya. Kamu mendapat halaman yang murah untuk disajikan sekaligus antarmuka yang hidup di tempat yang memang membutuhkannya.

Latihan: buat komponen CariArtikel dengan wire:model.live tanpa debounce, buka Network di DevTools, dan hitung permintaan saat mengetik satu kata. Lalu tambahkan .debounce.400ms dan hitung ulang.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.