Arsitektur CMS yang menjalankan Afapedia Studio dibangun dengan Laravel dan dipandu satu prinsip: setiap keputusan harus mengurangi risiko kesalahan penulis dan mempercepat halaman publik. Hasilnya adalah beberapa pola yang bisa dipakai di proyek CMS lain: revisi otomatis untuk setiap simpan, sanitasi konten di server, gambar yang diproses menjadi beberapa varian WebP, data SEO yang dihitung dari satu kelas, dan redirect otomatis saat URL berubah.
Kebutuhan yang Membentuk Arsitektur
- Satu situs dengan tiga zona: publik (blog, tools, produk), area member, dan portal admin.
- Penulis menulis lewat editor visual, bukan Markdown.
- Halaman publik harus cepat dan ramah mesin pencari.
- Tim kecil, jadi kode harus mudah dirawat tanpa infrastruktur rumit.
Keputusan 1: Semua Penyimpanan Lewat Satu Service
Membuat, mengedit, memulihkan revisi, dan mengimpor artikel semuanya melewati satu PostService::save(). Di dalamnya: sanitasi konten, pembuatan daftar isi, hitung kata dan waktu baca, slug unik, pencatatan revisi, redirect bila slug berubah, dan audit log. Satu jalur membuat aturan tidak bisa terlewat, apa pun sumber perubahannya.
Keputusan 2: Revisi untuk Setiap Simpan
Setiap kali kolom penting berubah, snapshot artikel disimpan sebagai revisi. Penulis bisa membandingkan dan memulihkan versi lama. Ada juga lock_version: kalau dua orang mengedit artikel yang sama, simpanan kedua ditolak dengan pesan jelas, bukan diam-diam menimpa pekerjaan orang lain.
Keputusan 3: Sanitasi Konten di Server
HTML dari editor dianggap tidak tepercaya. Sebelum disimpan, konten melewati HTML sanitizer dengan daftar tag yang diizinkan (paragraf, heading, daftar, tabel, kode, gambar, tautan). Script, iframe, dan form dibuang. Setelah itu, pemrosesan tambahan berjalan di level DOM:
- H1 di isi artikel diturunkan menjadi H2, karena H1 sudah dipakai judul halaman.
- Setiap H2 dan H3 diberi anchor, lalu dipakai untuk daftar isi.
- Tautan keluar diberi atribut aman, dan tautan afiliasi diberi
rel="sponsored"otomatis.
Hasilnya disimpan di dua kolom: sumber yang sudah disanitasi untuk diedit ulang, dan HTML siap tampil. Halaman publik cukup mencetak HTML jadi tanpa memproses ulang setiap request. Alasan keamanan di balik pendekatan ini dibahas di OWASP Top 10 untuk Laravel.
Keputusan 4: Gambar Diproses Sekali Saat Diunggah
Gambar unggahan diubah menjadi beberapa varian WebP (besar, sedang, kecil, dan ukuran Open Graph 1200x630). Nama file dibentuk dari alt text yang di-slug ditambah token acak, tidak pernah memakai nama file asli dari pengguna. Halaman publik memakai srcset agar ponsel mengunduh varian kecil. Untuk pengunjung yang ingin melakukan hal serupa tanpa server, situs ini menyediakan Kompres Gambar yang berjalan di browser.
Keputusan 5: SEO dari Satu Kelas
Title, meta description, canonical, robots, Open Graph, dan JSON-LD setiap jenis halaman dihasilkan oleh satu SeoFactory. View tidak menyusun meta tag sendiri. Keuntungannya:
- Aturan seperti "halaman 1 tidak memakai
?page=1" atau "artikel tipis diberi noindex" berlaku konsisten. - Perubahan format judul cukup di satu tempat.
- Mudah diuji: test cukup memanggil factory dan memeriksa hasilnya.
Editor juga menampilkan checklist SEO (panjang judul, meta description, focus keyword, tautan internal, alt gambar) yang membaca aturan yang sama.
Keputusan 6: Redirect Otomatis dan Rantai yang Diruntuhkan
Saat slug artikel atau kategori diubah, redirect 301 dari URL lama dibuat otomatis. Kalau A sudah dialihkan ke B lalu B diubah ke C, redirect A langsung diarahkan ke C agar tidak ada rantai. Peta redirect hanya dibaca saat request berakhir 404, jadi request normal tidak dibebani query tambahan.
Keputusan 7: Memberi Tahu Mesin Pencari Saat Konten Berubah
Observer pada model artikel mendeteksi perubahan pada kolom yang memengaruhi halaman publik (judul, isi, slug, status). Saat itu terjadi, sitemap diperbarui dan URL dikirim ke IndexNow agar mesin pencari yang mendukungnya cepat merayapi ulang. Perubahan kecil yang tidak terlihat pembaca tidak memicu notifikasi.
Yang Diubah Belakangan
- Kategori yang lebih sedikit sejak awal. Situs ini sempat punya 11 kategori sebelum dirampingkan menjadi 5 kategori berdasarkan pekerjaan pembaca, dengan redirect dari URL lama.
Pelajaran untuk Proyek CMS Lain
- Satukan jalur penyimpanan agar aturan bisnis tidak tersebar.
- Proses konten dan gambar saat ditulis, bukan saat dibaca.
- Pusatkan logika SEO dan ujilah seperti logika bisnis lain.
- Jangan pernah memutus URL yang sudah terindeks tanpa redirect.
Langkah Berikutnya
Pola-pola di atas memakai action, service, dan observer yang dijelaskan di design pattern untuk Laravel. Untuk strategi SEO dari sisi konten, baca SEO di era AI search.