- 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>
83 lines
3.9 KiB
TypeScript
83 lines
3.9 KiB
TypeScript
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;
|