Inertia — React/Vue tanpa API
Inertia menghapus pekerjaan paling membosankan dari membangun SPA: membuat API hanya untuk frontend-mu sendiri. Controller tetap mengembalikan "halaman", cuma isinya komponen React atau Vue.
Intisari
- Bukan framework — ia lem antara Laravel dan React/Vue. Tidak ada rute frontend, tidak ada API terpisah.
- Controller mengembalikan
Inertia::render('Artikel/Index', [...]); props langsung jadi props komponen. - Kunjungan pertama menghasilkan HTML penuh; berikutnya hanya JSON, tanpa memuat ulang halaman.
- Partial reload dan deferred props mencegah pengiriman data yang tidak dipakai.
- Butuh SEO untuk halaman publik? Perlu SSR — dan SSR menambah satu proses Node yang harus ikut dijalankan.
Bentuknya
// Controller — tidak ada API, tidak ada resource
class ArtikelController extends Controller
{
public function index(Request $request)
{
return Inertia::render('Artikel/Index', [
'artikel' => ArtikelResource::collection(
Artikel::with('penulis')->latest()->paginate(20)
),
'filter' => $request->only('q', 'kategori'),
// Dievaluasi hanya saat diminta lewat partial reload
'statistik' => Inertia::optional(fn () => $this->hitungStatistik()),
]);
}
}
// resources/js/Pages/Artikel/Index.jsx
export default function Index({ artikel, filter }) {
return (
<Layout>
{artikel.data.map((a) => (
<Link key={a.id} href={route('artikel.show', a.slug)}>{a.judul}</Link>
))}
</Layout>
);
}
Tidak ada fetch, tidak ada state loading yang harus diurus, tidak ada rute yang perlu didefinisikan
dua kali. Komponen <Link> mencegat klik, mengambil props halaman berikutnya sebagai JSON, dan
menukar komponennya.
Bagaimana permintaan bekerja
| Kunjungan | Yang dikirim server | Yang terjadi di browser |
|---|---|---|
| Pertama (URL langsung) | HTML penuh + props sebagai JSON tertanam | Aplikasi frontend dijalankan |
Berikutnya (klik <Link>) | Hanya JSON berisi props | Komponen ditukar, tidak ada muat ulang |
| Partial reload | Hanya props yang diminta | Sebagian layar diperbarui |
// Hanya ambil ulang daftar artikel, bukan seluruh props halaman
router.get('/artikel', { q }, { only: ['artikel'], preserveState: true });
Tanpa partial reload, setiap navigasi mengirim seluruh props halaman. Termasuk daftar kategori,
data pengguna, dan apa pun yang dibagikan lewat Inertia::share() — padahal yang berubah cuma satu
daftar. Untuk halaman dengan filter yang sering diubah, only dan Inertia::optional()
adalah perbedaan antara respons 40 KB dan 4 KB.
Livewire atau Inertia?
| Livewire | Inertia | |
|---|---|---|
| Bahasa antarmuka | PHP + Blade | JavaScript (React/Vue) |
| Keahlian tim yang dibutuhkan | PHP saja | PHP + JS |
| Interaksi tanpa jaringan | Perlu Alpine | Bawaan — state ada di klien |
| Beban server per interaksi | Lebih tinggi | Lebih rendah |
| Ukuran unduhan awal | Kecil | Lebih besar (bundel JS) |
| SEO halaman publik | Bawaan — HTML dari server | Perlu SSR |
| Bisa di-cache penuh di CDN | Tidak | Tidak (kecuali SSR + cache) |
SSR dan konsekuensinya
php artisan inertia:start-ssr # satu proses Node yang harus tetap hidup
SSR menambah satu komponen yang harus dijalankan, dipantau, dan di-deploy. Di kontainer, itu berarti proses Node kedua di samping PHP — dengan health check, batas memori, dan kemungkinan gagal sendiri. Untuk aplikasi internal, SSR biasanya tidak diperlukan. Untuk halaman publik yang harus terindeks mesin pencari, pertimbangkan apakah halaman itu memang perlu jadi SPA sama sekali: Blade biasa memberi HTML sempurna tanpa proses tambahan apa pun.
Pola campuran yang layak dipertimbangkan
/ Blade — halaman depan, bisa di-cache di CDN
/artikel/{slug} Blade — halaman baca, bisa di-cache di CDN
/cari Livewire atau JS ringan
/admin/* Inertia — antarmuka kaya untuk pengguna terautentikasi
Tidak ada aturan yang mengharuskan satu aplikasi memakai satu pendekatan. Bagian yang dibaca banyak orang dan jarang berubah paling murah sebagai HTML statis; bagian yang dipakai sedikit orang tapi rumit paling produktif sebagai SPA. Laravel mengizinkan keduanya hidup di satu basis kode.
Latihan: pasang starter kit React, buat halaman Artikel/Index yang menerima props hasil
paginasi, lalu buka tab Network dan bandingkan ukuran respons antara kunjungan pertama dan klik
<Link> berikutnya. Setelah itu tambahkan only: ['artikel'] dan ukur lagi.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.