OpenNext Cloudflare: App Router'da takıldığımız 5 nokta

Overview yazısından sonra sahada asıl takıldığımız yerler: binding, image, Node uyumsuzluğu, local vs Workers ve cache/revalidate. OpenNext ile Next.js'i Cloudflare Workers'a alırken pratik notlar.

Daha önce Next.js'i Cloudflare'a taşımak: OpenNext deneyimimiz yazısında genel resmi çizmiştik: Vercel şart değil, opennextjs-cloudflare ile App Router büyük ölçüde Workers üzerinde çalışıyor. Bu yazı o overview'un devamı. Kurulumdan sonra projeyi canlıya alırken tekrar tekrar sürtündüğümüz beş nokta — ve her birinin altında “bizde ne işe yaradı” notu.

DN Yazılım sitesi de aynı stack'te: OpenNext build, Workers deploy, veri D1'de. Aşağıdakiler dokümantasyon tekrarı değil; pipeline'da gerçekten vakit kaybettiren yerler. Eğer “OpenNext kurduk, local'de çalışıyor, production'da garip” aşamasındaysanız büyük ihtimalle listedekilerden birindesiniz.

1. Binding'leri unutmak (veya yanlış ortamda tanımlamak)

Workers tarafında D1, R2, KV ve secret'lar binding ile geliyor. Local'de next dev ile çalışırken bu binding'ler yoksa tablo yok, env undefined, “neden local'de çalışıyordu?” paniği başlıyor. Wrangler config'teki binding adı ile kodda env.DB / getCloudflareContext() tarafının aynı olduğundan emin olun.

Bizde düzen şöyle oturdu: local migration'ı dev script'ine bağlamak. db:migrate:local çalışmadan uygulamayı “temiz” saymıyoruz. Production'da remote migration ayrı bir adım; build'in geçmesi şemanın güncel olduğu anlamına gelmez.

  • Binding isimleri kod ve wrangler arasında birebir aynı olsun.
  • Secret'ları (API key, JWT) plain env sanıp commit etmeyin.
  • Preview ve production ortamlarında binding setinin farkını yazılı tutun — tek config her yerde yetmeyebilir.
  • Yeni bir binding eklediğinizde hem local hem preview'da smoke test yapın; “merging confetti” yetmez.

Küçük ama pahalı hata: staging'de bir D1 database'e, production'da başka birine bakıp “veri kayboldu” sanmak. Ortam isimlerini ve database id'lerini README'ye yazmak abartı değil.

2. Image pipeline: next/image varsayımları

App Router'da next/image alışkanlığı güçlü. Cloudflare tarafında optimizer ve remote pattern kuralları farklı işler. Yerel /public görselleri genelde sorun çıkarmaz; harici domain, dinamik resize veya uzak CMS medyası erken planlanmalı.

Biz pratikte ağır asset'leri R2'ye taşımayı veya statik public path kullanmayı tercih ettik. “Her şeyi image optimizer üzerinden geçireyim” yaklaşımı edge'de sürpriz çıkarıyor: beklenmeyen domain, boyut limiti, veya build sırasında resolve edilemeyen URL.

Cover image, OG görselleri ve portföy fotoğrafları için net bir kaynak stratejisi yazın:

  • Site UI ikon / küçük görseller → public
  • Büyük proje fotoğrafları → R2 veya kontrollü CDN
  • OG / sosyal kartlar → build-time generate veya sabit template

Bunu yazmazsanız her yeni sayfada aynı tartışma tekrar açılır.

3. Node API'lerinin bir kısmı yok (veya farklı)

OpenNext Cloudflare, Node uyumluluğunu genişletiyor ama her npm paketinin Workers'ta aynı çalışacağı anlamına gelmiyor. Dosya sistemi varsayımlı paketler, bazı native bağımlılıklar, uzun süren senkron işler — bunlar build'de veya runtime'da patlıyor.

Takım kuralımız: yeni bağımlılık eklerken “bu package Workers edge'de mi?” sorusunu sormak. Gerekirse işi Queue'ya, harici API'ye veya build-time'a kaydırmak. Tool calling / AI gibi özelliklerde model çağrısını Workers üzerinden yapıyorsanız timeout ve CPU limitlerini baştan hesaba katın.

Edge'de çalışmayan bir paket “geçici workaround” ile haftalarca teknik borç biriktirir. Erken kesmek ucuzdur.

Pratik test: şüpheli paketi izole bir Worker route veya küçük script ile denemek. “Main app'e ekleyip görelim” yaklaşımı debug süresini şişirir.

4. Local hızlı, preview yavaş: beklenti yönetimi

next dev iterasyon için hızlıdır. OpenNext preview / full build ise ilk seferlerde uzun gelebilir. Bu çoğu zaman normaldir; paniklenip adapter'ı her hata için suçlamak zaman kaybı.

Bizde işe yarayan akış:

  1. Özellik geliştirirken local Next + local D1.
  2. Cloudflare'e özgü (binding, cache, headers, middleware) değişikliklerde preview.
  3. Production deploy öncesi remote migration + smoke test: anasayfa, bir blog slug, iletişim formu, admin login.

Build süresini kısaltmak için gereksiz paket ve dev-only import'ları client bundle'a sızdırmayın. TipTap gibi editör bağımlılıkları admin-only kalmalı. “Herkes her sayfada aynı layout import'u” alışkanlığı edge bundle'ı şişirir.

Ayrıca CI'da OpenNext build'i çalıştırıyorsanız cache stratejisini ayrı düşünün; developers'ın laptop'undaki süre ile CI süresi farklı hikâyedir.

5. App Router veri katmanı: cache ve revalidate

Workers + D1 kombinasyonunda “her request'te taze” ile “agresif cache” arasında denge kurmak gerekir. Blog listesi ve bölge sayfaları sık değişmez; admin panel ise hemen görmeli.

Yanıltıcı kısım: local'de her şey taze görünürken production'da eski içerik kalması. Path bazlı veya tag bazlı revalidate stratejisini, yazı yayına alınca nasıl invalidate edeceğinizi netleştirin. Bizde yayın sonrası ilgili /blog ve slug path'lerinin güncellenmesi operasyon checklist'inde.

İkinci tuzak: middleware veya auth cookie'si yüzünden cache'in tamamen kapanması. “Her şeyi dinamik yapayım” güvenli görünür ama Türkiye kullanıcıları için gereksiz latency demektir. Hangi route'ların herkese aynı, hangilerinin kullanıcıya özel olduğunu yazılı tutun.

Kısa kontrol listesi (deploy öncesi)

  • Wrangler binding ↔ kod eşleşmesi
  • Local ve remote D1 migration alışkanlığı
  • Image / R2 stratejisi yazılı
  • Yeni paket edge uyumluluk kontrolü
  • Local → preview → production geçiş kuralları
  • Yayın sonrası cache / revalidate checklist
  • Smoke: public sayfalar + bir form + admin

Ne zaman OpenNext mantıklı?

Zaten Next.js App Router kullanıyorsanız ve Cloudflare'in edge ağı, D1, R2, Workers fiyatlandırması işinize uyuyorsa OpenNext güçlü bir yol. Sadece ucuz hosting diye girip Node ekosisteminin tamamını edge'e zorlamak hayal kırıklığı yaratır.

Türkiye odaklı gecikme ve maliyet çerçevesi için Cloudflare Workers ile Türkiye'de Next.js deploy yazısına bakın. Workers'ın genel olarak ne zaman mantıklı olduğu için de eski Workers yazımız hâlâ geçerli.

Mimari destek ve geçiş planı: Cloudflare mimari. Mevcut Next.js projenizi konuşmak için iletişim.

Mesaj