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.

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.txtisteğini var olmayan/tr/ads.txtadresine gönderir; - oturum kontrolü yapan bir proxy Google botunu
/girissayfası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.comhemwww.ornekblog.comadresini ekle ve hosting'in alan adı ayarlarında birini diğerine yönlendir. Sonra yönlendirmenin yolu koruduğunu doğrula:ornekblog.com/ads.txtana sayfaya değil,www.ornekblog.com/ads.txtadresine gitmeli. next.configiçinde host'a göre yönlendirme yapabilirsin.permanent: true308 gönderir. Klasik 301 istiyorsan onun yerinestatusCodekullan (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

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
- /tools/ads-txt-checkerads.txt Kontrol Aracı/ads.txt dosyasının her satırını doğrular, Google'ın senin yayıncı kimliğinle listelendiğini kontrol eder.Aracı aç
- /tools/robots-txt-testerrobots.txt Test AracıBir adresi AdSense botu, Googlebot ve AdsBot için robots.txt kurallarına karşı test eder.Aracı aç
Ücretsiz tarama
Kendi siteni kontrol et
Ücretsiz tarama: uygunluk puanı ve tüm sorunlar, genelde birkaç dakikada.