Files
kolaytercih/docs/arastirma/2026-09-24-geo-seo/01-teknik-denetim.md
bilalgursen 24d4bea32c
All checks were successful
Deploy / deploy (push) Successful in 6m16s
feat(geo): llms.txt, RSS, IndexNow, Article yazar/görsel, bölüm sayfasına veri özeti, vakıf bursu yazısı
GEO araştırması (docs/arastirma/2026-09-24-geo-seo) Dalga 1-2 uygulaması:
- /llms.txt ve /feed.xml route'ları (getAllRehberler'den otomatik), head'de RSS linki
- Article JSON-LD: author, image, mainEntityOfPage, publisher logo; görünür 'Yazan' satırı
- robots: ClaudeBot ayrı grupta Crawl-delay 1
- scripts/indexnow.ts (pnpm indexnow) + public anahtar dosyası
- bölüm sayfası açılışı veriden üretilen özgü cümleler (il/program/tür/kontenjan, taban aralığı, yıllık yön)
- ana sayfa fiyat iddiasına kaynak; iki yazıda 23.000 -> 21.000+; beş yazıya 'Kısa cevap' açılışı
- yeni yazı: vakif-universitesi-bursu-kesilir-mi (ÖSYM 2026 kılavuzu + YÖK ücret esasları)
- YAYIN-KUYRUGU: IndexNow adımı ve aylık AI görünürlük rutini

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 17:42:29 +03:00

90 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GEO/SEO Teknik Denetim — 2026-09-24
Kanıt işaretleri: **[D]** dosya/kod veya canlı curl çıktısı okundu · **[A]** yalnızca ikincil/arama kaynağı · **[Ç]** çıkarım · **[doğrulanmalı]** teyit edilmedi.
**Veri kısıtı:** Arama hacmi/rakip trafik aracı (Ahrefs/Similarweb) bu oturumda yetkili değil — bu raporda hacim rakamı yok. Tüm bulgular kod okuması (dosya:satır) ve canlı `curl` çıktısıyla [D] işaretli; tarayıcı/dev sunucusu açılmadı (AGENTS.md kuralı). Rybbit'e bu denetimde ihtiyaç duyulmadı.
## Özet (5 madde)
1. AI botlarına erişim tam açık: `robots.txt` GPTBot/ClaudeBot/PerplexityBot/Google-Extended dahil 17 botu `Allow: /` ile karşılıyor ve gerçek istekte hepsi 200 dönüyor, WAF/challenge yok — bu katman zaten doğru kurulmuş.
2. En büyük eksik yapılandırılmış veri: 863+ katalog sayfasının (634 bölüm + 229 üniversite) hiçbirinde tablodaki taban puanı/sıralama verisini makine-okunur kılan bir şema (Dataset/ItemList/Table) yok; yalnızca `BreadcrumbList` var. Rehber yazılarındaki `Article` şemasında `author` ve `image` alanı eksik.
3. `/llms.txt`, `/llms-full.txt`, `/feed.xml`, `/rss.xml` dördü de canlıda 404 — hiçbiri üretilmiyor; site 46 rehber yazısını ve katalog kapsamını hiçbir merkezi makine-okunur listede özetlemiyor.
4. İçerik tarafı zaten GEO'ya uygun yazılmış: "Kısa cevap" ile başlayan gövde, madde madde Soru-Cevap blokları, tarihli kaynak listesi, mermaid karar şeması — ama bu Soru-Cevap blokları `FAQPage` şemasına hiç bağlanmamış (yalnızca ana sayfadaki 4 soru `FAQPage` alıyor).
5. Sunucu HTML'i tam: tablo, taban puan trend grafiği (SVG+title), harita, veri kaynağı/tarih metni hepsi bot-erişilebilir ilk HTML'de geliyor (`curl` ile doğrulandı); ama tüm sayfalarda `Cache-Control: private, no-cache, no-store` ve `Last-Modified`/`ETag` yok — 1011 URL'lik sitemap'te crawl bütçesi açısından koşullu istek (If-Modified-Since) imkânı sıfır.
## Bulgular
| # | Bulgu | Kanıt | Etki | Efor |
|---|---|---|---|---|
| 1 | `Article` JSON-LD'de `author` yok, `image` yok | `src/lib/seo.tsx:149-172` (`articleJsonLd`); canlı `curl https://kolaytercih.com/rehber/kyk-burs-mu-kredi-mi` çıktısında `@type":"Article"` bloğunda `author`/`image` alanı yok [D] | Orta | 1s |
| 2 | Katalog sayfalarında (bölüm/il) tablo verisi için şema yok; yalnızca `BreadcrumbList` | `src/features/katalog/components/bolum-icerik.tsx:246-251`, `il-icerik.tsx:98-103` — ikisinde de tek `JsonLd` çağrısı `breadcrumbJsonLd`; `grep "@type"` sonucu ikisinde de sadece `BreadcrumbList` [D] | Yüksek | 4-6s |
| 3 | Üniversite sayfasında `CollegeOrUniversity` var ama bölüm/il sayfalarında karşılığı (`EducationalOccupationalProgram`/`Place`) yok | `universite-icerik.tsx:483-503` (`CollegeOrUniversity` + `PostalAddress`); canlı `curl https://kolaytercih.com/universite/abdullah-gul-universitesi` JSON-LD'de doğrulandı [D] | Orta | 3-4s |
| 4 | `FAQPage` yalnızca ana sayfada; rehber yazılarındaki Soru-Cevap blokları (`**Soru?**\nCevap.` deseni, ör. `kyk-burs-mu-kredi-mi.md` sonundaki 6 soru) şemaya bağlanmamış | `src/app/page.tsx:124-141` (tek kullanım yeri); `content/rehber/kyk-burs-mu-kredi-mi.md` içinde en az 6 açık soru-cevap çifti; `rehber-makale.tsx`'te `faqPageJsonLd` import edilmiyor [D] | Yüksek | 3-4s (içerik tarafında soru işaretleme kuralı + şema üretimi) |
| 5 | `/llms.txt`, `/llms-full.txt`, `/feed.xml`, `/rss.xml` 404 | `curl -o /dev/null -w "%{http_code}"` dördünde de `404`; `src/app/` altında bu route'lar yok (`find src/app -maxdepth 1 -iname "llms*" -o -iname "feed*"` boş sonuç) [D] | Yüksek | llms.txt 2s, feed.xml 3s |
| 6 | `Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate` — tüm sayfalarda (ana sayfa, rehber, katalog); `Last-Modified`/`ETag` hiçbir yanıtta yok | `curl -sI https://kolaytercih.com/`, `/rehber/kyk-burs-mu-kredi-mi`, `/universiteler/kayseri` üçünde de aynı başlık [D]; kaynak muhtemelen `next.config.ts:31` `cacheComponents: true` (PPR) — kök layout'ta `HeaderGate` gibi istek-anı dinamik parça olduğu için tüm yanıt no-store'a düşüyor [Ç] | Orta | Araştırma 2s + olası segment-config denemesi |
| 7 | `/bolum/[slug]/sayfa/[no]` ve `/universite/[slug]/sayfa/[no]` alt sayfaları (sayfalanmış tablo devamları) sitemap'te yok | `src/app/sitemap.ts:39-51` yalnızca taban `/bolum/{slug}` ve `/universite/{slug}` üretiyor, `/sayfa/{n}` yok; `sayfalama.tsx:52-69` bu alt yolların gerçek statik `<Link>` olduğunu doğruluyor [D] | Düşük | 1s (sitemap'e eklemek mi, bilinçli mi karar CTO'da) |
| 8 | Şehir haritası (`SehirPikselHaritasi`) client component | `sehir-piksel-haritasi.tsx:1` `"use client"` — ama dekoratif, kritik metin (üniversite listesi, YÖK Atlas kaynak satırı) ayrı server bileşeninde ve ilk HTML'de mevcut (canlı `curl` ile "YÖK Atlas" 7 kez, "ÖSYM" 9 kez bulundu) [D] | Düşük | — (aksiyon gerekmiyor, not amaçlı) |
| 9 | Üniversite program tablosu (`UniversiteProgramTablosu`) `"use client"` ama SSR kırılmıyor — `next/dynamic(ssr:false)` yalnızca sihirbaz/liste/dev-panel bileşenlerinde kullanılıyor, katalog/rehber hiçbirinde yok | `universite-program-tablosu.tsx:1`; `grep -rn "ssr: false"` sonucu 6 eşleşmenin hiçbiri katalog/rehber değil; canlı HTML'de `<table>` + 46-51 satır veri doğrulandı [D] | — | — (bulgu: sorun yok, doğrulama amaçlı) |
| 10 | `Organization` JSON-LD'de `sameAs` (sosyal/kurumsal profil linki) yok; `WebSite`'ta `potentialAction`/`SearchAction` yok | `src/lib/seo.tsx:76-100` | Düşük | 1s |
| 11 | Künye/Hakkında sayfası yok — E-E-A-T için "kim yazıyor, hangi veriyle" tek yerde toplu anlatılmıyor; yalnızca `/iletisim` var ve orada yalnızca e-posta + iade metni var, tüzel kimlik (unvan, adres) yok | `src/app/iletisim/page.tsx` tam dosya okundu — `Mail` ikonu + `destek@kolaytercih.com` dışında kurumsal bilgi yok; `find src/app -iname "hakkinda*" -o -iname "kunye*"` boş sonuç [D] | Orta | 2-3s (yeni sayfa) |
| 12 | Google Search Console doğrulama meta'sı `layout.tsx`'te yok | `grep google-site-verification src/app/layout.tsx` boş [D] | — | — (mülk `sc-domain:` DNS ile doğrulanıyor olmalı — AGENTS.md'deki Search Console notuyla tutarlı, aksiyon gerekmez) [Ç] |
| 13 | IndexNow/Bing anlık bildirim entegrasyonu kodda yok | `grep -rn "indexnow" src scripts` boş sonuç [D] | Düşük | 2-3s |
| 14 | Sitemap 1011 URL, tamamı tek `sitemap.xml`'de (Google limiti 50.000 URL/dosya — sorun değil bugün, ama büyüme notu) | `curl -s .../sitemap.xml \| grep -c "<url>"` → 1011; kırılım: 634 bölüm, 229 üniversite, 92 il, 46 rehber, 10 statik [D] | — | — (bilgi amaçlı, aksiyon yok) |
| 15 | `lastmod` değerleri katalog için tek sabit tarih (`KATALOG_VERI_TARIHI = "2026-09-21"`), rehber için yazı bazlı gerçek tarih — anlamlı, uydurma değil | `src/lib/seo.tsx:24`; sitemap çıktısında katalog URL'leri `2026-09-21`, rehber URL'leri kendi `tarih`/`guncelleme` alanı [D] | — | — (doğru kurulmuş, aksiyon yok) |
| 16 | AI botları için farklı davranış yok: `GPTBot/ClaudeBot/PerplexityBot/Google-Extended/Bingbot` + rastgele UA hepsi 200, içerik boyutu birbirine yakın (164.9–165.5 KB, fark muhtemelen script nonce/varyant) | 6 farklı UA ile `curl -A ... -w "%{http_code}"` testi [D] | — | — (doğru, aksiyon yok) |
## Önerilen uygulama sırası
**Dalga 1 — düşük efor, yüksek/orta etki (CTO'ya tek paket):**
1. `articleJsonLd`'ye `author` (Organization veya sabit "KolayTercih Editör Ekibi" Person/Organization) ve `image` (mevcut OG görseli) ekle → `src/lib/seo.tsx:149-172`.
2. `/llms.txt` statik veya `src/app/llms.txt/route.ts` route'u ekle: site tanımı, ana bölümler (`/bolumler`, `/universiteler`, `/rehber`), 46 rehber yazısının başlık+özet listesi (`getAllRehberler()` zaten `src/lib/rehber.ts`'te var, aynı veriyi besler), veri kaynağı (YÖK Atlas, `KATALOG_VERI_TARIHI`). Taslak içerik aşağıda.
3. `Organization` şemasına `sameAs` ekle (varsa sosyal hesap linki; yoksa madde ertelenir, Bilal'e sorulur).
**Dalga 2 — orta efor, yüksek etki:**
4. Bölüm/il sayfalarına tablo verisini temsil eden `ItemList`/`Table` türünde şema ekle (her satır: üniversite adı, program adı, taban sıralaması, yıl) — CTO şablon düzeyinde tek fonksiyon yazıp `bolum-icerik.tsx` ve `il-icerik.tsx`'e bağlamalı, elle sayfa sayfa değil.
5. Rehber yazılarındaki soru-cevap bloklarını `FAQPage` şemasına bağla: `content/rehber/*.md` içindeki `**Soru?**\nCevap.` desenini `rehber.ts` parse aşamasında ayrıştırıp `rehber-makale.tsx`'e `faqPageJsonLd` olarak geçir.
6. `/feed.xml` (rehber RSS) route'u ekle, `sitemap.ts`'e ve `<head>`'e (layout.tsx) `<link rel="alternate" type="application/rss+xml">` ekle.
**Dalga 3 — düşük öncelik / araştırma gerektirir:**
7. `Cache-Control: no-store` kaynağını netleştir — `cacheComponents` altında hangi bileşen (muhtemelen `HeaderGate`/oturum kontrolü) tüm sayfayı dinamik yapıyor; `node_modules/next/dist/docs/01-app/03-api-reference/05-config/01-next-config-js/cacheComponents.md` okunarak segment bazlı `'use cache'` ile katalog/rehber gövdesinin CDN'de önbelleklenip önbelleklenemeyeceği değerlendirilmeli. Bu iş kod değişikliği gerektirdiği için CTO/yazılımcı işi.
8. Künye/Hakkında sayfası (`/hakkinda`) — tüzel kimlik, veri metodolojisi, editör ekibi. Ürün kararı, [BİLAL].
9. Sayfalama alt yollarını (`/sayfa/N`) sitemap'e ekleyip eklememeye CTO karar versin (bugün de linklerle keşfedilebilir durumda, kritik değil).
## Bilal'den istenen
- Yok. Bu tur yalnızca araştırma; Dalga 1-2 maddeleri CEO onayına, kod değişikliği CTO/yazılımcıya gidecek.
---
### Ek: `/llms.txt` taslağı (Türkçe, somut)
```
# KolayTercih
> Türkiye'de YKS (üniversite giriş sınavı) tercih danışmanlığı: YÖK Atlas'ın
> resmî yerleştirme verisine dayanan yapay zekâ destekli 24'lük tercih listesi.
> Ücretsiz katalog: 229 üniversite, 634 bölüm, il bazlı arama.
## Veri kaynağı
Tüm taban puan/sıralama verisi YÖK Atlas {SON_YIL} yerleştirme sonuçlarından
alınır. Katalog en son {KATALOG_VERI_TARIHI} tarihinde güncellendi.
## Ana bölümler
- /bolumler — 634 bölümün taban puanı ve sıralama tablosu
- /universiteler — il bazlı üniversite kataloğu, 229 üniversite
- /universite-siralamasi — URAP akademik başarı sıralaması
- /rehber — YKS tercih süreciyle ilgili 46 rehber yazısı (aşağıda liste)
- /paket — ücretli yapay zekâ tercih listesi hizmeti
## Rehber yazıları
(getAllRehberler() çıktısından otomatik üretilmeli — her satır:
"- /rehber/{slug} — {baslik}: {aciklama}")
## Kısıtlar
- Yapay zekâ önerileri yalnızca kullanıcının sıralamasıyla açılan gerçek
YÖK Atlas programlarından seçilir; havuz dışına çıkmaz.
- Yerleşme garantisi verilmez.
```
Not: içerik listesi elle yazılmamalı — `getAllRehberler()` (`src/lib/rehber.ts`) zaten slug/başlık/açıklama döndürüyor; route bunu build-time'da stringe çevirip üretmeli, statik `public/llms.txt` olarak elle bakım riskli (46 yazı büyüyecek).