Soft 404 untuk Website Kecil - Samakan Status dengan Isi Halaman
Seorang pengunjung meminta URL yang tidak pernah ada. Halamannya dengan jelas mengatakan “tidak ditemukan”, menyediakan kotak pencarian, dan menautkan kembali ke bagian yang berguna. Namun, baris responsnya mengatakan 200 OK. Bagi manusia, halaman itu tampak seperti error. Bagi client HTTP, request tersebut berhasil. Pesan mana yang seharusnya dipercaya?
Ketidaksesuaian ini umum disebut soft 404 dalam dokumentasi Google Search. Ini bukan status code HTTP tersembunyi, dan bukan bukti bahwa sebuah situs telah terkena penalti. Ini adalah diagnosis: konten yang dikembalikan tampak menjelaskan resource yang hilang, sementara respons protokolnya tidak menyatakan dengan jelas bahwa resource tersebut tidak ada.
Untuk CMS kecil, perbaikannya biasanya bukan soal “melakukan SEO”, melainkan menyampaikan kenyataan secara konsisten. Route, status code, halaman yang terlihat, redirect, sitemap, dan internal link seharusnya menggambarkan hasil yang sama. Hal itu membantu browser, crawler, alat monitoring, cache, dan manusia memahami respons tersebut.
Soft 404 Adalah Klasifikasi, Bukan Fitur Protokol
HTTP sudah memiliki status untuk resource yang tidak dapat ditemukan: 404 Not Found. RFC 9110 mendefinisikan 404 tanpa menyatakan apakah ketiadaan tersebut bersifat sementara atau permanen. Jika server mengetahui bahwa akses sudah tidak tersedia dan kondisinya kemungkinan permanen, spesifikasi menyediakan 410 Gone.
“Soft 404” berada di lapisan yang berbeda. Google mendokumentasikan bahwa respons sukses 2xx dapat dilaporkan sebagai soft 404 ketika kontennya tampak seperti error, kosong, atau dengan cara lain menunjukkan bahwa tidak ada halaman yang berguna. Klasifikasi persisnya adalah penilaian Google terhadap respons tersebut; crawler lain mungkin memakai istilah atau heuristik yang berbeda.
Perbedaan ini mencegah dua kesalahpahaman umum. Pertama, tidak ada header soft-404 yang perlu ditambahkan. Kedua, mengembalikan 200 tidak memaksa halaman masuk ke search index. Google secara eksplisit mengatakan bahwa respons 2xx memungkinkan konten diproses, tetapi tidak menjamin indexing. Success code adalah pernyataan mengenai request HTTP, bukan permintaan agar mendapat ranking.
Pilih Respons Berdasarkan Apa yang Terjadi
Status seharusnya mengikuti keadaan resource yang sebenarnya, bukan pilihan yang tampak paling menguntungkan di dashboard. Decision table kecil sering kali sudah cukup:
- URL tidak memiliki resource yang cocok: kembalikan
404dan render halaman not-found yang membantu. - Resource sengaja dihapus dan kemungkinan tidak akan kembali:
410dapat menyampaikan fakta yang lebih kuat itu. Jika riwayatnya tidak pasti,404tetap lebih jujur. - Resource berpindah dan memiliki pengganti yang nyata: redirect ke pengganti tersebut. Gunakan permanent redirect hanya ketika perpindahannya memang dimaksudkan untuk bertahan.
- Resource masih ada, tetapi server tidak dapat menyediakannya karena kegagalan sementara: gunakan respons 5xx yang sesuai. Menyebut gangguan sebagai “tidak ditemukan” menyembunyikan masalah operasional.
- Resource ada dan respons merepresentasikannya: status 2xx sesuai, meskipun halaman hanya memiliki sedikit teks.
Perbedaan antara 404 dan 410 merupakan kosakata HTTP yang bermakna, tetapi jangan mengubahnya menjadi trik deindexing. Dokumentasi crawler Google saat ini menyatakan bahwa crawler tersebut memperlakukan respons 4xx biasa selain 429 dengan cara yang sama untuk indexing pipeline-nya. Pilih 410 karena penghapusan permanen memang diketahui, bukan karena diharapkan memberikan timeline tertentu.
Halaman Error yang Ramah Tetap Dapat Menjadi Error Sungguhan
Body dan status menjawab pertanyaan yang berbeda. Status memberi tahu software apa yang terjadi. HTML membantu manusia memutuskan apa yang perlu dilakukan berikutnya. Respons 404 sungguhan tetap dapat memakai navigasi situs seperti biasa, menjelaskan masalah dengan bahasa yang jelas, menawarkan pencarian, dan menyarankan bagian yang relevan.
Sebaliknya, halaman besar yang rapi tidak membuat 200 menjadi benar. CMS sering menghasilkan soft 404 ketika front controller memuat kerangka situs terlebih dahulu, gagal menemukan record yang diminta, me-render template error, lalu tidak pernah mengubah status sukses default PHP. Hasilnya tampak disengaja di browser karena browser me-render response body untuk 404 maupun 200.
Me-redirect setiap URL yang tidak dikenal ke homepage menciptakan ketidaksesuaian lain. Homepage hampir tidak pernah menjadi pengganti bagi /articles/a-title-that-does-not-exist. Pengunjung kehilangan konteks URL rusak tersebut, sedangkan client otomatis melihat banyak alamat yang tidak berkaitan menyatu ke satu tujuan. Panduan redirect Google membahas redirect dalam konteks konten yang benar-benar berpindah atau memiliki lokasi baru. Redirect seharusnya menjadi peta menuju penerus yang relevan, bukan cara menghindari pengakuan bahwa penerus itu tidak ada.
Tetapkan Status Saat Hasil Route Sudah Diketahui
Dalam aplikasi native PHP, controller seharusnya memutuskan bahwa resource tidak ada sebelum me-render shared error view. PHP manual mendokumentasikan http_response_code() sebagai cara mendapatkan atau menetapkan status respons dan mencatat bahwa default web server adalah 200 ketika tidak ada code yang ditetapkan.
$post = findPublishedPostBySlug($slug);
if ($post === null) {
http_response_code(404);
require __DIR__ . '/views/errors/404.php';
exit;
}
renderPost($post);
exit penting karena aplikasi tidak seharusnya melanjutkan ke success template setelah me-render error. Status juga harus ditetapkan sebelum output mengirim response header. Framework mungkin menyediakan response object atau exception untuk tujuan yang sama; prinsipnya lebih penting daripada bentuk PHP khusus ini.
Setiap kelompok route perlu diuji secara terpisah. CMS mungkin menolak slug English yang tidak dikenal dengan benar, sementara fallback /id/ atau /de/-nya diam-diam mengembalikan homepage terjemahan dengan 200. Halaman kategori, author archive, pagination yang melewati halaman terakhir, media yang dihapus, dan identifier yang malformed dapat melewati jalur controller yang berbeda. Satu template 404 global yang benar tidak membuktikan bahwa setiap route yang hilang mencapainya.
Pertahankan Status Melewati Nginx
Web server dapat mengganti error body tanpa mengubah status asal. Dokumentasi resmi error_page Nginx menunjukkan pola dasarnya:
error_page 404 /404.html;
location = /404.html {
internal;
}
Internal error document tersebut dapat menyediakan halaman yang konsisten sementara client tetap menerima 404. Nginx juga mendukung penggantian status secara eksplisit. Sebagai contoh, error_page 404 =200 /empty.gif; sengaja mengubah respons menjadi 200. Kemampuan itu memiliki kegunaan khusus yang sah, tetapi menerapkan pola yang sama pada halaman HTML yang hilang menciptakan ketidaksesuaian semantik yang sedang dibahas.
Aplikasi di belakang FastCGI atau reverse proxy memerlukan pemeriksaan end-to-end. PHP dapat memilih satu status, lalu proxy, cache rule, custom error handler, atau application fallback menggantinya kemudian. Hanya membaca kode template tidak dapat memperlihatkan respons akhir yang diterima client.
Client-Side Routing Memiliki Batas yang Lebih Sulit
Single-page application dapat menerima kerangka HTML dengan 200 sebelum JavaScript mengetahui bahwa object yang diminta tidak ada. Mengubah teks di document tidak menulis ulang status network response yang telah selesai. Inilah sebabnya view “tidak ditemukan” yang di-render di client tetap dapat menjadi soft 404.
Panduan troubleshooting JavaScript Google menjelaskan redirect ke URL yang mengembalikan 404 atau menambahkan noindex ketika SPA menemukan konten yang hilang. Untuk situs konten publik, menyelesaikan route yang diketahui di server dan mengembalikan status yang benar pada respons awal biasanya merupakan desain yang lebih jelas. Directive noindex dapat memengaruhi indexing, tetapi tidak mengubah respons HTTP sukses menjadi 404 dan tidak seharusnya dianggap memiliki semantik protokol yang setara.
Uji Hal yang Tidak Dikenal, Bukan Hanya Halaman yang Dirancang
Membuka /404 di browser mungkin hanya menguji route demonstrasi. Pemeriksaan yang lebih kuat meminta path acak yang tidak mungkin telah dikonfigurasi secara sengaja:
curl -sS -o /dev/null -w '%{http_code}\n' \
https://example.com/definitely-missing-7f3a9c/
curl -sS -I https://example.com/definitely-missing-7f3a9c/
Command pertama memperlihatkan status akhir setelah redirect. Command kedua memudahkan pemeriksaan response header, meskipun pengujian yang kuat juga perlu melakukan GET biasa karena beberapa aplikasi menangani HEAD secara berbeda. Gunakan suffix acak yang baru agar tidak menguji URL yang tersimpan di cache atau ditangani secara khusus.
Audit praktis mengambil sampel hasil, bukan mengejar hitungan sempurna:
- Minta URL artikel, kategori, author, locale, pagination, dan asset yang tidak dikenal.
- Pastikan setiap route yang hilang mengembalikan 404 atau alternatif yang sengaja dipilih dan dapat dijelaskan.
- Pastikan rendered body tetap menjelaskan error dan menawarkan navigasi yang berguna.
- Uji halaman yang berpindah dan pastikan redirect-nya berakhir pada pengganti yang spesifik, bukan homepage umum.
- Hapus internal link dan entri sitemap yang usang; 404 yang benar tidak membuat broken internal link menjadi baik.
- Uji melalui proxy publik atau CDN serta origin, karena setiap lapisan dapat mengubah respons.
Untuk laporan khusus Google, Search Console menyarankan pemeriksaan contoh dan penggunaan live URL inspection. Laporan tersebut adalah bukti diagnostik, bukan skor yang harus mencapai nol. URL acak yang salah ketik atau berasal dari luar dapat secara sah mengembalikan 404. Pertanyaan yang berguna adalah apakah halaman penting yang masih ada salah diklasifikasikan, atau apakah routing situs mengembalikan success response untuk resource yang tidak dimilikinya.
Biarkan Status dan Halaman Menyampaikan Cerita yang Sama
Soft 404 biasanya merupakan gejala batas yang tidak jelas: aplikasi mengetahui bahwa tidak ada record, tetapi pengetahuan tersebut tidak pernah mencapai respons HTTP. Perbaikan yang tahan lama adalah membuat keputusannya eksplisit. Kembalikan 404 untuk resource yang tidak dikenal, 410 hanya untuk penghapusan permanen yang diketahui, redirect untuk penerus yang nyata, dan 5xx ketika layanan yang masih ada mengalami kegagalan.
Tidak satu pun dari hal ini menjamin indexing atau ranking, dan tidak setiap 404 perlu “diperbaiki”. Beberapa URL memang tidak ada. Tujuannya lebih kecil dan lebih dapat dipertanggungjawabkan: manusia seharusnya menerima penjelasan yang membantu, sementara software menerima status yang menggambarkan kenyataan yang sama.
References
- IETF RFC 9110: 404 Not Found and 410 Gone
- Google Search Central: How HTTP Status Codes Affect Google's Crawlers
- Google Search Console Help: Page Indexing Report
- Google Search Central: Redirects and Google Search
- Google Search Central: Fix Search-Related JavaScript Problems
- Nginx Documentation: error_page
- PHP Manual: http_response_code
- MDN: 404 Not Found
