Belajar Livewire 4 #12 – Home Page Component

Tutorial lengkap Livewire 4 dan Laravel 12 yang membahas konsep, fitur terbaru, dan praktik terbaik membangun aplikasi web modern tanpa ribet JavaScript. Materi disusun bertahap dari dasar hingga studi kasus nyata dengan penjelasan mengalir dan mudah dipahami.

✅ Telah dilihat 145 kali

Rating: 5.00 ⭐

... 04 February 2026, 06:28

Pada materi kali ini, kita akan membuat sebuah page component Livewire yang bertugas untuk menampilkan data posts di halaman home (/) dalam bentuk card.

Tujuan utamanya sederhana:

  • Saat user membuka halaman /
  • Data post langsung ditampilkan
  • Tanpa controller
  • Tanpa query di route
  • Semua logic dan tampilan ada di satu file Livewire

Membuat Page Component Home

Silakan teman-teman jalankan perintah berikut ini di dalam direktori project:

php artisan make:livewire pages::home.index

Jika berhasil, maka Livewire akan membuat file:

resources/views/pages/home/⚡index.blade.php

Inilah halaman home kita, yang nantinya akan dirender langsung ketika user mengakses /. Silakan buka file index.blade.php didalam folder resources/views/pages/home/ kemudian ubah menjadi seperti berikut ini:

<?php

use App\Models\Post;
use Livewire\Component;
use Livewire\WithPagination;

new class extends Component
{
    use WithPagination;

    public function render()
    {
        return $this->view([
            'posts' => Post::latest()->paginate(6),
        ])
            ->layout('layouts::app')
            ->title('Home');
    }
};
?>

<div class="max-w-7xl mx-auto px-4 py-10">
    <h1 class="text-3xl font-bold mb-8 text-gray-800">
        Latest Posts
    </h1>

    @if ($posts->count())
        <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
            @foreach ($posts as $post)
                <div
                    class="bg-white rounded-xl shadow hover:shadow-lg transition overflow-hidden">

                    {{-- Image --}}
                    @if ($post->image)
                        <img
                            src="{{ asset('storage/posts/' . $post->image) }}"
                            alt="{{ $post->title }}"
                            class="w-full h-48 object-cover">
                    @else
                        <div
                            class="w-full h-48 bg-gray-200 flex items-center justify-center text-gray-500">
                            No Image
                        </div>
                    @endif

                    {{-- Content --}}
                    <div class="p-5">
                        <h2 class="text-xl font-semibold text-gray-800 mb-2">
                            {{ $post->title }}
                        </h2>

                        <p class="text-gray-600 text-sm line-clamp-3 mb-4">
                            {!! strip_tags($post->content) !!}
                        </p>

                        <div class="flex items-center justify-between">
                            <span class="text-xs text-gray-400">
                                {{ $post->created_at->diffForHumans() }}
                            </span>

                            <a href="/posts/{{ $post->id }}"
                               wire:navigate
                               class="text-sm font-semibold text-indigo-600 hover:underline">
                                Read More →
                            </a>
                        </div>
                    </div>
                </div>
            @endforeach
        </div>

        {{-- Pagination --}}
        <div class="mt-10">
            {{ $posts->links() }}
        </div>
    @else
        <div
            class="bg-yellow-100 border border-yellow-300 text-yellow-800 px-4 py-3 rounded">
            Belum ada post.
        </div>
    @endif
</div>

1. Bagian Class Component (Logic)

<?php

use App\Models\Post;
use Livewire\Component;
use Livewire\WithPagination;

Penjelasan:

  • Post Digunakan untuk mengambil data dari tabel posts
  • Component Base class Livewire
  • WithPagination Trait bawaan Livewire untuk pagination otomatis

Mengaktifkan Pagination

new class extends Component
{
    use WithPagination;

Artinya:

  • Component ini mendukung pagination
  • Livewire akan otomatis mengelola:
    • halaman aktif
    • query string
    • render ulang data tanpa reload halaman

Method render()

public function render()
{
    return $this->view([
        'posts' => Post::latest()->paginate(6),
    ])
        ->layout('layouts::app')
        ->title('Home');
}

Penjelasannya:

  • Post::latest() Mengambil data post terbaru berdasarkan created_at
  • paginate(6) Menampilkan 6 post per halaman
  • Data dikirim ke view dengan key posts

Lalu:

  • layout('layouts::app') Menggunakan layout utama aplikasi
  • title('Home') Mengatur title halaman (SEO friendly)

📌 Semua ini tanpa controller dan tanpa route logic tambahan.


2. Bagian Tampilan (Blade View)

Container Utama

<div class="max-w-7xl mx-auto px-4 py-10">

Digunakan untuk:

  • Membatasi lebar konten
  • Membuat tampilan rapi di layar besar
  • Memberi padding atas dan bawah

Judul Halaman

<h1 class="text-3xl font-bold mb-8 text-gray-800">
    Latest Posts
</h1>

Judul utama halaman home.


3. Mengecek Data Post

@if ($posts->count())

Artinya:

  • Jika data post ada
  • Maka tampilkan daftar post
  • Jika tidak ada, tampilkan pesan kosong

4. Grid Card Post

<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">

Penjelasan layout:

  • Mobile: 1 kolom
  • Tablet: 2 kolom
  • Desktop: 3 kolom
  • gap-6 memberi jarak antar card

Loop Data Post

@foreach ($posts as $post)

Setiap post ditampilkan sebagai card modern.


Image Post

@if ($post->image)
  • Jika post memiliki image → tampilkan image
  • Jika tidak → tampilkan placeholder No Image

Ini penting supaya UI tetap rapi walaupun data belum lengkap.


Judul & Konten Singkat

<h2 class="text-xl font-semibold">
    {{ $post->title }}
</h2>
<p class="line-clamp-3">
    {!! strip_tags($post->content) !!}
</p>

Penjelasan:

  • strip_tags() Menghapus HTML agar aman ditampilkan
  • line-clamp-3 Membatasi teks hanya 3 baris

Footer Card

{{ $post->created_at->diffForHumans() }}

Menampilkan waktu secara human readable:

  • “2 jam yang lalu”
  • “3 hari yang lalu”

Link Read More

<a href="/posts/{{ $post->id }}"
   wire:navigate>

Artinya:

  • Navigasi menggunakan Livewire SPA
  • Halaman berpindah tanpa reload
  • Pengalaman user lebih cepat dan halus

5. Pagination

{{ $posts->links() }}

Livewire otomatis:

  • Mengatur halaman
  • Mengirim request AJAX
  • Render ulang grid post

Tanpa JavaScript tambahan 🔥


6. Jika Belum Ada Post

Belum ada post.

Ditampilkan jika tabel posts masih kosong.


Konfigurasi Rute

Langkah berikutnya adalah menghubungkan Home Page Component Livewire ke sistem routing Laravel.

Silakan teman-teman buka file:

routes/web.php

Lalu sesuaikan menjadi seperti berikut:

<?php

use Illuminate\Support\Facades\Route;

Route::livewire('/', 'pages::home.index');

Route::livewire('/posts', 'pages::post.index');
Route::livewire('/posts/create', 'pages::post.create');
Route::livewire('/posts/{post}/edit', 'pages::post.edit');

Penjelasan

Route Home (/)

Route::livewire('/', 'pages::home.index');

Artinya:

  • URL utama aplikasi:

    /
    
  • Akan menampilkan Home Page Component Livewire yang berada di:

    resources/views/pages/home/⚡index.blade.php
    

Apa yang Terjadi Saat URL / Diakses?

Ketika teman-teman membuka alamat:

http://localhost:8000/

Maka akan terlihat seperti berikut ini:

Pada materi berikutnya, kita akan membuat sebuah page component terakhir yakni untuk melihat detail dari post pada halaman hompage.

Daftar eBook