Files
kolaytercih/next.config.ts
bilalgursen 53eb07bb34 feat(seo): GEO paketi — yapılandırılmış metadata, AI bot erişimi, veri tazelik sinyali
- sayfaMetadata(): indekslenebilir sayfalar için tek kaynaklı canonical +
  eksiksiz openGraph üretimi; sayfalar buna geçirildi
- robots.ts: yalnızca /api/ engellenir; noindex'li sayfalar robots engeli
  yerine meta ile yönetilir, AI botları niyeti belgeleyen açık grupla izinli
- next.config: htmlLimitedBots'a AI botları eklendi (JS çalıştırmayan
  botlara metadata head içinde bloklanarak verilir)
- sitemap lastmod + katalogda görünür 'Kaynak/son güncelleme' satırı
  (VeriKaynagi) KATALOG_VERI_TARIHI tek kaynağından
- docs/geo/geo-raporu.md: çalışmanın raporu

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-21 00:51:16 +03:00

83 lines
3.9 KiB
TypeScript
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.
import type { NextConfig } from "next";
import { HTML_LIMITED_BOT_UA_RE } from "next/dist/shared/lib/router/utils/html-bots";
// Dockerfile builder katmanı BUILD_KAYNAK_KISITLI=1 verir: imaj build'i prod
// VPS'te çalışan uygulamayla aynı makinede koştuğu için bellek/paralellik kısılır.
// Lokal build ve dev bu kısıtlardan etkilenmez.
const kaynakKisitli = process.env.BUILD_KAYNAK_KISITLI === "1";
// Arama/AI botları JS çalıştırmaz. Next, metadata'sı istek anına kalan
// sayfalarda <title>/canonical/robots etiketlerini <body>'ye akıtır; yalnızca
// bu listedeki user-agent'lara <head> içinde, bloklayarak verir. Varsayılan
// listede AI botları yok. Şu an herkese açık sayfaların hepsi prerender
// edildiği için etkisi yok; ileride dinamik bir sayfa eklenirse sigortadır.
// `htmlLimitedBots` varsayılanı EZDİĞİ için Next'in kendi listesi de eklenir.
const AI_BOTLARI =
"GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-User|Claude-SearchBot|PerplexityBot|Perplexity-User|meta-externalagent|meta-externalfetcher|meta-webindexer|Amazonbot|Amzn-SearchBot|Amzn-User|DuckAssistBot|MistralAI-User|CCBot|Bytespider";
const nextConfig: NextConfig = {
htmlLimitedBots: new RegExp(
`${HTML_LIMITED_BOT_UA_RE.source}|${AI_BOTLARI}`,
"i",
),
// PPR: statik kabuk anında servis edilir, dinamik parçalar (UserNav vb.)
// Suspense sınırlarının içinde akar. Bkz. docs/cacheComponents.md.
cacheComponents: true,
output: "standalone",
// Server-only paketler bundle dışında tutulur: Turbopack bunları derlemez
// (build belleği ciddi düşer), runtime'da native require ile yüklenir ve
// standalone trace'i imaja kopyalar. (Tarihçe: @google/genai'nin sürüklediği
// bağımlılık zinciri VPS'te build OOM'unu tetiklemişti; AI katmanı artık
// yalnızca openai paketiyle OpenRouter'a gidiyor.)
serverExternalPackages: [
"better-sqlite3",
"iyzipay",
"@libsql/client",
"openai",
"resend",
],
// iyzipay lib/'ini runtime'da readdirSync ile dinamik yükler; nft trace bunu
// göremediği için standalone'a yalnızca Iyzipay.js düşer ve initialize
// "ENOENT ... lib/resources" ile patlar. Tüm lib/ zorla imaja alınır.
outputFileTracingIncludes: {
"/*": ["node_modules/.pnpm/iyzipay@*/node_modules/iyzipay/lib/**"],
},
experimental: {
// radix-ui kök barrel'ı 36 alt paketi çeker ve Next'in varsayılan
// optimize listesinde yoktur; named import'lar doğrudan alt modüle
// çevrilir (dev boot / build modül grafiği küçülür).
optimizePackageImports: ["radix-ui"],
...(kaynakKisitli
? {
// Turbopack'ın Rust tarafı NODE_OPTIONS heap sınırını görmez; bellek
// hedefi byte cinsinden ayrıca verilir (1 GB). 1.5 GB hedef + Node
// heap'i, ~1.5 GB boş belleği olan VPS'te derleme fazında OOM-kill
// üretiyordu (lokalde --memory=1536m ile reprodüke edildi).
turbopackMemoryLimit: 1_073_741_824,
// Statik üretim: varsayılan 4 worker × 8 eşzamanlı sayfa yerine tek
// worker × 4 sayfa. Her worker ayrı bir Node süreci/heap'idir.
cpus: 1,
staticGenerationMaxConcurrency: 4,
}
: {}),
},
...(kaynakKisitli
? {
// cacheComponents açıkken prerender fazında source map üretimi varsayılan
// açık; 1900+ statik sayfada ciddi bellek maliyeti var.
enablePrerenderSourceMaps: false,
}
: {}),
async redirects() {
// Eski akış /sonuc modalına taşındı. /rapor/yazdir korunur (tam eşleşme).
return [
{ source: "/rapor", destination: "/sonuc", permanent: false },
{ source: "/sohbet", destination: "/listem", permanent: false },
// Ayrı robot sayfası kaldırıldı; rehber içi linkler hero formuna düşer.
{ source: "/tercih-robotu", destination: "/#hero-form", permanent: true },
];
},
};
export default nextConfig;