Membaca dokumentasi menjelaskan fitur satu per satu, tetapi membangun website utuh mengajarkan cara menyatukannya. Artikel ini memandu alur berpikir untuk membuat website portofolio + blog dengan Laravel, dari perencanaan sampai siap rilis. Kode kunci disertakan, dan detail dasar (CRUD, migration) bisa kamu dalami lewat artikel terkait.
Langkah 0: Rencanakan sebelum koding
Tulis daftar fitur dan batasi cakupan versi pertama (MVP).
Fitur publik:
- Beranda dengan perkenalan dan proyek unggulan.
- Halaman daftar proyek dan detail proyek.
- Blog: daftar artikel (dengan pagination) dan detail artikel.
- Halaman kontak (form pesan).
Fitur admin:
- Login admin.
- Kelola proyek, artikel, dan lihat pesan masuk.
Hal yang sengaja ditunda: komentar, multi-bahasa, langganan newsletter. Menunda fitur adalah kunci menyelesaikan proyek.
Langkah 1: Rancang database
| Tabel | Kolom penting |
|---|---|
users | id, name, email, password |
projects | id, title, slug, summary, description, image, url, featured, created_at |
posts | id, title, slug, excerpt, body, cover, published_at |
categories | id, name, slug |
category_post | category_id, post_id *(banyak-ke-banyak)* |
messages | id, name, email, body, read_at |
Beberapa keputusan penting:
- Slug (judul untuk URL,
belajar-laravel) dipakai di URL agar ramah SEO. Beriunique. published_atnullable:null= draft, tanggal masa depan = terjadwal.- Relasi artikel-kategori banyak-ke-banyak, jadi butuh tabel penghubung (lihat Mengenal Eloquent Relationship).
Buat lewat php artisan make:model Post -mfc, lalu isi migration (panduan migration).
Langkah 2: Layout dan komponen Blade
Hindari menyalin header/footer di setiap halaman. Buat satu layout:
{{-- resources/views/layouts/app.blade.php --}}
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title', 'Portofolio Saya')</title>
<meta name="description" content="@yield('description', 'Portofolio dan blog developer')">
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<x-navbar />
<main>@yield('content')</main>
<x-footer />
</body>
</html>
Halaman anak:
@extends('layouts.app')
@section('title', $post->title)
@section('content')
<article>...</article>
@endsection
Komponen kecil yang dipakai ulang (<x-card>, <x-navbar>) dibuat dengan php artisan make:component Card.
Langkah 3: Routing yang bersih
Route::get('/', HomeController::class);
Route::get('/proyek', [ProjectController::class, 'index'])->name('projects.index');
Route::get('/proyek/{project:slug}', [ProjectController::class, 'show'])->name('projects.show');
Route::get('/blog', [PostController::class, 'index'])->name('posts.index');
Route::get('/blog/{post:slug}', [PostController::class, 'show'])->name('posts.show');
Route::post('/kontak', [ContactController::class, 'store'])->name('contact.store');
Route::middleware('auth')->prefix('admin')->name('admin.')->group(function () {
Route::resource('projects', Admin\ProjectController::class);
Route::resource('posts', Admin\PostController::class);
});
{post:slug} membuat route model binding memakai kolom slug, bukan ID.
Langkah 4: Query yang efisien di controller
public function index()
{
$posts = Post::with('categories') // eager loading: cegah N+1
->whereNotNull('published_at')
->where('published_at', '<=', now())
->latest('published_at')
->paginate(9);
return view('posts.index', compact('posts'));
}
Gunakan scope di model agar logika "artikel terbit" tidak diulang:
public function scopePublished($query)
{
return $query->whereNotNull('published_at')->where('published_at', '<=', now());
}
// pemakaian: Post::published()->latest('published_at')->paginate(9)
Eager loading dan teknik performa lainnya dibahas di Tips Optimasi Query Laravel.
Langkah 5: Upload gambar dengan aman
$request->validate([
'cover' => 'nullable|image|mimes:jpg,jpeg,png,webp|max:2048',
]);
if ($request->hasFile('cover')) {
$data['cover'] = $request->file('cover')->store('covers', 'public');
}
Jalankan sekali php artisan storage:link, lalu tampilkan dengan asset('storage/' . $post->cover). Aturan penting:
- Validasi tipe dan ukuran file, jangan percaya ekstensi.
- Jangan simpan dengan nama asli dari pengguna; biarkan Laravel membuat nama acak.
- Hapus file lama saat diganti (
Storage::disk('public')->delete($old)).
Langkah 6: Form kontak dengan validasi dan proteksi spam
$data = $request->validate([
'name' => 'required|max:100',
'email' => 'required|email',
'body' => 'required|min:10|max:2000',
]);
Message::create($data);
Tambahkan pembatasan laju (->middleware('throttle:5,1')) dan honeypot (field tersembunyi yang harus kosong) untuk mengurangi spam. Kirim notifikasi email ke dirimu lewat Mail::to(...)->queue(...).
Langkah 7: SEO dasar
- Judul dan
meta descriptionunik per halaman. - URL berbasis slug.
<link rel="canonical">, tag Open Graph untuk pratinjau saat dibagikan.- Gambar dengan atribut
alt. sitemap.xmldanrobots.txt.- Kecepatan: kompres gambar, gunakan
loading="lazy", aktifkan cache.
Langkah 8: Autentikasi admin
Pasang starter kit (misalnya Breeze), lalu lindungi route admin dengan middleware auth. Karena situs hanya punya satu admin, nonaktifkan registrasi publik agar orang asing tidak bisa membuat akun. Detail alurnya ada di Membuat Authentication Laravel.
Langkah 9: Pengujian dan persiapan rilis
- Tulis beberapa test fitur: halaman publik bisa dibuka, draft tidak tampil, form kontak tervalidasi.
- Set
APP_ENV=production,APP_DEBUG=false. - Jalankan
php artisan config:cache route:cache view:cache. - Siapkan backup database.
- Deploy dengan panduan Deploy Laravel ke Server.
Pelajaran dari proyek seperti ini
- Rencanakan fitur dan database dulu; perubahan skema di akhir itu mahal.
- Pecah tampilan jadi layout dan komponen sejak awal.
- Pakai slug, eager loading, dan scope agar kode bersih dan cepat.
- Validasi semua input, termasuk upload.
- Rilis versi kecil lebih dulu, tambah fitur bertahap.
Kesimpulan
Website portofolio dan blog adalah proyek ideal untuk berlatih: cukup kecil untuk diselesaikan, tetapi mencakup routing, database, relasi, upload, autentikasi, SEO, dan deployment. Selesaikan versi sederhana, tampilkan di portofolio, lalu perbaiki dari sana.
Komentar (0)
Masuk / Daftar