Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu ve nasıl temiz bir çözümle aştığımı anlatacağım. Bir e-ticaret projesinde, ürün katalog sayfası sürekli güncelleniyordu (stok, fiyat, yeni ürünler). Tamamen static (getStaticProps) yapsam güncelleme olmuyor, client-side fetch yapsam hem SEO kaybı hem de ilk yüklenme performansı düşüyordu. İşte o zaman Next.js'in ISR (Incremental Static Regeneration) özelliği imdadıma yetişti.
Karşılaştığım Sorun ve ISR Fikri
Müşteri, "Sayfa hızlı açılsın, SEO'su mükemmel olsun AMA admin panelinden bir ürünü düzelttiğimde 5 dakika içinde sitede de görünsün" diyordu. Bu istekler ilk duyduğumda "ya statik ya dinamik, ikisi birden olmaz" demiştim ama yanılmışım. Next.js ISR, sayfayı build zamanında static olarak oluşturuyor, ama belirlediğiniz bir süre (revalidate) sonra arka planda yeniden oluşturup eski static sayfayı güncelliyor. Yani best of both worlds!
getStaticProps ile ISR'yi Aktif Etmek
Çözüm inanılmaz basit. Mevcut `getStaticProps` fonksiyonunuzun döndüğü object'e bir `revalidate` anahtarı eklemekten ibaret. İşte benim katalog sayfamın (`pages/products/index.js`) dosyasındaki kilit nokta:
Buradaki revalidate: 60 ifadesi, Next.js'e diyor ki: "Bu sayfayı sunucuda static olarak sakla, ama gelen her istekten sonra kontrol et. Eğer son üretiminden 60 saniye geçmişse, bir sonraki istekte arka planda yeni verilerle sayfayı tekrar oluştur ve cache'ini güncelle." Kullanıcı eski, güncellenmemiş sayfayı görürken, arka planda yenisi hazırlanıyor.
On-Demand Revalidation (İsteğe Bağlı Yenileme) ile Süper Güç
60 saniye beklemek bile bazı kritik güncellemeler (fiyat düşürme!) için uzun gelebilir. Next.js 12.1 ile gelen On-Demand Revalidation tam da bunun için. Admin panelinden bir ürün güncellendiğinde, bir API route'u tetikleyerek o spesifik sayfanın anında yenilenmesini sağlayabilirsiniz.
İlk olarak, bir secret token tanımlayın (`.env.local` dosyasında):
Sonra, `pages/api/revalidate.js` API route'unu oluşturun:
Artık, ürün güncellendiğinde backend'iniz şu isteği atabilir:
`
`
Bu sayede, katalog sayfanız anında, hiç beklemeden güncellenir. ISR + On-Demand Revalidation kombinasyonu gerçekten ölümcül bir performans ve güncellik ikilisi sunuyor.
Sonuç ve Performans Kazanımı
Bu yapıyı kurduktan sonra, sayfa Lighthouse skorlarında Performance 98+, SEO ise tabii ki 100 aldı. Sayfa tamamen static HTML/CSS/JS olarak sunulduğu için inanılmaz hızlı açılıyor. Veritabanı veya API'ye her istekte gidip sorgu yapılmıyor, sadece belirli periyotlarda veya manuel tetikleme ile güncelleniyor.
Siz Next.js'te benzer dinamik içeriği static tutma senaryolarında neler kullandınız? ISR dışında fallback, blocking gibi stratejileri projelerinizde deneyimlediniz mi? Ya da bu yapıyı kurarken karşılaştığınız ilginç sorular oldu mu? Yorumlarda buluşalım!
Müşteri, "Sayfa hızlı açılsın, SEO'su mükemmel olsun AMA admin panelinden bir ürünü düzelttiğimde 5 dakika içinde sitede de görünsün" diyordu. Bu istekler ilk duyduğumda "ya statik ya dinamik, ikisi birden olmaz" demiştim ama yanılmışım. Next.js ISR, sayfayı build zamanında static olarak oluşturuyor, ama belirlediğiniz bir süre (revalidate) sonra arka planda yeniden oluşturup eski static sayfayı güncelliyor. Yani best of both worlds!
Çözüm inanılmaz basit. Mevcut `getStaticProps` fonksiyonunuzun döndüğü object'e bir `revalidate` anahtarı eklemekten ibaret. İşte benim katalog sayfamın (`pages/products/index.js`) dosyasındaki kilit nokta:
JavaScript:
export async function getStaticProps() {
// Ürünleri API'nizden veya veritabanınızdan çekin
const res = await fetch('https://api.sitem.com/products');
const products = await res.json();
// Eğer ürün yoksa 404 sayfası gösterilsin
if (!products) {
return {
notFound: true,
};
}
// BU SATIR SİHİRLİ! Her 60 saniyede bir sayfayı yeniden oluşturma izni ver.
return {
props: {
products,
},
revalidate: 60, // 60 saniye (1 dakika)
};
}
Buradaki revalidate: 60 ifadesi, Next.js'e diyor ki: "Bu sayfayı sunucuda static olarak sakla, ama gelen her istekten sonra kontrol et. Eğer son üretiminden 60 saniye geçmişse, bir sonraki istekte arka planda yeni verilerle sayfayı tekrar oluştur ve cache'ini güncelle." Kullanıcı eski, güncellenmemiş sayfayı görürken, arka planda yenisi hazırlanıyor.
60 saniye beklemek bile bazı kritik güncellemeler (fiyat düşürme!) için uzun gelebilir. Next.js 12.1 ile gelen On-Demand Revalidation tam da bunun için. Admin panelinden bir ürün güncellendiğinde, bir API route'u tetikleyerek o spesifik sayfanın anında yenilenmesini sağlayabilirsiniz.
İlk olarak, bir secret token tanımlayın (`.env.local` dosyasında):
Kod:
NEXT_PUBLIC_REVALIDATE_SECRET=benim_super_gizli_tokenum
Sonra, `pages/api/revalidate.js` API route'unu oluşturun:
JavaScript:
export default async function handler(req, res) {
// Gelen isteğin token'ını kontrol et
if (req.query.secret !== process.env.NEXT_PUBLIC_REVALIDATE_SECRET) {
return res.status(401).json({ message: 'Geçersiz token' });
}
try {
// Hangi sayfanın yenileneceğini path'ten anla (bu örnekte tüm katalog)
const pathToRevalidate = req.query.path || '/products';
await res.revalidate(pathToRevalidate);
return res.json({ revalidated: true, path: pathToRevalidate });
} catch (err) {
// Hata durumunda 500 döndür
return res.status(500).send('Revalidation hatası');
}
}
Artık, ürün güncellendiğinde backend'iniz şu isteği atabilir:
`
Bu bağlantı ziyaretçiler için gizlenmiştir. Görmek için lütfen giriş yapın veya üye olun.
Bu sayede, katalog sayfanız anında, hiç beklemeden güncellenir. ISR + On-Demand Revalidation kombinasyonu gerçekten ölümcül bir performans ve güncellik ikilisi sunuyor.
Bu yapıyı kurduktan sonra, sayfa Lighthouse skorlarında Performance 98+, SEO ise tabii ki 100 aldı. Sayfa tamamen static HTML/CSS/JS olarak sunulduğu için inanılmaz hızlı açılıyor. Veritabanı veya API'ye her istekte gidip sorgu yapılmıyor, sadece belirli periyotlarda veya manuel tetikleme ile güncelleniyor.
Siz Next.js'te benzer dinamik içeriği static tutma senaryolarında neler kullandınız? ISR dışında fallback, blocking gibi stratejileri projelerinizde deneyimlediniz mi? Ya da bu yapıyı kurarken karşılaştığınız ilginç sorular oldu mu? Yorumlarda buluşalım!