Geliştirici dokümanları

Entegrasyon

Bir ziyaretçi 404'e düştüğünde no404'e sorarsınız, en uygun URL'yi alırsınız ve oraya yönlendirirsiniz. Bunu üç farklı yoldan yapabilirsiniz — aralarındaki fark ziyaretçinin gördüğü şey değil, arama motorunun gördüğü HTTP durumudur.

Hangi yolu seçmeliyim?

Üçü de ziyaretçiyi doğru sayfaya götürür. Fark sunucunun döndürdüğü HTTP durumundadır ve bu fark SEO'da belirleyicidir: 301 alan bir adres birikmiş değerini yenisine taşır, 404 kalan bir adres taşımaz.

YolHTTP durumuKimin için
WordPress eklentisi301WordPress siteleri. Kod yazmadan, panelden kurulur.
PrestaShop modülü301PrestaShop 8 ve 9 mağazaları. Kod yazmadan, zip ile kurulur.
Laravel paketi301Laravel 12 ve 13 uygulamaları. Composer ile kurulur, entegrasyon kodu yazılmaz.
Node.js paketi301Express, Fastify, Hono ve Next.js uygulamaları. npm ile kurulur, entegrasyon kodu yazılmaz.
Sunucu tarafı301Kendi kodunu yazan herkes. Hazır bir şartname veriyoruz.
Tarayıcı snippet'i404 kalırSunucuya erişimi olmayan ya da beş dakikada denemek isteyen.
Snippet en kolay yoldur ama tek yapamadığı şey HTTP durumunu değiştirmektir: sayfa ziyaretçi için taşınır, arama motoru için ölü kalır. Sunucunuza erişiminiz varsa 301 üreten yollardan birini seçin.

WordPress eklentisiWordPress.org'da yayımlandı

404'ü sunucu tarafında yakalar, no404'e sorar ve gerçek bir 301 döndürür. Tema dosyalarına dokunmaz, kod yazmanızı gerektirmez.

  • WordPress 6.0+ · PHP 7.4+
  • Sonuçları yerel olarak önbelleğe alır — kotanızı ve hız sınırını korur.
  • no404 yanıt vermezse sayfa normal 404'üne düşer (fail-open); eklenti siteyi asla bekletmez.

Kurulum

  1. WordPress yönetiminde Eklentiler → Yeni Ekle bölümünde no404 aratın.
  2. Şimdi Kur deyip etkinleştirin.
  3. Panelden aldığınız API anahtarını eklenti ayarlarına yapıştırın.
Eklenti resmi WordPress dizininde yayımlanmıştır ve açık kaynaktır (kaynak kod). Dizinden kurun: .zip elle yüklenebilir ama o kurulum otomatik güncelleme almaz — güvenlik yaması çıktığında siteniz eski sürümde kalır.

PrestaShop modülü

404'ü sunucu tarafında yakalar — silinmiş ürün ve kategoriler dahil —, no404'e sorar ve gerçek bir 301 döndürür. Override kullanmaz, tema dosyalarına dokunmaz.

  • PrestaShop 9.0+ → 2.x hattı (PHP 8.1+) · PrestaShop 8.0–8.2 → 1.x hattı (PHP 7.2+) · cURL eklentisi ve dostu URL'ler (SEO URL'leri) açık olmalı
  • Sonuçları mağaza başına yerel önbelleğe alır; çoklu mağazada her mağaza kendi API anahtarını tutabilir.
  • no404 yanıt vermezse mağazanızın kendi 404 sayfası gösterilir; 1,5 sn zaman aşımı ve devre kesici mağazayı asla bekletmez.

Kurulum

  1. Mağazanızın sürümüne uygun zip'i indirin: PrestaShop 9 → 2.x, PrestaShop 8 → 1.x.
  2. Modüller → Modül Yöneticisi → Modül yükle ile zip'i açmadan yükleyin.
  3. no404 → Yapılandır ekranında panelden aldığınız API anahtarını yapıştırıp bağlantıyı test edin.
Modül açık kaynaktır (kaynak kod). PrestaShop Addons pazarında henüz yok; elle yüklenen modül otomatik güncelleme almaz — yeni sürüm çıktığında zip'i yeniden yükleyin, ayarlarınız korunur. Mağazanızı PrestaShop 8'den 9'a yükselttiğinizde 2.x zip'ini yükleyin: modül güncellemesi olarak kurulur.

Laravel paketi

Uygulamanız 404 döndürdüğünde (eşleşmeyen rota, abort(404), findOrFail, Route::fallback()) no404'e sorar ve gerçek bir 301 ya da 302 döndürür. Middleware kendini kaydeder; exception handler'ınıza dokunmanız gerekmez.

  • Laravel 12 · 13 · PHP 8.2+ (Laravel 13 için 8.3+) · istekler arasında kalıcı bir önbellek deposu (redis, database, file…)
  • Yanıtları yol başına önbelleğe alır, eşleşmeyenler dahil. Statik dosyalar, /storage, /livewire, /api ve yönetim yolları hiç sorulmaz.
  • no404 yavaş ya da erişilemezse ziyaretçi en geç 1,5 sn içinde uygulamanızın kendi 404 sayfasını görür; sorgular bir dakika duraklar.

Kurulum

Paketi kurun:

composer require no404/laravel

Panelden aldığınız API anahtarını .env dosyasına ekleyin:

NO404_API_KEY=SENIN_API_ANAHTARIN

Bağlantıyı kontrol edin, sonra panelde Entegrasyon → Test et ile doğrulayın:

php artisan no404:test
Paket açık kaynaktır (kaynak kod) ve Packagist üzerinden dağıtılır; güncellemeler composer update ile gelir. APP_URL sitenizin gerçek adresi olmalı, çünkü hedefler yalnızca o alan adında kabul edilir. Laravel 11 ve öncesi desteklenmez; oralarda sunucu tarafı entegrasyonu kullanın.

Node.js paketi

Uygulamanız 404 döndüreceği anda no404'e sorar ve gerçek bir 301 ya da 302 döndürür. Next.js App Router'da sayfa katmanı yalnızca 308 ve 307 üretebildiği için 301 → 308, 302 → 307 olur; Google ikisini de aynı anlamda sayar.

  • Node.js 22.12+ · Express · Fastify · Hono · Next.js · çalışma zamanı bağımlılığı yok
  • Yanıtları yol başına önbelleğe alır, eşleşmeyenler dahil; aynı ölü bağlantıya aynı anda gelen istekler tek sorguda birleşir. Sunucusuz platformlarda (Vercel, Lambda, Workers) paylaşımlı önbellek önerilir: Redis ya da Cloudflare KV. Reklamdan ya da bir yapay zekâ asistanından gelen tıklama önbelleği atlar, böylece no404 her birini sayar; no404'e ulaşılamazsa önbellekteki yanıt yine kullanılır.
  • no404 yavaş ya da erişilemezse ziyaretçi en geç 1,5 sn içinde uygulamanızın kendi 404 sayfasını görür; sorgular bir dakika duraklar.

Kurulum

Paketi kurun:

npm install @no404/node

Panelden aldığınız API anahtarını ve sitenizin adresini sunucunun ortam değişkenlerine ekleyin (NEXT_PUBLIC_ önekiyle DEĞİL — anahtar tarayıcıya gitmemeli):

NO404_API_KEY=SENIN_API_ANAHTARIN
NO404_SITE_URL=https://magazaniz.com

Express'te bütün rotalarınızdan sonra, kendi 404 işleyicinizden önce bağlayın:

import express from "express";
import { createNo404 } from "@no404/node";
import { no404Express } from "@no404/node/express";

const app = express();
// … rotalarınız …
app.use(no404Express(createNo404()));

Next.js App Router'da iki küçük dosya yeterli: proxy.ts (Next 15'te middleware.ts) orijinal adresi taşır, eşleşmeyen adresleri yakalayan app/[...rest]/page.tsx sorar. Sorguyu app/not-found.tsx içine KOYMAYIN: Next o dosyayı her sayfanın yanıtına gömer, sorgu 200 dönen sayfalarda da çalışır ve hakkınızdan boşuna düşer. Zaten bir proxy.ts'iniz varsa döndürdüğünüz yanıtın istek başlıklarına withNo404Headers(request) verin. Silinmiş ürün sayfalarında notFound() yerine notFoundOrRedirect() kullanın:

// proxy.ts
import { NextResponse, type NextRequest } from "next/server";
import { withNo404Headers } from "@no404/node/next/proxy";

export function proxy(request: NextRequest) {
  return NextResponse.next({ request: { headers: withNo404Headers(request) } });
}

export const config = { matcher: ["/((?!_next/|api/|favicon.ico).*)"] };

// app/[...rest]/page.tsx
import { createNo404 } from "@no404/node";
import { resolveNotFound } from "@no404/node/next";
import { notFound } from "next/navigation";

const no404 = createNo404();

export default async function UnmatchedPath() {
  await resolveNotFound(no404);
  notFound();
}

Ortamı kontrol edin ve anahtarı tek bir sorguyla deneyin, sonra panelde Entegrasyon → Test et ile doğrulayın:

npx @no404/node doctor
npx @no404/node resolve /14-gram-altin-yuzuk-102
Paket açık kaynaktır (kaynak kod) ve npm üzerinden dağıtılır; güncellemeler npm update ile gelir. Fastify, Hono ve Pages Router örnekleri paketin README'sinde. Statik dışa aktarma (output: export) sunucu çalıştırmadığı için desteklenmez.

Sunucu tarafı entegrasyon

Kendi kodunuzu yazıyorsanız 404 ürettiğiniz yerde no404'e sorup gerçek bir 301 döndürebilirsiniz. Bunu sıfırdan kurgulamanız gerekmiyor: panel, siteniz için hazır bir entegrasyon şartnamesi üretir.

Şartname bir kod parçası değil, bir mühendislik belgesidir: zaman aşımı, zorunlu önbellek, kara liste, 301/302 kuralı, döngü ve açık yönlendirme koruması dahil. Dosyayı geliştiricinize ya da doğrudan kod yazan bir yapay zekâ ajanına verirsiniz.

Panel → site detay → Entegrasyon sekmesinden indirin. Şartname sitenizin adresine ve ayarlarına göre üretilir; kopyasını buraya koymuyoruz — iki yerde tutulan bir belge er geç ikiye ayrılır.

Önbellek opsiyonel değildir

Sunucudan sunucuya çağrıda tüm trafiğiniz tek bir IP'den sayılır ve hız sınırı (dakikada 120 istek) o IP'ye uygulanır. Yanıtları yerel olarak önbelleğe almazsanız yoğun bir sitede sınıra çarpar ve yönlendirmeler sessizce durur. Şartname bunu zorunlu bir madde olarak içerir.

En yalın hâli (Node.js)

const res = await fetch(
  "https://www.no404.tr/api/v1/resolve?path=" + encodeURIComponent(path),
  { headers: { Authorization: "Bearer SENIN_API_ANAHTARIN" } }
);
const data = await res.json();

// redirectStatus, panelde seçtiğiniz 301 eşiğine göre 301 ya da 302 gelir.
if (data.redirect) {
  const status = data.redirectStatus === 301 ? 301 : 302;
  // Express: res.redirect(status, data.redirect);
}

Tarayıcı snippet'i

Bu yol HTTP durumunu 404 bırakır

Yönlendirme JavaScript ile yapılır; sunucu yine 404 döndürmüş olur. Ziyaretçi doğru sayfaya gider ama arama motoru eski adresi ölü saymaya devam eder ve link değeri aktarılmaz. Sunucunuza erişebiliyorsanız yukarıdaki iki yoldan birini seçin.

Anahtar herkese açıktır: kod parçasındaki anahtar sayfa kaynağında görünür. Anahtarınızla gelen her istek, bot ya da kötü niyetli trafik dahil, aylık hakkınızdan düşer (Kullanım Koşulları §2). Sunucu tarafı entegrasyonda anahtar sunucunuzda kalır.

Aşağıdaki kodu sitenizin 404 sayfasına ekleyin. SENIN_API_ANAHTARIN yerine panelden aldığınız API anahtarını yazın.

<!-- no404: 404 sayfanıza ekleyin -->
<script>
(function () {
  var p = location.pathname + location.search;
  var ref = document.referrer;
  fetch("https://www.no404.tr/api/v1/resolve/SENIN_API_ANAHTARIN?path=" + encodeURIComponent(p) + "&ref=" + encodeURIComponent(ref))
    .then(function (r) { return r.json(); })
    .then(function (d) { if (d && d.redirect) location.replace(d.redirect); })
    .catch(function () {});
})();
</script>

Next.js (App Router)

app/not-found.tsx içine:

"use client";
import { useEffect } from "react";

export default function NotFound() {
  useEffect(() => {
    const p = location.pathname + location.search;
    fetch(`https://www.no404.tr/api/v1/resolve/SENIN_API_ANAHTARIN?path=${encodeURIComponent(p)}&ref=${encodeURIComponent(document.referrer)}`)
      .then((r) => r.json())
      .then((d) => { if (d.redirect) location.replace(d.redirect); })
      .catch(() => {});
  }, []);
  return <p>Sayfa bulunamadı, yönlendiriliyorsunuz…</p>;
}
API anahtarınızı ve izinli origin'lerinizi panel → site detay sayfasından yönetirsiniz.

Endpoint referansı

Üç yolun da kullandığı tek endpoint; hem GET hem POST destekler.

Anahtar iki yoldan gönderilebilir ve ikisinin kuralı farklıdır. Adreste giderse (/api/v1/resolve/ANAHTAR) bu tarayıcı yoludur: isteği bir sayfa yaptığı için Origin başlığı zorunludur ve sitenizin izinli listesinde olmalıdır. Authorization: Bearer başlığında giderse (/api/v1/resolve) istek sunucunuzdan gelmiş sayılır, Origin aranmaz. Sunucudan çağırıyorsanız başlığı kullanın: adresteki anahtar sunucu ve proxy günlüklerine düşer, başlık düşmez.

GETPOST/api/v1/resolve/{apiKey}

Parametreler

apiKeyyol (path)Sitenizin API anahtarı. Authorization başlığı kullanmıyorsanız zorunlu. Bu yolda Origin başlığı da zorunludur.
pathquery / gövde404 dönen yol, örn. /eksik-sayfa (zorunlu).
refquery / gövdeZiyaretçinin geldiği adres (document.referrer). İsteğe bağlı; boş = doğrudan giriş.
adquery / gövdeReklam kategorisi: google, microsoft, meta ya da other. İsteğe bağlı; sorgu dizesini göndermeyen sunucu entegrasyonu kategoriyi kendisi çıkarıp bildirir. Ham tıklama kimliği (gclid) göndermeyin.
Authorizationbaşlık (header)Bearer ANAHTAR. Başlık kullanıldığında adres /api/v1/resolve olur, anahtar adreste yer almaz ve Origin aranmaz.

GET örneği

curl "https://www.no404.tr/api/v1/resolve/SENIN_API_ANAHTARIN?path=/14-gram-altin-yuzuk-102" \
  -H "Origin: https://siteniz.com"

POST örneği

curl -X POST "https://www.no404.tr/api/v1/resolve/SENIN_API_ANAHTARIN" \
  -H "Content-Type: application/json" \
  -H "Origin: https://siteniz.com" \
  -d '{"path":"/14-gram-altin-yuzuk-102"}'

Başlıkla (sunucu tarafı için önerilen)

curl "https://www.no404.tr/api/v1/resolve?path=/14-gram-altin-yuzuk-102" \
  -H "Authorization: Bearer SENIN_API_ANAHTARIN"

Yanıt & durum kodları

Başarılı yanıt JSON döner:

{
  "success": true,
  "found": true,
  "redirect": "https://siteniz.com/14-gram-altin-yuzuk",
  "score": 0.92,
  "source": "CATALOG",
  "redirectStatus": 301
}

Yanıt alanları

foundbooleanKesin eşleşme bulundu mu (yedek yönlendirmede false olabilir).
redirectstring | nullYönlendirilecek tam URL. Dolu ise ziyaretçiyi buraya gönderin (yedek dahil).
scorenumberEşleşme skoru 0-1 arası (1 = manuel yönlendirme).
sourceenumREDIRECT (manuel) · CATALOG (otomatik) · FALLBACK (eşik altı: üst kategori ya da yedek adres) · NONE (yok).
redirectStatus301 | 302 | nullSunucu tarafında verilecek HTTP durumu. Site sahibinin panelde seçtiği 301 eşiğine göre hesaplanır: manuel yönlendirme ve eşiğin üstündeki katalog eşleşmesi 301, gerisi 302; yönlendirme yoksa null. Kendi eşiğinizi koda gömmeyin, bu alanı kullanın.

Durum kodları

200Başarılı (found true/false olabilir).
403Origin eksik ya da izinli değil, ya da izleme duraklatıldı.
404Geçersiz API anahtarı.
422Geçersiz veya eksik 'path'.
429Rate limit aşıldı (çok fazla istek).

Origin kilidi & güvenlik

API anahtarınız origin kilidi ile korunur. Anahtar adreste giderken istek yalnızca panelde tanımladığınız izinli origin'lerden kabul edilir; Origin başlığı hiç gelmediğinde de reddedilir. Anahtarınız sızsa bile başka bir alan adından gelen istek 403 alır ve CORS yanıtı verilmez.

  • Sitenizi eklediğinizde alan adınız otomatik izinli origin olarak eklenir (www + köksüz).
  • Ek alan adlarını panelden ekleyebilirsiniz.
  • Anahtar sızıntısında panelden anahtarı yenileyin; eski anahtar o an geçersiz olur.
Kilit tarayıcı isteklerini kısıtlar. Sunucudan sunucuya çağrıda Origin başlığı gönderilmez, o yüzden Authorization: Bearer yolunda kilit devreye girmez ve koruma anahtarın gizliliğine ve hız sınırına kalır. Anahtarı sunucu tarafında tutun, istemciye gömmeyin.

En iyi pratikler

  • Sunucu tarafını tercih edin: 301 üreten tek yol odur; snippet SEO değerini taşımaz.
  • Yanıtları önbelleğe alın: sunucu tarafı entegrasyonda bu opsiyonel değildir — tüm trafik tek IP'den sayılır.
  • Sitemap'inizi bağlayın: eşleştirme kalitesi kataloğunuzun güncelliğine bağlıdır.
  • Eşiği gözden geçirin: çok agresif yönlendirme istemiyorsanız eşiği yükseltin (önerilen 0.3).
  • Kritik yollar için manuel yönlendirme tanımlayın; otomatik eşleştirmeyi ezer.
  • Hız sınırı: anahtar + IP başına dakikada 120 istek.

Hazır mısınız?

Sitenizi ekleyin, anahtarınızı alın, dakikalar içinde yayında.

Ücretsiz Kayıt Ol