# Nuxt 3: SSR ve statik üretim, eksiksiz rehber > Nuxt 3 ile SSR ve statik üretimi tüm yönleriyle öğrenin. useFetch'ten route rules'a, Vue.js uygulamalarınızın performansını optimize edin. - Published: 2026-02-11 - Updated: 2026-04-28 - Author: SharpSkill - Tags: nuxt 3, vue.js, ssr, statik üretim, web performansı - Reading time: 12 min --- Nuxt 3, farklı kullanım senaryolarına uygun çoklu render modları sunarak Vue.js uygulamalarının inşa şeklini dönüştürür. Server-Side Rendering (SSR), statik üretim ve hibrit render arasında framework, performans ve SEO optimizasyonu için dikkat çekici bir esneklik sağlar. > **Ön gereksinimler** > > Bu eğitim Vue 3 ve Composition API hakkında temel bilgi gerektirir. Sunucu tarafı render kavramlarına aşinalık faydalı olur ancak zorunlu değildir; temel bilgiler rehber boyunca açıklanır. ## Nuxt 3 render modlarını anlamak Koda dalmadan önce mevcut render modları arasındaki farkları anlamak şarttır. Her mod; performans, SEO ve kullanıcı deneyimi açısından belirli ihtiyaçlara karşılık gelir. SSR (Server-Side Rendering) her istek için sunucuda HTML üretir. Statik üretim (SSG) build zamanında tüm sayfaları önceden üretir. Hibrit mod, bu yaklaşımları sayfa bazında birleştirmeyi sağlar. ```typescript // nuxt.config.ts // Farklı render modlarının yapılandırması export default defineNuxtConfig({ // SSR varsayılan olarak etkin (SEO için önerilir) ssr: true, // Statik üretim: tüm sayfaları önceden render eder // Build için 'npm run generate' kullanın // target: 'static', // Nuxt 2 söz dizimi // Hibrit mod: rota bazında yapılandırılabilir routeRules: { // Ana sayfa: önceden render edilmiş ve önbelleğe alınmış '/': { prerender: true }, // Blog: statik üretim '/blog/**': { prerender: true }, // Dashboard: yalnızca istemci tarafı render '/dashboard/**': { ssr: false }, // API: pre-render yok '/api/**': { prerender: false } } }) ``` Bu yapılandırma hibrit modun gücünü gösterir: uygulamanın her bölümü kendi ihtiyaçlarına en uygun render modunu kullanır. ## useFetch ve useAsyncData ile veri çekme Nuxt 3, izomorfik şekilde veri çekmek için iki ana composable sunar. Bu composable'lar hem sunucu hem istemci tarafında çalışır ve hidrasyonu otomatik yönetir. `useFetch`, HTTP çağrılarını basitleştiren `useAsyncData` etrafındaki bir wrapper'dır. `useAsyncData` ileri seviye senaryolarda daha fazla kontrol sunar. ```vue ``` Daha fazla kontrol gerektiren durumlarda `useAsyncData` herhangi bir asenkron fonksiyon çalıştırmaya izin verir. ```vue ``` Bu composable'lar çift fetch'i önler: sunucuda alınan veriler HTML payload'una serileştirilir ve istemci hidrasyonu sırasında yeniden kullanılır. ## Server hooks ile SSR'ı özelleştirmek Nuxt 3'ün SSR'ı server hooks aracılığıyla özelleştirilebilir. Bu hook'lar, varsayılan davranışı değiştirmek için render döngüsünün farklı aşamalarına müdahale etmeye olanak tanır. ```typescript // server/plugins/render-hooks.ts // SSR render'ını özelleştirmek için sunucu eklentisi export default defineNitroPlugin((nitroApp) => { // Her sayfanın render'ından önce çalışan hook nitroApp.hooks.hook('render:html', (html, { event }) => { // Script veya metadata enjekte et html.head.push(` `) }) // Render önbelleğinin yönetimi için hook nitroApp.hooks.hook('render:response', (response, { event }) => { // Özel önbellek başlıkları ekle const path = event.path if (path.startsWith('/blog/')) { // Blog makaleleri için uzun önbellek response.headers['Cache-Control'] = 'public, max-age=3600, s-maxage=86400' } else if (path.startsWith('/api/')) { // API'ler için önbellek yok response.headers['Cache-Control'] = 'no-store' } }) }) ``` > **SSR performansı** > > `render:response` hook'u HTTP önbellek stratejilerini uygulamak için idealdir. SSR'ı Cache-Control başlıklarına saygı gösteren bir CDN ile birleştirmek, önceden render edilmiş sayfaları sunmaya devam ederken bunları geçersiz kılma yeteneğini korur. ## nuxt generate ile statik üretim Statik üretim, build zamanında tüm sayfaları önceden inşa eder. Bu yaklaşım blog, dokümantasyon veya pazarlama siteleri gibi sabit içerikli siteler için idealdir. Dinamik rotalar için Nuxt'un üretilecek tüm URL'leri bilmesi gerekir. `prerender:routes` hook'u bu rotaları programatik olarak tanımlamayı sağlar. ```typescript // nuxt.config.ts // Statik üretim için eksiksiz yapılandırma export default defineNuxtConfig({ // Statik üretimi etkinleştir nitro: { prerender: { // Otomatik link tarayıcısını etkinleştir crawlLinks: true, // Her zaman dahil edilecek rotalar routes: ['/', '/about', '/contact'], // Belirli rotaları yoksay ignore: ['/admin', '/api'] } }, hooks: { // Dinamik rotaları üretmek için hook async 'prerender:routes'(ctx) { // Makaleleri API veya DB'den çek const articles = await fetch('https://api.example.com/articles') .then(res => res.json()) // Makale rotalarını ekle for (const article of articles) { ctx.routes.add(`/blog/${article.slug}`) } // Kategorileri çek const categories = await fetch('https://api.example.com/categories') .then(res => res.json()) for (const category of categories) { ctx.routes.add(`/category/${category.slug}`) } } } }) ``` Çok sayfalı projelerde otomatik tarayıcı yetersiz kalabilir. İşte ayrı bir yapılandırma dosyasıyla daha sağlam bir yaklaşım. ```typescript // server/utils/generate-routes.ts // Dinamik rota listesini üretmek için yardımcı işlev import { prisma } from './prisma' export async function getAllStaticRoutes(): Promise { const routes: string[] = [] // Blog makaleleri const articles = await prisma.article.findMany({ where: { published: true }, select: { slug: true, category: { select: { slug: true } } } }) for (const article of articles) { routes.push(`/blog/${article.category.slug}/${article.slug}`) } // Ürün sayfaları const products = await prisma.product.findMany({ where: { active: true }, select: { slug: true } }) for (const product of products) { routes.push(`/products/${product.slug}`) } // Etiket sayfaları const tags = await prisma.tag.findMany({ select: { slug: true } }) for (const tag of tags) { routes.push(`/tags/${tag.slug}`) } return routes } ``` ## routeRules ile hibrit render Hibrit render Nuxt 3'ün öne çıkan özelliğidir. Her rota için farklı render kuralları tanımlamayı ve SSR ile SSG'nin en iyi yönlerini birleştirmeyi sağlar. ```typescript // nuxt.config.ts // Gelişmiş hibrit render yapılandırması export default defineNuxtConfig({ routeRules: { // Pazarlama sayfaları: önceden render edilmiş ve uzun süre önbelleklenmiş '/': { prerender: true }, '/pricing': { prerender: true }, '/features/**': { prerender: true }, // Blog: ISR (Incremental Static Regeneration) // Saatte bir yeniden doğrulama '/blog/**': { isr: 3600, prerender: true }, // Dokümantasyon: yeniden doğrulamalı CDN önbelleği '/docs/**': { swr: 86400, // Stale-while-revalidate prerender: true }, // E-ticaret: kısa önbellekli SSR '/products/**': { ssr: true, cache: { maxAge: 60, staleMaxAge: 300 } }, // Sepet ve ödeme: yalnızca istemci tarafı '/cart': { ssr: false }, '/checkout/**': { ssr: false }, // Dashboard: SPA modu '/dashboard/**': { ssr: false, // Pre-rendering'i devre dışı bırak prerender: false }, // API rotaları: varsayılan olarak önbellek yok '/api/**': { cors: true, headers: { 'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE' } } } }) ``` Bu yapılandırma tipik bir modern uygulama mimarisini gösterir: kamuya açık sayfalar SEO için SSG ile optimize edilirken etkileşimli bölümler istemci tarafı render kullanır. ## Veri önbelleğiyle performans optimizasyonu Sayfa önbelleğinin ötesinde Nuxt 3, çekilen verileri önbelleklemeyi sağlar. Bu strateji API'ler üzerindeki yükü azaltır ve yanıt sürelerini iyileştirir. ```typescript // server/api/articles/[slug].get.ts // Veri önbellekli API endpoint'i import { getArticleBySlug } from '~/server/utils/articles' export default defineCachedEventHandler( async (event) => { const slug = getRouterParam(event, 'slug') if (!slug) { throw createError({ statusCode: 400, message: 'Slug eksik' }) } const article = await getArticleBySlug(slug) if (!article) { throw createError({ statusCode: 404, message: 'Makale bulunamadı' }) } return article }, { // Slug tabanlı önbellek anahtarı getKey: (event) => `article-${getRouterParam(event, 'slug')}`, // Önbellek süresi: 1 saat maxAge: 3600, // Stale-while-revalidate: güncelleme sırasında eski önbelleği sun staleMaxAge: 7200, // Etiket tabanlı geçersiz kılma tags: ['articles'] } ) ``` İçerik değiştiğinde önbelleği geçersiz kılmak için Nuxt bir etiket sistemi sunar. ```typescript // server/api/articles/[slug].put.ts // Önbellek geçersiz kılmalı makale güncellemesi import { updateArticle } from '~/server/utils/articles' export default defineEventHandler(async (event) => { const slug = getRouterParam(event, 'slug') const body = await readBody(event) // Makaleyi güncelle const article = await updateArticle(slug, body) // Bu makale için önbelleği geçersiz kıl await useStorage('cache').removeItem(`nitro:handlers:article-${slug}`) // Veya etiket tabanlı geçersiz kılma (tüm makaleler) // await useStorage('cache').clear('articles') return article }) ``` > **Dağıtık önbellek** > > Birden fazla örnekli üretimde bellek içi önbellek yetersiz kalır. Örnekler arasında tutarlılığı sağlamak için Nitro yapılandırması üzerinden Redis veya başka bir dağıtık sistemin kurulması önerilir. ## SEO ve metadata yönetimi SSR, metadata'yı sunucu tarafında üreterek SEO optimizasyonuna olanak tanır. Nuxt 3, meta etiketleri dinamik olarak yönetmek için birkaç yaklaşım sunar. ```vue ``` Statik sayfalar için metadata doğrudan bileşende tanımlanabilir. ```vue ``` ## Dağıtım ve üretim hususları Dağıtım seçimi kullanılan render moduna bağlıdır. İşte başlıca seçenekler ve yapılandırmaları. ```typescript // nuxt.config.ts // Farklı dağıtım ortamları için yapılandırma export default defineNuxtConfig({ nitro: { // Hedef platforma göre preset // preset: 'vercel', // Vercel // preset: 'netlify', // Netlify // preset: 'cloudflare-pages', // Cloudflare // preset: 'node-server', // Klasik Node.js // Üretimde Node.js için yapılandırma preset: 'node-server', // Yanıt sıkıştırması compressPublicAssets: true, // Önbellek deposu yapılandırması storage: { cache: { driver: 'redis', url: process.env.REDIS_URL } } }, // Çalışma zamanı ortam değişkenleri runtimeConfig: { // Sırlar (istemciye sunulmaz) apiSecret: process.env.API_SECRET, // Genel yapılandırma public: { apiBase: process.env.NUXT_PUBLIC_API_BASE || '/api' } } }) ``` Statik dağıtım için `npm run generate` komutu, herhangi bir statik dosya barındırıcısında dağıtıma hazır bir `.output/public` klasörü oluşturur. ```bash # Statik üretim npm run generate # .output/public içeriği şunlara dağıtılabilir: # - Vercel (otomatik tespit) # - Netlify (otomatik yapılandırma) # - GitHub Pages # - S3 + CloudFront # - Herhangi bir CDN veya statik dosya sunucusu ``` ## Sonuç Nuxt 3, Vue.js uygulamalarını render etmek için olağanüstü bir esneklik sunar. SSR, SSG ve hibrit render arasındaki seçim her projenin özel ihtiyaçlarına bağlıdır. **Önemli noktalar:** ✅ **SSR**: iyi SEO gerektiren dinamik içerikler için ideal (e-ticaret, haber siteleri) ✅ **SSG**: sabit içerikler için mükemmel (bloglar, dokümantasyon, pazarlama siteleri) ✅ **Hibrit**: çeşitli ihtiyaçlara sahip karmaşık uygulamalar için en iyi yaklaşım ✅ **useFetch/useAsyncData**: otomatik hidrasyon ve önbellek yönetimi ✅ **routeRules**: her rotanın davranışı için ince ayarlı yapılandırma ✅ **Önbellek**: üretim performansını optimize etmek için çoklu stratejiler Hibrit render'ı iyi düşünülmüş bir önbellek stratejisiyle birleştirmek, Single Page Applications'ın etkileşimini koruyarak SEO için optimize edilmiş yüksek performanslı uygulamalar inşa etmeyi sağlar. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/tr/blog/vue-nuxt/nuxt-3-ssr-static-generation