İçeriğe geç
Approvalens

Okuma odası · 4 dk okuma

Next.js'te ads.txt Nasıl Eklenir? (App Router ve Pages Router)

Next.js sitesine ads.txt ekleme: /public içinde statik dosya ya da Route Handler, dosyaya dokunmayan proxy matcher'ı ve canlı alan adında kontrol.

Approvalens ekibi

Şu rapor bulgularını düzeltir

  • ads.txt dosyası
  • ads.txt içerik türü
  • ads.txt içindeki Google satırı
  • ads.txt biçimi
  • ads.txt yönlendirmesi

Next.js'te ads.txt düz bir dosyadır: public/ads.txt olarak kaydet, deploy et, https://alanadin.com/ads.txt adresinden sunulsun. App Router'da da Pages Router'da da aynı şekilde çalışıyor. Sorunların çoğu dosyayla Google arasındaki katmanlardan çıkıyor: adresi yeniden yazan bir proxy (eski adıyla middleware), kök alan adını dosyasız bırakan bir www kurulumu ya da bilinmeyen adreslere HTML döndüren bir hosting kuralı.

1. Satırını hazırla

AdSense sana kendi yayıncı kimliğinle tek bir satır veriyor (ads.txt rehberi):

google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0

pub- ve 16 rakam. Reklam kodundaki ca- öneki ads.txt'ye yazılmaz. Başka reklam ağları kullanıyorsan onların satırları da aynı dosyaya girer. Biçim kuralları ve hatalar genel ads.txt kurulumu rehberinde.

2. Dosyayı /public klasörüne koy

projem/
├── app/            (ya da pages/)
├── public/
│   └── ads.txt     ← /ads.txt adresinden sunulur
└── next.config.ts

Next.js, public içindeki her şeyi kökten sunuyor: bu dosyalara "kök adresten (/) başlayarak" ulaşılıyor (public klasörü). app/ içinde ads.txt için özel bir dosya kuralı yok. Metadata kuralları ikonları, manifest'i, Open Graph görsellerini, robots.txt ve sitemap.xml'i kapsıyor, fazlasını değil (metadata dosyaları).

Dosyayı Word gibi bir programda değil, kod editöründe UTF-8 düz metin olarak kaydet ve sonuna bir satır sonu bırak.

Next.js uygulamasında /ads.txt isteğinin üç olası sonu: public/ads.txt'den 200 ile sunulması, app/ads.txt/route.ts ile üretilmesi ya da matcher'sız bir proxy'ye takılıp 404 dönen /tr/ads.txt adresine yönlenmesi
/ads.txt'ye giden iki çalışan yol ve ikisini de bozan proxy tuzağı.

Alternatif: Route Handler

Yayıncı kimliği bir ortam değişkeninden gelecekse ya da aynı kodu birden fazla alan adına deploy ediyorsan dosyayı üret. Route Handler'lar HTML dışı yanıt döndürebiliyor ve dokümanda tam bu iş için noktalı bir klasör adı kullanılıyor (app/rss.xml/route.ts) (Route Handlers):

// app/ads.txt/route.ts
export const dynamic = "force-static";

export function GET() {
  const line = `google.com, ${process.env.ADSENSE_PUB_ID}, DIRECT, f08c47fec0942fa0`;
  return new Response(line + "\n", {
    headers: { "Content-Type": "text/plain; charset=utf-8" },
  });
}

force-static yanıtı bir kez üretiyor. output: 'export' kullanıyorsan da zorunlu, çünkü statik dışa aktarımda Route Handler'ların statik işaretlenmesi gerekiyor (statik dışa aktarım). ADSENSE_PUB_ID canlı ortamda tanımlı mı, kontrol et. Tanımlı değilse dosyada google.com, undefined, DIRECT… yazar, bu da hiç dosya olmamasından kötü. public/ads.txt ya da Route Handler: ikisinden birini tut, ikisini birden değil.

İki yöntemi de Next.js 16.3 ile geliştirme ortamında denedik. İkisi de 200 durum kodu ve text/plain içerik türü döndürdü.

3. proxy.ts'yi dosyadan uzak tut

Next.js 16'da middleware.ts'nin adı proxy.ts oldu. Doküman açıkça uyarıyor: matcher yoksa Proxy, public/ klasöründeki dosyalar dahil "her istekte" çalışıyor (proxy.js). ads.txt için tipik sonuçları şunlar:

  • dil öneki ekleyen bir proxy /ads.txt isteğini var olmayan /tr/ads.txt adresine gönderir;
  • oturum kontrolü yapan bir proxy Google botunu /giris sayfasına atar;
  • bir bot filtresi tarayıcı olmayan her isteğe 403 döndürür.

Dosyaları matcher'ın dışında bırak. Resmî örnek favicon.ico, sitemap.xml ve robots.txt'yi adıyla dışarıda bırakıyor. Nokta içeren her yolu atlamak ads.txt'yi de kapsar:

// proxy.ts
export const config = {
  matcher: ["/((?!api|_next|.*\\..*).*)"],
};

next.config içindeki rewrite'lara da bak. public dosyaları beforeFiles rewrite'larından sonra, normal rewrite'lardan önce sunuluyor (rewrites). Yani harici bir CMS'e giden genel bir beforeFiles rewrite'ı /ads.txt'yi yakalayabilir.

4. Kök alan adı yanıt versin

Google kök alan adından başlıyor: "www.domain.com/ads.txt üzerindeki bir ads.txt dosyası, yalnızca domain.com/ads.txt ona yönlendiriyorsa taranır" (tarama kuralları). Bot ayrıca hem HTTP hem HTTPS'i deniyor.

  • Vercel, Netlify ve benzerlerinde projeye hem ornekblog.com hem www.ornekblog.com adresini ekle ve hosting'in alan adı ayarlarında birini diğerine yönlendir. Sonra yönlendirmenin yolu koruduğunu doğrula: ornekblog.com/ads.txt ana sayfaya değil, www.ornekblog.com/ads.txt adresine gitmeli.
  • next.config içinde host'a göre yönlendirme yapabilirsin. permanent: true 308 gönderir. Klasik 301 istiyorsan onun yerine statusCode kullan (redirects):
// next.config.ts
async redirects() {
  return [{
    source: "/:path*",
    has: [{ type: "host", value: "www.ornekblog.com" }],
    destination: "https://ornekblog.com/:path*",
    statusCode: 301,
  }];
}

next.config yönlendirmeleri "sayfalar ve /public dosyaları dahil dosya sisteminden önce" kontrol ediliyor, yani /ads.txt için de geçerli. output: 'export' ile çalışmıyorlar. O durumda yönlendirmeyi hosting'de kurman gerekiyor. DNS tarafını Cloudflare'de www yönlendirme rehberinde anlattık.

5. Statik dışa aktarım ve diğer hosting'ler

output: 'export' ile public/ads.txt, out/ klasörüne kopyalanıyor. Sonrası hosting'e bağlı. Cloudflare Pages, projede 404.html yoksa siteyi tek sayfalık uygulama sayıyor ve olmayan adreslere ana sayfayı sunuyor. Böylece eksik bir ads.txt, 200 dönen bir HTML sayfası gibi görünüyor. Ayrıntılar Cloudflare Pages ve Workers'ta ads.txt rehberinde.

Canlı alan adında kontrol et

curl -sI https://ornekblog.com/ads.txt
curl -sI http://ornekblog.com/ads.txt
curl -s  https://ornekblog.com/ads.txt
Bir Next.js geliştirme sunucusuna curl -i isteğinin terminal çıktısı: HTTP/1.1 200 OK, Content-Type text/plain; charset=UTF-8, Content-Length 59 ve ardından tek Google satırı
Çalışan bir yanıt böyle görünür. Örnek kimlikle yaptığımız Next.js 16.3 testinin gerçek çıktısı.

Görmek istediğin sonuç: 200 kodu (doğrudan ya da tek yönlendirmeden sonra), text/plain ve gövdede Google satırın. Hiçbir yerde <html> olmamalı. ads.txt kontrol aracı bu kontrolleri yapıyor ve kimliği AdSense kodunla karşılaştırıyor. robots.txt'de Disallow: /ads gibi bir kural varsa /ads.txt'yi de engeller. robots.txt test aracıyla dene.

Gördüğün Next.js'teki olası neden Çözüm
/ads.txt 404 Dosya public dışında ya da public/static/ altında public/ads.txt konumuna taşı
/tr/ads.txt'ye 307/308 Dosyaları dışarıda bırakmayan dil proxy'si Yukarıdaki matcher'ı ekle
/giris'e 302 Oturum proxy'si Dosyaları ve herkese açık sayfaları matcher dışında bırak
HTML ile 200 Genel rewrite ya da hosting'in SPA yedeği Dosya rewrite'lardan önce sunulsun, statik hosting'de 404.html ekle
Satırda undefined Canlıda ortam değişkeni olmayan Route Handler ADSENSE_PUB_ID'yi tanımla ya da statik dosyaya geç
www'de çalışıyor, kökte 404 Kök alan adı bağlı değil ya da yönlendirmiyor Kök alan adını ekle ve yönlendir

AdSense'in değişikliği görmesi zaman alıyor. Google bunun "birkaç gün" sürebileceğini, az reklam isteği alan sitelerde bir aya kadar uzayabileceğini söylüyor (ads.txt rehberi).

Başvurmadan önce canlı alan adında ücretsiz site taramasını çalıştır. Tarama ads.txt'yi HTTP ve HTTPS üzerinden, www'li ve www'siz çekiyor. Böylece Google botunun tam olarak ne aldığını görürsün. Kurulumun geri kalanı, yani render, kodun yeri ve onay yönetimi Next.js AdSense rehberinde.

Eskimiş ya da yanlış bir şey mi gördün? Bize yaz, düzeltelim.

Bu rehberi İngilizce oku →

Kendi sitende kontrol et. Ücretsiz, kayıt yok.

Bunun için ücretsiz araçlar

Ücretsiz tarama

Kendi siteni kontrol et

Ücretsiz tarama: uygunluk puanı ve tüm sorunlar, genelde birkaç dakikada.

Ücretsiz tarama · puan ve bulunan tüm sorunlar · üyelik yok

Tüm rehberler →