D
P
0

Technical SEO

Redirect Wildcard 301 Lintas Host Bikin Semua URL Lama Jadi `404`? Path-nya Tidak Ada di Host Baru

13 Juli 2026·4 menit baca
Redirect Wildcard 301 Lintas Host Bikin Semua URL Lama Jadi `404`? Path-nya Tidak Ada di Host Baru

Sebuah klien pindah dari situs WordPress lama ke host baru, dan tugas saya sederhana di atas kertas: pasang redirect 301 site-wide biar semua URL lama mendarat di tempat yang benar. Situs baru itu single-page di sebuah host JAMstack, jadi tidak ada WordPress lagi di sisi tujuan. Saya buka plugin Redirection di situs lama, aktifkan mode regex, dan bikin satu aturan wildcard yang kelihatannya rapi:

Source:  /(.*)
Target:  https://newsite/$1

Logikanya klasik migrasi: tangkap apa pun path yang datang, teruskan ke host baru dengan path yang sama. Saya deploy, buka homepage lama, dan ter-redirect mulus ke homepage baru. Kelihatan beres. Saya tutup laptop.

Beberapa jam kemudian klien lapor: banyak halaman malah "hilang". Bukan homepage, tapi URL dalam. Saya buka old-site.com/contact dan bukannya mendarat di halaman kontak yang baru, saya dilempar ke sebuah halaman 404 milik host tujuan. Coba old-site.com/services, 404 lagi. old-site.com/about, 404. Homepage satu-satunya yang selamat.

Gejalanya

Yang bikin saya salah baca di awal: redirect-nya jelas jalan. Ini bukan kasus "aturan tidak jalan". curl -I menunjukkan 301 yang bersih dan Location yang benar mengarah ke host baru. Rantainya berfungsi persis seperti yang saya tulis.

curl -I https://old-site.com/contact

Hasilnya 301 menuju https://newsite/contact, lalu host baru membalas 404 untuk /contact. Jadi redirect-nya sukses; yang gagal adalah tujuan akhirnya. Setiap path dalam yang ditangkap wildcard diteruskan ke URL yang memang tidak ada di sisi tujuan.

Investigasi

Saya sempat curiga aturan wildcard-nya ketimpa aturan lain. Di situs lama itu sudah ada beberapa redirect internal yang dipasang jauh sebelum saya, dan plugin memproses aturan berurutan: aturan yang lebih dulu dievaluasi sebelum wildcard. Saya cek satu per satu, kalau-kalau ada aturan lama yang menabrak path tertentu. Ternyata tidak. Aturan-aturan lama itu menyasar path spesifik yang lain dan tidak bentrok dengan yang sedang 404.

Saya juga sempat panik soal /wp-admin, takut wildcard /(.*) ikut menangkap panel admin dan mengunci saya keluar. Ternyata plugin Redirection secara default sudah mengecualikan /wp-admin, jadi saya masih bisa masuk dashboard. Bukan itu masalahnya.

Baru setelah saya benar-benar melihat Location header dan membandingkannya dengan struktur situs baru, uangnya jatuh. https://newsite/contact itu URL yang tidak pernah ada. Situs baru bukan replika situs lama dengan konten dipindah. Dia situs single-page dengan arsitektur informasi yang sama sekali berbeda: tidak ada /contact, tidak ada /services, tidak ada /about. Semuanya satu halaman.

Akar masalahnya

Capture group $1 itu masuk akal hanya kalau host tujuan punya struktur path yang sama dengan asal. Itu asumsi default setiap panduan migrasi WordPress: pindah domain, path tetap. Tapi asumsi itu roboh begitu tujuannya adalah situs yang benar-benar berbeda.

Source: /(.*) menangkap segala sesuatu setelah domain ke dalam $1. Target: https://newsite/$1 lalu menempelkan kembali path itu ke host baru. Untuk /contact, hasilnya https://newsite/contact, sebuah URL yang tidak punya padanan di situs single-page tersebut, sehingga host membalasnya dengan 404-nya sendiri. Redirect saya bekerja sempurna; dia cuma dengan setia mengantar setiap pengunjung ke alamat yang tidak ada.

Preservasi path itu benar untuk migrasi like-for-like. Di sini justru itu yang salah. Saya memaksakan peta jalan lama ke sebuah kota yang jalannya sudah dirombak total.

Perbaikannya

Solusinya adalah membuang capture group dan meruntuhkan semua URL lama ke homepage baru yang flat. Karena situs baru punya arsitektur informasi berbeda, preservasi path memang tidak diinginkan:

Source:  /(.*)      (regex aktif)
Target:  https://newsite/

Perhatikan Target tidak lagi berakhiran /$1. Apa pun path lama yang datang, /contact, /services, /about, semuanya sekarang mendarat di https://newsite/, halaman tunggal yang memang jadi rumah semua konten. Tidak ada lagi URL tujuan yang mengada-ada, tidak ada lagi 404.

Setelah itu saya jalankan verifikasi ulang dari terminal:

curl -I https://old-site.com/contact

Sekarang Location mengarah ke https://newsite/ dan host membalas 200. Saya coba beberapa path dalam lain dan semuanya kini mendarat di homepage baru dengan status sehat.

Checklist buat kamu yang migrasi lintas host

  • Tanya dulu: apakah host tujuan punya struktur path yang sama dengan asal? Kalau ya, Target: https://newsite/$1 cocok. Kalau tidak, buang $1.
  • Untuk tujuan single-page atau IA yang berbeda, runtuhkan semua ke homepage: Target: https://newsite/ tanpa capture group.
  • Verifikasi dengan curl -I, jangan cuma lihat statusnya redirect. Cek Location mengarah ke URL yang benar-benar ada dan host tujuan membalas 200, bukan 404.
  • Periksa aturan redirect internal yang sudah ada lebih dulu; plugin memprosesnya sebelum wildcard, dan aturan lama bisa menabrak path tertentu.
  • Pastikan /wp-admin dikecualikan (Redirection melakukannya secara default) supaya wildcard /(.*) tidak mengunci kamu keluar dari dashboard.

Pelajaran yang saya bawa pulang: redirect yang "berhasil" belum tentu redirect yang benar. 301 yang bersih tetap salah kalau mengantar ke pintu yang tidak ada. Sejak itu, setiap kali saya pasang wildcard lintas host, pertanyaan pertama saya bukan "apakah redirect-nya jalan", tapi "apakah alamat tujuannya betul-betul ada".