WordPress’te Özel 404 Sayfası Yönlendirmesi: functions.php Kullanımı
WordPress sitenizde bir kullanici olmayan bir sayfaya gittiginde ne olur? Cevap basit: 404 hatasi alir. Ama bu 404 hatasinin nasil yonetildigi, kullanici deneyimi ve SEO acisindan son derece kritik bir konudur. Cok fazla site varsayilan WordPress 404 sayfasini kullanir ve bu sayfa genellikle kullaniciyi bilgilendirmez, yonlendirmez, hatta markayla uyumlu bile degildir. Burada devreye functions.php girer ve bu dosyayla 404 yonetimini kökten degistirebilirsiniz.
404 Sayfasi Neden Bu Kadar Önemli?
Bir ziyaretci 404 sayfasina dustugunde iki senaryo gerceklesir: ya geri tusuna basar ve bir daha gelmez, ya da sitenizde gezinmeye devam eder. Ikinci senaryoyu saglamak tamamen size baglidir.
SEO acisindan bakildiginda, Google’in sitenizi taradigi sirada cok fazla 404 hatasi görmesi, sitenizin bakim yapilmayan bir site olarak algilanmasina yol acar. Buna ek olarak, degerli link juice’u kaybedersiniz. Bir baska site size link vermis ama o sayfa artik mevcut degilse, o trafigi ve otorite puanini cöpe atmis olursunuz.
functions.php üzerinden yapilabilecek 404 yonetimi birkaç farkli katmanda ele alinabilir:
- Kullaniciyi 404 sayfasina gitmeden önce yönlendirmek
- 404 sayfasina gidildiginde özel bir içerik sunmak
- 404 loglarini tutmak ve analiz etmek
- Belirli URL kaliplarini yakalamak ve dogru sayfaya yonlendirmek
Temel Yönlendirme Mantigi
Ilk olarak en basit senaryoyu ele alalim. Kullanici olmayan bir sayfaya geldigi anda anasayfaya yönlendirmek istiyorsunuz. Bu cok agresif bir yaklasim olsa da bazen tercih edilebilir.
// functions.php icine ekle
function custom_redirect_404_to_homepage() {
if ( is_404() ) {
wp_redirect( home_url(), 301 );
exit();
}
}
add_action( 'template_redirect', 'custom_redirect_404_to_homepage' );
Burada wp_redirect() fonksiyonunun ikinci parametresi olan 301 dikkat cekici. 301 kalici yonlendirme anlamina gelir ve SEO acisindan oldukca önemlidir. Eger gecici bir yonlendirme yapmak istiyorsaniz 302 kullanabilirsiniz. Ancak 301 kullanarak Google’a “bu sayfa artik burada degil, buraya bak” mesajini veriyorsunuz.
URL Kalibina Göre Akilli Yönlendirme
Gercek dunya senaryolarinda tek tip yonlendirme yeterli olmaz. Diyelim ki eski blog yazilarinizi /haberler/ path’inden /blog/ path’ine tasidiiniz. Bu durumda tüm eski linklerin yeni lokasyona yönlendirilmesi gerekiyor.
function smart_404_redirect() {
if ( ! is_404() ) {
return;
}
$request_uri = $_SERVER['REQUEST_URI'];
// Eski /haberler/ path'ini /blog/'a yonlendir
if ( strpos( $request_uri, '/haberler/' ) !== false ) {
$new_url = str_replace( '/haberler/', '/blog/', $request_uri );
wp_redirect( home_url( $new_url ), 301 );
exit();
}
// Eski /urunler/ path'ini /shop/'a yonlendir
if ( strpos( $request_uri, '/urunler/' ) !== false ) {
$new_url = str_replace( '/urunler/', '/shop/', $request_uri );
wp_redirect( home_url( $new_url ), 301 );
exit();
}
// Hicbiri eslesmediyse anasayfaya yonlendir
wp_redirect( home_url( '/' ), 302 );
exit();
}
add_action( 'template_redirect', 'smart_404_redirect' );
Bu örnekte URL içinde belirli kaliplari ariyoruz ve buldugumuzda ilgili yeni URL’e yonlendiriyoruz. Bu teknik ozellikle büyük site migrasyonlarinda son derece islevseldir.
Regex ile Gelismis URL Eslesme
Bazen URL kaliplari daha karmasik olabilir. Ornegin, tarih bazli eski URL yapiniz varsa regex kullanmak daha mantiklidir.
function regex_based_404_redirect() {
if ( ! is_404() ) {
return;
}
$request_uri = trim( $_SERVER['REQUEST_URI'], '/' );
// Eski tarih bazli URL yapisi: /2019/01/15/yazi-basligi/
// Yeni yapi: /blog/yazi-basligi/
$pattern = '/^(d{4})/(d{2})/(d{2})/(.+)$/';
if ( preg_match( $pattern, $request_uri, $matches ) ) {
$slug = $matches[4];
// Slug ile yazinin var olup olmadigini kontrol et
$post = get_page_by_path( $slug, OBJECT, 'post' );
if ( $post ) {
wp_redirect( get_permalink( $post->ID ), 301 );
exit();
} else {
// Yazi yoksa blog sayfasina yonlendir
wp_redirect( home_url( '/blog/' ), 302 );
exit();
}
}
}
add_action( 'template_redirect', 'regex_based_404_redirect' );
Bu ornekte ozellikle güçlü bir yaklasim var: yonlendirme yapmadan önce hedef sayfanin gercekten var olup olmadigini get_page_by_path() ile kontrol ediyoruz. Var olan bir sayfaya 301 ile yönlendiriyoruz, yoksa genel bir sayfaya 302 ile gönderiyoruz.
404 Olaylarini Loglama
Yonlendirme yapmak güzel ama hangi URL’lerin 404 ürettigi hakkinda veri toplamak daha da güçlüdür. Bu veriyi toplayarak daha bilinçli kararlar alabilirsiniz.
function log_404_errors() {
if ( ! is_404() ) {
return;
}
$log_data = array(
'url' => home_url( $_SERVER['REQUEST_URI'] ),
'referer' => isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : 'Direkt',
'user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : 'Bilinmiyor',
'tarih' => current_time( 'mysql' ),
'ip' => $_SERVER['REMOTE_ADDR'],
);
// Mevcut loglari al
$existing_logs = get_option( 'custom_404_logs', array() );
// Yeni logu ekle
array_push( $existing_logs, $log_data );
// Son 100 kaydi tut, daha eskilerini sil
if ( count( $existing_logs ) > 100 ) {
$existing_logs = array_slice( $existing_logs, -100 );
}
update_option( 'custom_404_logs', $existing_logs );
}
add_action( 'wp', 'log_404_errors' );
Bu log sistemi, WordPress options tablosunu kullanarak son 100 adet 404 hatasini saklar. Admin panelinden bu verilere erisebilmek icin basit bir yonetim sayfasi da olusturabilirsiniz. Ancak cok yogun trafik alan sitelerde bu yaklasim options tablosunu yorabilir; bu durumda custom bir veritabani tablosu ya da dosya bazli loglama daha sagliklı olur.
WooCommerce Için Özel 404 Yönlendirmeleri
WooCommerce kullananlar icin 404 yonetimi biraz daha spesifik olabilir. Silinmis bir ürün sayfasina gelen kullanici ne yapacagini bilemez. En mantikli yaklasim, kullaniciyi ilgili ürün kategorisine yönlendirmek ya da genel shop sayfasina göndermektir.
function woocommerce_product_404_redirect() {
if ( ! is_404() ) {
return;
}
$request_uri = $_SERVER['REQUEST_URI'];
// URL'de /urun/ veya /product/ kalibini ara
if ( strpos( $request_uri, '/urun/' ) !== false || strpos( $request_uri, '/product/' ) !== false ) {
// URL'den slug'i cikarmaya calis
$path_parts = explode( '/', trim( $request_uri, '/' ) );
$slug = end( $path_parts );
// Bu slug'la eslesen bir kategori var mi kontrol et
$term = get_term_by( 'slug', $slug, 'product_cat' );
if ( $term ) {
// Kategori varsa oraya yonlendir
wp_redirect( get_term_link( $term ), 301 );
exit();
}
// Yoksa genel shop sayfasina yonlendir
if ( function_exists( 'wc_get_page_id' ) ) {
$shop_url = get_permalink( wc_get_page_id( 'shop' ) );
wp_redirect( $shop_url, 302 );
exit();
}
}
// Sepet veya hesap sayfasi 404 aliyorsa
if ( strpos( $request_uri, '/sepet/' ) !== false || strpos( $request_uri, '/cart/' ) !== false ) {
if ( function_exists( 'wc_get_page_id' ) ) {
$cart_url = get_permalink( wc_get_page_id( 'cart' ) );
wp_redirect( $cart_url, 301 );
exit();
}
}
}
add_action( 'template_redirect', 'woocommerce_product_404_redirect' );
Bu kod, WooCommerce’e özgü URL yapilarini yakaliyor ve mantikli yerlere yonlendiriyor. Ürün URL’lerinde önce kategori eslesmesi deniyor, bulunamazsa genel magaza sayfasina gidiliyor.
Özel 404 Sayfasi Içerigi Olusturma
Yonlendirme yapmak yerine kullaniciyi bilgilendirici ve marka ile uyumlu bir 404 sayfasinda tutmak isteyebilirsiniz. Bu durumda functions.php üzerinden 404 sablonuna özel içerik enjekte edebilirsiniz.
function custom_404_page_content( $template ) {
if ( ! is_404() ) {
return $template;
}
// 404 sayfasina özel query'ler ayarla
// Populer yazilari sorgula
$popular_posts_query = new WP_Query( array(
'post_type' => 'post',
'posts_per_page' => 5,
'orderby' => 'comment_count',
'order' => 'DESC',
'post_status' => 'publish',
) );
// Bu veriyi global olarak kullanilabilir hale getir
set_query_var( '404_popular_posts', $popular_posts_query );
// Arama sonuclarina göre öneri yap
$request_uri = $_SERVER['REQUEST_URI'];
$search_term = str_replace( array( '/', '-', '_' ), ' ', trim( $request_uri, '/' ) );
$search_term = sanitize_text_field( $search_term );
// Bu arama terimiyle eslesen yazilari bul
$suggested_posts = new WP_Query( array(
'post_type' => 'post',
'posts_per_page' => 3,
's' => $search_term,
'post_status' => 'publish',
) );
set_query_var( '404_suggested_posts', $suggested_posts );
return $template;
}
add_filter( 'template_include', 'custom_404_page_content' );
Bu yaklasimda, kullanicinin ziyaret etmeye calistigi URL’den anlam cikarip benzer içerikleri öneriyor ve en populer yazilari gösteriyoruz. Bu, bounce rate’i düsürmek icin oldukca etkili bir yontemdir.
Admin Paneline 404 Raporu Ekleme
Loglama sistemini kurduktan sonra bu verileri admin panelinde görüntülemek için bir menü sayfasi olusturabiliriz.
function register_404_report_page() {
add_menu_page(
'404 Raporu',
'404 Raporu',
'manage_options',
'custom-404-report',
'render_404_report_page',
'dashicons-warning',
30
);
}
add_action( 'admin_menu', 'register_404_report_page' );
function render_404_report_page() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$logs = get_option( 'custom_404_logs', array() );
$logs = array_reverse( $logs ); // En yenileri basta göster
echo '<div class="wrap">';
echo '<h1>404 Hata Raporu</h1>';
// Loglari temizleme butonu
if ( isset( $_POST['clear_404_logs'] ) && check_admin_referer( 'clear_404_action' ) ) {
delete_option( 'custom_404_logs' );
echo '<div class="notice notice-success"><p>404 loglari temizlendi.</p></div>';
$logs = array();
}
echo '<form method="post">';
wp_nonce_field( 'clear_404_action' );
echo '<input type="submit" name="clear_404_logs" class="button button-secondary" value="Loglari Temizle">';
echo '</form><br>';
if ( empty( $logs ) ) {
echo '<p>Henüz 404 hatasi kaydedilmemis.</p>';
} else {
echo '<p><strong>Toplam kayit: ' . count( $logs ) . '</strong></p>';
foreach ( $logs as $log ) {
echo '<div style="border:1px solid #ddd; padding:10px; margin-bottom:10px; background:#fff;">';
echo '<strong>URL:</strong> ' . esc_html( $log['url'] ) . '<br>';
echo '<strong>Tarih:</strong> ' . esc_html( $log['tarih'] ) . '<br>';
echo '<strong>Referer:</strong> ' . esc_html( $log['referer'] ) . '<br>';
echo '<strong>IP:</strong> ' . esc_html( $log['ip'] ) . '<br>';
echo '</div>';
}
}
echo '</div>';
}
Bu kod ile admin panelinde “404 Raporu” adinda yeni bir menü ögesi olusuyor. Buradan hangi URL’lerin 404 ürettigini, nereden geldiklerini ve hangi tarihlerde gerceklestiklerini görebilirsiniz. Bu bilgi, yonlendirme kurallarinizi optimize etmek icin altin degerindedir.
Performans Optimizasyonu: Transient Kullanimi
Her 404 iste ekledigimiz agir sorgular performans sorunlarina yol acabilir. Bu noktada WordPress transient API’sini kullanmak akillica olur.
function optimized_404_handling() {
if ( ! is_404() ) {
return;
}
// Redirect map'ini cache'den al veya olustur
$redirect_map = get_transient( 'custom_404_redirect_map' );
if ( false === $redirect_map ) {
// Redirect map'i veritabanindan veya sabit listeden olustur
$redirect_map = array(
'/eski-sayfa-1/' => '/yeni-sayfa-1/',
'/eski-kategori/' => '/yeni-kategori/',
'/ekip/' => '/hakkimizda/',
'/iletisim-formu/' => '/iletisim/',
);
// Dinamik olarak silinmis yazilari da ekleyebilirsiniz
// Ornek: trash'teki yazilarin eski URL'lerini bul
$trashed_posts = get_posts( array(
'post_status' => 'trash',
'posts_per_page' => 50,
'post_type' => 'post',
) );
foreach ( $trashed_posts as $post ) {
$old_slug = $post->post_name;
// Kategorisine yonlendir
$categories = get_the_category( $post->ID );
if ( ! empty( $categories ) ) {
$redirect_map[ '/' . $old_slug . '/' ] = get_category_link( $categories[0]->term_id );
}
}
// 1 saatlik cache
set_transient( 'custom_404_redirect_map', $redirect_map, HOUR_IN_SECONDS );
}
$request_uri = $_SERVER['REQUEST_URI'];
// Redirect map'te tam eslesme ara
if ( isset( $redirect_map[ $request_uri ] ) ) {
wp_redirect( $redirect_map[ $request_uri ], 301 );
exit();
}
// Kismı eslesme dene
foreach ( $redirect_map as $old => $new ) {
if ( strpos( $request_uri, $old ) !== false ) {
wp_redirect( $new, 301 );
exit();
}
}
}
add_action( 'template_redirect', 'optimized_404_handling' );
Transient kullanimi sayesinde her 404 isteinde agir veritabani sorgulari yapmak yerine, sonuclari 1 saatligine cache’liyoruz. Bu özellikle silinmis post taramamasi gibi agir islemlerde ciddi performans kazanimi saglar.
En Sık Yapilan Hatalar
functions.php ile 404 yönetimi yaparken dikkat edilmesi gereken birkaç kritik nokta var:
- Sonsuz döngü riski:
home_url()sayfasi da 404 üretiyorsa sonsuz yonlendirme döngüsüne girebilirsiniz. Her zaman yonlendirme öncesinde hedef URL’in var oldugunu dogrulayin. - exit() eksikligi:
wp_redirect()fonksiyonundan sonra mutlakaexit()veyadie()cagrilmalidir, aksi halde PHP calismayi sürdürür. - Hook secimi:
template_redirecthook’u, sablon yuklenirken calisir. Bazı durumlardawphook’u daha erken calısir ama dikkatli kullanilmalidir. - Performans: Her 404 isteinde agir veritabani sorgulari yapmaktan kaçinin. Transient veya static array yontemiyle bu yuku azaltin.
- HTTP durum kodu karmasasi: Kalici tasinan sayfalar icin 301, gecici durumlar icin 302 kullanin. Yanlis HTTP kodu SEO’yu olumsuz etkiler.
- Güvenlik:
$_SERVER['REQUEST_URI']degerini kullanicilara göstermeden önce mutlakasanitize_text_field()veyaesc_url()ile temizleyin.
Gerçek Dünya Senaryosu: E-ticaret Sitesi Migrasyonu
Bir e-ticaret sitesini baska bir platformdan WooCommerce’e tasidığinizi düsünün. Eski platform /kategori/ürün-adi.html formatinda URL kullanirken, WooCommerce varsayilan olarak /urun/ürün-adi/ yapisini kullanır. Bu durumda yüzlerce ürün sayfasi 404 üretecektir.
Böyle bir senaryoda yapilmasi gereken:
- Eski URL listesini CSV veya veritabanindan al
- Bu URL’leri PHP array olarak
functions.php‘e ekle template_redirecthookunda eslestirme yap- Migrasyon tamamlandiktan sonra bu kodu kaldirip yerine
.htaccessyönlendirmeleri koy
Bu geçiş sürecinde functions.php çözümü, .htaccess düzenlemelerine kiyasla test edilmesi ve geri alinmasi cok daha kolay oldugu icin tercih edilir.
Sonuç
functions.php ile 404 yonetimi, WordPress sitelerinde sıklıkla göz ardi edilen ama aslında oldukca güçlü bir tekniktir. Dogru yapıldığında hem kullanici deneyimini iyilestirir hem de SEO kaybini minimize eder. Bu yazida ele aldigimiz yaklasimlar sirasiyla:
- Basit anasayfa yonlendirmesi ile islem hizlica baslatilebilir.
- URL kalibi eslesme ile göç sonrasi senaryolar ele alinabilir.
- Regex kullanimi ile karmasik URL yapilari yonetilebilir.
- Loglama sistemi ile sorunlu URL’ler tespit edilebilir.
- WooCommerce entegrasyonu ile magaza özelinde çözümler üretilebilir.
- Admin rapor sayfasi ile veriler görsellestirilip analiz edilebilir.
- Transient cache ile performans korunabilir.
Tüm bu kodlari körü körüne uygulamak yerine, önce sitenize özgü 404 kaynaklarini analiz edin. Google Search Console’daki “Kapsam” raporunu inceleyin, oradaki 404 URL’lerini listeleyin ve en çok trafik kaybi yasayan sayfalara odaklanin. Sonrasinda dogru yonlendirme mantigi ile bu kayiplari büyük ölcüde giderebilirsiniz.
Son olarak, functions.php‘i düzenlemeden önce mutlaka bir yedek alin ve degisiklikleri staging ortaminda test edin. Çocuk tema (child theme) kullaniyorsaniz bu kodlari çocuk temanin functions.php‘ine ekleyin; böylece tema güncellemelerinde kodlariniz kaybolmaz.
