Nuxt uygulamasını edge ortamına taşımak yalnızca deploy hedefinin adını değiştirmek değil. Sunucu çıktısının Web API'leriyle uyumu, statik dosyaların nasıl sunulduğu ve secret'ların build ile runtime arasındaki yeri birlikte düşünülmeli.
Bu not, okuduğun sitenin Cloudflare Workers kurulumundan çıktı. Yapı küçük tutuldu: ayrı bir adaptör katmanı yerine Nitro'nun kendi Cloudflare preset'i ve resmi Wrangler aracı kullanılıyor.
Sürümleri sabitle
Build ortamında sürpriz yaşamamak için Node ve paket yöneticisi sürümleri depoda tanımlı:
{
"packageManager": "pnpm@11.19.0",
"engines": { "node": "24.x" }
}
.node-version dosyası da 24 değerini taşır. Cloudflare Workers Builds bu dosyayı okuyabilir; packageManager ise Corepack'in aynı pnpm sürümünü seçmesini sağlar. Kurulumda pnpm install --frozen-lockfile kullanmak, manifest ile kilit dosyası uyuşmadığında sessizce farklı bağımlılık çözülmesini engeller.
Modern Worker preset'ini açıkça seç
Nuxt'un sunucu katmanı Nitro tarafından hazırlanır. Bu projede hedef ES module tabanlı Cloudflare Worker'dır:
export default defineNuxtConfig({
content: {
experimental: { sqliteConnector: "native" },
database: { type: "d1", bindingName: "DB" },
},
nitro: {
preset: "cloudflare_module",
prerender: { crawlLinks: true, failOnError: true },
},
});
cloudflare_module, Worker'ın beklediği fetch girişini üretir. Çıktının sunucu parçası .output/server/index.mjs, tarayıcıya açık dosyaları ise .output/public altında bulunur.
Worker kodu ve asset'leri birlikte yayınla
Wrangler yapılandırmasının esas bölümü iki çıktı dizinini birbirine bağlar:
{
"name": "mehmet-macar",
"main": ".output/server/index.mjs",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"binding": "ASSETS",
"directory": ".output/public"
}
}
Statik bir dosya eşleştiğinde Workers Assets bunu doğrudan sunar. /api/contact gibi bir asset'e karşılık gelmeyen istek Worker'a ulaşır. Böylece prerender edilmiş sayfalar ile server endpoint'i aynı deployment içinde kalır.
nodejs_compat bayrağı, bağımlılıkların ihtiyaç duyduğu Node uyumluluk API'lerini Workers runtime'ında açar. Bu yine de klasik bir Node sunucusunda çalışıldığı anlamına gelmez; dosya sistemi veya uzun yaşayan process varsayımı yapılmamalıdır.
Nuxt Content'in Workers runtime'ında sorgu çalıştırabilmesi için DB adlı Cloudflare D1 binding'i de gerekir. Wrangler'ın kimliksiz resource provisioning özelliğiyle binding config'e yazılıp veritabanı ilk deploy sırasında oluşturulabilir; böylece hesap özelindeki database ID'yi repoya önceden koymak gerekmez.
Prerender'ı yayın öncesi kontrol olarak kullan
İçerik sayfaları build sırasında hazırlanır ve bağlantılar taranır:
routeRules: {
"/": { prerender: true },
"/yazilar/**": { prerender: true },
"/projeler/**": { prerender: true },
},
nitro: {
prerender: { crawlLinks: true, failOnError: true },
}
failOnError: true, bozuk bir içerik route'unu ziyaretçiden önce CI build'inde görünür kılar. İletişim API'si ise prerender edilmez; her POST isteği Worker içinde çalışır.
Build değişkeni ile runtime secret'ını ayır
Nuxt runtime config'te public altındaki değerler istemciye gidebilir, diğerleri yalnız sunucuda kalır:
runtimeConfig: {
resendApiKey: "",
contactEmail: "",
contactFrom: "",
public: {
siteUrl: process.env.NUXT_PUBLIC_SITE_URL || "http://localhost:3000",
},
}
Runtime override isimleri sırasıyla NUXT_RESEND_API_KEY, NUXT_CONTACT_EMAIL ve NUXT_CONTACT_FROM olur. Resend anahtarının NUXT_PUBLIC_ ile başlamaması kritik; aksi hâlde gizli değer istemci yapılandırmasına taşınabilir.
NUXT_PUBLIC_SITE_URL ise gerçekten public'tir. Canonical, sitemap ve RSS prerender sırasında üretildiği için bu değer Cloudflare'ın build ortamında https://mehmetmacar.com olarak tanımlanır. Aynı değer origin kontrolü için Worker runtime variable olarak da bulunur.
İletişim formunu edge'de güvenli tut
Form tarayıcıdan doğrudan Resend'e gitmez. Ziyaretçi /api/contact endpoint'ine JSON gönderir; Worker girdiyi doğruladıktan sonra Resend API'yi server-side çağırır.
Bu projedeki temel kontroller:
- Alan tipi, e-posta biçimi, boşluk ve uzunluk doğrulaması
- JSON ve toplam istek boyutu sınırı
- Honeypot alanı
- Site origin kontrolü
CF-Connecting-IPüzerinden temel, isolate içi rate limit- Sağlayıcı hatasını ve form içeriğini loglara taşımayan hata cevabı
Mailin Reply-To alanına ziyaretçinin adresi yazılır. Böylece gerçek alıcı kutusunda Yanıtla seçildiğinde yanıt formu dolduran kişiye gider.
GitHub push'unu deployment'a dönüştür
Workers Builds için işlem iki adımlıdır:
corepack pnpm build
corepack pnpm exec wrangler deploy
İlk komut Nuxt/Nitro çıktısını üretir, ikincisi Worker ile asset'leri yükler. Production branch main olduğunda bu branch'e gelen push aktif deployment'ı günceller. Diğer branch'lerde wrangler versions upload kullanılırsa production'ı değiştirmeden preview version alınabilir.
Deploy etmeden bundle'ı doğrula
Gerçek hesapta değişiklik yapmadan önce üç kontrol yeterli bir taban sağlar:
pnpm lint
pnpm typecheck
pnpm test
pnpm build
pnpm exec wrangler deploy --dry-run
Dry-run, Wrangler'ın Worker girişini ve statik asset yapılandırmasını okuyabildiğini gösterir. Canlı dağıtımdan sonra doğrudan detay URL'leri, sitemap/RSS/robots, 404 ve iletişim formu ayrıca sınanmalıdır. Build'in başarılı olması DNS, domain doğrulaması veya gerçek e-posta teslimini tek başına kanıtlamaz.
