Astro 7: yeniden tasarlanan dev server
Astro neden sürüm atladı?
Astro 6, Ocak 2025'te çıktığında content collections API'sinde köklü değişiklikler getirmişti. Altı ay sonra Astro 7 (Haziran 2025) ise altta yatan altyapıyı değiştiriyor: Vite 7'ye geçiş, dev server mimarisinin yeniden yazılması ve performansı doğrudan etkileyen bir dizi API. Breaking change sayısı az; asıl mesele Vite 7'nin getirdiği Rolldown entegrasyonu ve bunun Astro'nun build pipeline'ına yansıması. Rolldown hakkında daha fazla bilgi için bu yazıya bakabilirsiniz.
Vite 7 ve Rolldown geçişi
Astro 7'nin en belirgin altyapı değişikliği Vite 7'ye geçiş. Vite 7, esbuild ve Rollup ikilisini bırakıp Rust tabanlı Rolldown'a geçti. Astro açısından bu ne anlama geliyor?
Dev server'da modül dönüşümleri artık Rolldown üzerinden yapılıyor. Önceki sürümlerde esbuild ile yapılan TypeScript/JSX transform işlemleri ve Rollup ile yapılan dependency pre-bundling artık tek bir araçta birleşiyor. Pratikte cold start süreleri kısalıyor; büyük mono-repo'larda (500+ sayfa, çok sayıda island) dev server'ın ayağa kalkma süresi gözle görülür şekilde düşüyor.
Build tarafında da Rolldown devreye giriyor. Astro'nun SSG (Static Site Generation) pipeline'ı zaten sayfa başına bağımsız chunk'lar üretiyordu; Rolldown'ın paralel chunk oluşturma yeteneği bu süreci hızlandırıyor. Vite 8 ve Rolldown ilişkisini detaylıca anlattığım yazı burada.
Vite 7 geçişi bir breaking change. Eğer astro.config.mjs içinde doğrudan Vite plugin'leri kullanıyorsanız, bu plugin'lerin Vite 7 uyumluluğunu kontrol etmeniz gerekiyor:
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
vite: {
plugins: [
// Vite 7 uyumlu plugin'ler kullanın
// Rollup-only plugin'ler artık çalışmayabilir
],
},
});Dev server mimarisi: ne değişti?
Astro 7'de dev server sadece Vite güncellemesiyle kalmıyor. Astro ekibi, HMR (Hot Module Replacement) pipeline'ını yeniden yazdı. Önceki sürümlerde .astro dosyalarında yapılan bir değişiklik bazen tüm sayfanın yeniden yüklenmesine neden oluyordu; özellikle layout dosyalarında yapılan düzenlemeler buna sebep oluyordu.
Astro 7'de .astro bileşenlerinin dependency graph'i daha granüler izleniyor. Bir layout değiştiğinde yalnızca o layout'u kullanan sayfalar invalidate ediliyor, ama bu sayfalar da tam reload yerine partial update alıyor. Sonuç: layout düzenlemelerinde bile sayfa state'i (form input'ları, scroll pozisyonu) korunabiliyor.
Bir diğer iyileştirme middleware pipeline'ında. Dev modda middleware zinciri artık lazy evaluation yapıyor; middleware dosyanız değişmediği sürece her istekte yeniden çalıştırılmıyor, cache'leniyor.
Live content collections
Astro 6'da content collections zaten glob() ve file() loader'ları ile yeniden tasarlanmıştı. Astro 7 bunun üzerine "live" kavramını ekliyor. Live content collections, dev server çalışırken içerik dosyalarını (Markdown, MDX, JSON, YAML) izliyor ve değişiklik anında sayfayı güncelliyor. Kulağa basit geliyor, ama önceki davranışla farkı var.
Astro 6'da bir .md dosyasını değiştirdiğinizde dev server dosyayı yeniden parse ediyordu, ancak collection query'leri (örneğin getCollection('blog')) cache'lenmiş veriyi döndürebiliyordu. Sayfa yenilemesi gerekebiliyordu. Astro 7'de content layer bir file watcher ile doğrudan bağlı; dosya değiştiğinde collection cache invalidate ediliyor ve HMR üzerinden sayfa güncelleniyor.
Konfigürasyon tarafında büyük bir değişiklik yok. content.config.ts dosyanız aynı yapıda çalışıyor:
// src/content.config.ts
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const blog = defineCollection({
loader: glob({ pattern: '**/*.md', base: './src/content/blog' }),
schema: z.object({
title: z.string(),
date: z.coerce.date(),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };Fark runtime'da. Dev modda bu collection artık reaktif. Yeni bir .md dosyası eklediğinizde, blog listesi sayfası otomatik güncelleniyor; dosyayı sildiğinizde de aynı şekilde.
Live collections'ın bir güzel tarafı: remote loader'lar (API'den veri çeken custom loader'lar) için de polling desteği geldi. Loader'ınıza pollInterval parametresi ekleyerek dev modda belirli aralıklarla veri yenilemesi yapabilirsiniz:
import { defineCollection } from 'astro:content';
import { myApiLoader } from './loaders/api';
const products = defineCollection({
loader: myApiLoader({
endpoint: 'https://api.example.com/products',
pollInterval: 30_000, // 30 saniyede bir kontrol et (sadece dev modda)
}),
});Built-in font optimizasyonu
Astro 7, framework seviyesinde bir font API sunuyor. Daha önce @fontsource paketleri veya manuel <link> etiketleri kullanılıyordu. Yeni API, Google Fonts ve lokal font dosyalarını build sırasında indirip self-host ediyor. Bu, üçüncü parti DNS lookup'larını ortadan kaldırıyor.
Kullanımı şöyle:
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
fonts: {
families: [
{
name: 'Inter',
provider: 'google',
weights: [400, 500, 700],
subsets: ['latin', 'latin-ext'],
},
{
name: 'JetBrains Mono',
provider: 'local',
src: './src/fonts/JetBrainsMono-Regular.woff2',
weights: [400],
},
],
defaults: {
fallback: 'system-ui',
display: 'swap',
},
},
});Build sırasında Astro, Google Fonts'tan font dosyalarını indiriyor, _astro/fonts/ dizinine koyuyor ve gerekli @font-face kurallarını otomatik oluşturuyor. Ayrıca font-display: swap gibi ayarları merkezi olarak kontrol edebiliyorsunuz.
Lokal fontlar için de aynı pipeline geçerli: dosya hash'leniyor, cache-friendly isim alıyor, CSS'e ekleniyor. Font optimizasyonu denilince akla genellikle Next.js'in next/font modülü gelir; Astro'nun yaklaşımı benzer ama framework-agnostic, herhangi bir UI framework'üne bağlı değil.
Content Security Policy (CSP) API
Astro 7'de CSP desteği birinci sınıf bir API olarak eklendi. Content Security Policy header'ları, XSS saldırılarına karşı tarayıcı seviyesinde koruma sağlıyor. Astro'nun inline script'ler üretme eğilimi (island hydration, view transitions) CSP ile çatışıyordu; unsafe-inline kullanmak gerekiyordu ki bu CSP'nin amacını büyük ölçüde boşa çıkarıyordu.
Yeni API, Astro'nun ürettiği her inline script'e otomatik nonce ekliyor:
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
security: {
csp: {
mode: 'nonce', // 'nonce' veya 'hash'
directives: {
'script-src': ['self'],
'style-src': ['self'],
'img-src': ['self', 'data:'],
},
},
},
});mode: 'nonce' seçildiğinde, Astro her response için rastgele bir nonce üretiyor ve tüm <script> etiketlerine nonce attribute'u ekliyor. SSR modunda bu nonce her istekte yenileniyor. SSG modunda ise mode: 'hash' tercih etmek daha mantıklı; statik dosyalarda nonce kullanılamayacağı için Astro, script içeriklerinin SHA-256 hash'lerini hesaplayıp CSP header'ına ekliyor.
Bu özellik özellikle kurumsal projelerde, güvenlik denetimleri gerektiren uygulamalarda büyük kolaylık sağlıyor. Daha önce bu işi manuel yapmak ya da bir middleware ile halletmek gerekiyordu.
Diğer dikkat çekici değişiklikler
Astro Actions iyileştirmeleri
Astro 4.15'te deneysel olarak gelen Actions API, Astro 7'de birkaç iyileştirme aldı. Action'lardan dönen hataların tipi artık daha spesifik; ActionError sınıfı code alanında literal type döndürüyor:
// src/actions/index.ts
import { defineAction, z } from 'astro:actions';
export const server = {
subscribe: defineAction({
input: z.object({
email: z.string().email(),
}),
handler: async ({ email }) => {
const exists = await checkSubscription(email);
if (exists) {
throw new ActionError({
code: 'CONFLICT', // literal type olarak çıkıyor
message: 'Bu e-posta zaten kayıtlı.',
});
}
await addSubscriber(email);
return { success: true };
},
}),
};Partial prerendering
Astro 7'de hybrid rendering daha esnek hale geldi. Bir sayfa içinde bazı bölümleri statik, bazılarını dinamik render edebilme yeteneği geliştirildi. server:defer directive'i ile bir island'ın ilk yüklemede placeholder gösterip sonra server'dan veri çekmesi sağlanıyor. Bu, streaming SSR ile birlikte çalışıyor.
Node.js minimum sürüm
Astro 7, Node.js 20.x ve üzeri gerektiriyor. Node.js 18 desteği bırakıldı. Bu, globalThis.crypto, fetch gibi API'lerin polyfill olmadan kullanılabilmesi anlamına geliyor.
Astro 6'dan 7'ye geçiş
Geçiş için Astro'nun CLI aracı var:
npx @astrojs/upgradeBu komut package.json'daki Astro ve resmi integration sürümlerini güncelliyor, bilinen breaking change'ler için uyarı veriyor. Manuel kontrol edilmesi gereken noktalar:
- Vite plugin'lerinin Vite 7 uyumluluğu
astro.config.mjsiçinde deprecated olan ayarlar (varsa CLI uyarıyor)- Node.js sürümünüzün 20+ olması
- Üçüncü parti integration'ların güncel sürümleri
Breaking change sayısı Astro 5→6 geçişine kıyasla az. Vite plugin sorunu yoksa geçiş genellikle sorunsuz.
Ne zaman Astro 7'ye geçmeli?
Content-heavy bir site çalıştırıyorsanız, live content collections tek başına geçiş sebebi. Dev deneyimi fark edilir biçimde iyileşiyor. CSP gereksinimi olan kurumsal projelerde built-in CSP API, middleware katmanında yazılan custom kodu ortadan kaldırıyor. Font optimizasyonu ise zaten yapılması gereken ama genellikle ertelenen bir iş; framework seviyesinde sunulması bu ertelemeyi anlamsız kılıyor.
Geçiş riskini minimize etmek isteyenler için tavsiyem: önce bir feature branch'te npx @astrojs/upgrade çalıştırıp build'in geçtiğini doğrulayın. Vite plugin uyumsuzluğu yoksa, geçiş genellikle yarım saatten kısa sürüyor.