feat(geo): llms.txt, RSS, IndexNow, Article yazar/görsel, bölüm sayfasına veri özeti, vakıf bursu yazısı
All checks were successful
Deploy / deploy (push) Successful in 6m16s
All checks were successful
Deploy / deploy (push) Successful in 6m16s
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>
This commit is contained in:
54
src/app/feed.xml/route.ts
Normal file
54
src/app/feed.xml/route.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { getAllRehberler } from "@/lib/rehber";
|
||||
import { SITE_NAME, SITE_URL } from "@/lib/seo";
|
||||
|
||||
/**
|
||||
* Rehber yazılarının RSS 2.0 beslemesi. Kök layout metadata'sındaki
|
||||
* alternates.types bu adresi <link rel="alternate"> olarak <head>'e yazar.
|
||||
* Cache Components altında istek verisi okunmadığı için prerender edilir.
|
||||
*/
|
||||
function xmlKacis(metin: string): string {
|
||||
return metin
|
||||
.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">")
|
||||
.replaceAll('"', """);
|
||||
}
|
||||
|
||||
/** "YYYY-MM-DD" → RFC 822 (RSS pubDate). Gün 09:00 Türkiye saati kabul edilir. */
|
||||
function rfc822(iso: string): string {
|
||||
return new Date(`${iso}T09:00:00+03:00`).toUTCString();
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
const yazilar = getAllRehberler();
|
||||
const enYeni = yazilar[0]?.guncelleme ?? yazilar[0]?.tarih;
|
||||
|
||||
const items = yazilar
|
||||
.map(
|
||||
(y) => ` <item>
|
||||
<title>${xmlKacis(y.baslik)}</title>
|
||||
<link>${SITE_URL}/rehber/${y.slug}</link>
|
||||
<guid isPermaLink="true">${SITE_URL}/rehber/${y.slug}</guid>
|
||||
<description>${xmlKacis(y.aciklama)}</description>
|
||||
<pubDate>${rfc822(y.tarih)}</pubDate>
|
||||
</item>`,
|
||||
)
|
||||
.join("\n");
|
||||
|
||||
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>${SITE_NAME} Tercih Rehberi</title>
|
||||
<link>${SITE_URL}/rehber</link>
|
||||
<description>YKS tercih dönemi rehberi: veriye dayalı, öğrenci diliyle yazılar.</description>
|
||||
<language>tr</language>
|
||||
<atom:link href="${SITE_URL}/feed.xml" rel="self" type="application/rss+xml" />
|
||||
${enYeni ? ` <lastBuildDate>${rfc822(enYeni)}</lastBuildDate>\n` : ""}${items}
|
||||
</channel>
|
||||
</rss>
|
||||
`;
|
||||
|
||||
return new Response(xml, {
|
||||
headers: { "Content-Type": "application/rss+xml; charset=utf-8" },
|
||||
});
|
||||
}
|
||||
@@ -52,6 +52,9 @@ export const metadata: Metadata = {
|
||||
description:
|
||||
"YKS sıralamana göre gerçek YÖK Atlas verisiyle dengeli 24 tercihlik liste. İnsan danışmandan çok daha düşük fiyata, yapay zekâ destekli tercih danışmanlığı.",
|
||||
applicationName: "KolayTercih",
|
||||
alternates: {
|
||||
types: { "application/rss+xml": "/feed.xml" },
|
||||
},
|
||||
openGraph: {
|
||||
type: "website",
|
||||
locale: "tr_TR",
|
||||
|
||||
62
src/app/llms.txt/route.ts
Normal file
62
src/app/llms.txt/route.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { getAllRehberler } from "@/lib/rehber";
|
||||
import { KATALOG_VERI_TARIHI, SITE_URL } from "@/lib/seo";
|
||||
import { SON_YIL, VERI_ARALIGI } from "@/lib/veri-yillari";
|
||||
import { PROGRAM_SAYISI_METNI } from "@/lib/veri-kapsami";
|
||||
import { trTarih } from "@/lib/tarih";
|
||||
|
||||
/**
|
||||
* llmstxt.org biçiminde site özeti: H1, tek paragraf özet, H2 altında
|
||||
* bağlantı listeleri. Yalnızca sitede zaten görünen bilgiyi taşır; içerik
|
||||
* gövdesi (llms-full.txt) bilinçli olarak üretilmez — etkisi kanıtsız,
|
||||
* toplu kopyalamayı kolaylaştırır (docs/arastirma/2026-09-24-geo-seo).
|
||||
*
|
||||
* Rehber listesi getAllRehberler()'den gelir; sitemap ile aynı kaynak,
|
||||
* elle bakım yok. Cache Components altında istek verisi okunmadığı için
|
||||
* build'de prerender edilir.
|
||||
*/
|
||||
export async function GET() {
|
||||
const yazilar = getAllRehberler();
|
||||
const rehberSatirlari = yazilar
|
||||
.map(
|
||||
(y) =>
|
||||
`- [${y.baslik}](${SITE_URL}/rehber/${y.slug}): ${y.aciklama}`,
|
||||
)
|
||||
.join("\n");
|
||||
|
||||
const metin = `# 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 tercihlik dengeli
|
||||
> liste. Ücretsiz katalog: bölüm, üniversite ve il sayfalarında ${VERI_ARALIGI}
|
||||
> taban sıralamaları.
|
||||
|
||||
Veri kaynağı: YÖK Atlas ${SON_YIL} yerleştirme sonuçları, ${PROGRAM_SAYISI_METNI}
|
||||
program. Katalog en son ${trTarih(KATALOG_VERI_TARIHI)} tarihinde güncellendi.
|
||||
KolayTercih, ÖSYM ya da YÖK ile bağlantılı değildir; yerleşme garantisi vermez.
|
||||
Yapay zekâ önerileri yalnızca kullanıcının sıralamasıyla açılan gerçek programlar
|
||||
arasından seçilir.
|
||||
|
||||
## Ana bölümler
|
||||
|
||||
- [Bölümler](${SITE_URL}/bolumler): bölüm bazında taban puanı ve sıralama tabloları
|
||||
- [Üniversiteler](${SITE_URL}/universiteler): il bazlı üniversite kataloğu
|
||||
- [Üniversite sıralaması](${SITE_URL}/universite-siralamasi): URAP akademik başarı sıralaması
|
||||
- [Tercih Rehberi](${SITE_URL}/rehber): tercih süreciyle ilgili ${yazilar.length} rehber yazısı
|
||||
- [Nasıl çalışır](${SITE_URL}/meraklisina): sihirbaz ve liste mantığının anlatımı
|
||||
- [Paket](${SITE_URL}/paket): ücretli yapay zekâ tercih listesi hizmeti
|
||||
|
||||
## Rehber yazıları
|
||||
|
||||
${rehberSatirlari}
|
||||
|
||||
## Optional
|
||||
|
||||
- [Gizlilik](${SITE_URL}/gizlilik)
|
||||
- [Kullanım koşulları](${SITE_URL}/kosullar)
|
||||
- [İletişim](${SITE_URL}/iletisim)
|
||||
`;
|
||||
|
||||
return new Response(metin, {
|
||||
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
||||
});
|
||||
}
|
||||
@@ -93,7 +93,7 @@ const problems = [
|
||||
icon: Wallet,
|
||||
title: "Danışman lüks haline geldi",
|
||||
description:
|
||||
"İyi bir tercih danışmanı 1.000–3.000 TL istiyor. Ücretsiz robotların çoğu ise yalnızca liste filtreliyor; listeyi kurup gerekçesini yazmıyor.",
|
||||
"Armut'ta tercih danışmanlığı ilanları ortalama 1.000–3.000 TL (Eylül 2026). Ücretsiz robotların çoğu ise yalnızca liste filtreliyor; listeyi kurup gerekçesini yazmıyor.",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -185,7 +185,7 @@ const comparison = [
|
||||
{
|
||||
feature: "Fiyat",
|
||||
robot: "Ücretsiz",
|
||||
danisman: "1.000–3.000 TL",
|
||||
danisman: "1.000–3.000 TL*",
|
||||
tercihai: `${PAKET_FIYATI} TL · tek seferlik`,
|
||||
},
|
||||
];
|
||||
@@ -524,6 +524,9 @@ export default function Home() {
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
<p className="mt-3 text-xs text-slate-500">
|
||||
* Danışman fiyat aralığı: Armut ortalama fiyatı, Eylül 2026.
|
||||
</p>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,7 @@ const AI_BOTLARI = [
|
||||
"Amzn-SearchBot",
|
||||
// Model eğitimi: aramasız yanıtlarda markanın bilinmesi buradan geçer
|
||||
"GPTBot",
|
||||
"ClaudeBot",
|
||||
// ClaudeBot aşağıda kendi grubunda (Crawl-delay için); buraya yazma.
|
||||
"Google-Extended",
|
||||
"Applebot-Extended",
|
||||
"meta-externalagent",
|
||||
@@ -38,6 +38,9 @@ export default function robots(): MetadataRoute.Robots {
|
||||
rules: [
|
||||
{ userAgent: "*", allow: "/", disallow: DISALLOW },
|
||||
{ userAgent: AI_BOTLARI, allow: "/", disallow: DISALLOW },
|
||||
// Anthropic Crawl-delay'i resmî olarak destekliyor (support.claude.com);
|
||||
// eğitim taraması 1011 URL'lik katalogda saniyede 1 istekle yeter.
|
||||
{ userAgent: "ClaudeBot", allow: "/", disallow: DISALLOW, crawlDelay: 1 },
|
||||
],
|
||||
sitemap: `${SITE_URL}/sitemap.xml`,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user