Bir ürünün düzenli içerik üretimi, çok kanallı yayın veya editör iş akışı ihtiyacı varsa CMS değerlendirilebilir. Headless CMS yaklaşımı içerik yönetimi ile sunum katmanını ayırır; bu ayrım esneklik sağlayabildiği gibi ek entegrasyon, önizleme, güvenlik ve işletim sorumluluğu da getirir. Bu rehber Strapi, Sanity ve Contentful'u karar ölçütleri üzerinden karşılaştırır.
Headless CMS Nedir?
Geleneksel CMS kurulumu çoğunlukla içerik yönetimi ile tema/render katmanını aynı ürün içinde sunar. WordPress gibi sistemler varsayılan olarak bu modelde kullanılabilir, ancak API üzerinden decoupled/headless kurulumları da mümkündür. Headless yaklaşımda ise:
- Backend (CMS): İçerik oluşturma, düzenleme, yönetme — API üzerinden sunar
- Frontend (Web/Mobil/Kiosk): İçeriği API'den çekerek istediği şekilde gösterir
Bu ayrımın olası sonuçları:
- Birden fazla kanal: Aynı içerik modeli web, mobil veya diğer istemcilerce kullanılabilir; her kanalın sunum ve erişilebilirlik işi yine ayrıdır.
- Render seçeneği: Frontend statik, sunucu taraflı veya hibrit render edilebilir; headless mimari tek başına hızlı sayfa garantisi vermez.
- Güvenlik sınırı: Yönetim arayüzü ile yayın API'si ayrılabilir; API yetkisi, token yönetimi ve ağ erişimi ayrıca tasarlanmalıdır.
- Bağımsız ölçekleme: Sunum ve içerik servisleri ayrı ölçeklenebilir; bu da daha fazla gözlemlenebilirlik ve hata senaryosu doğurur.
- Teknoloji seçimi: İstemci katmanı CMS temasından bağımsız seçilebilir; içerik şeması ve taşınabilirlik yine platforma bağlı olabilir.
Strapi: Açık Kaynak ve Self-Hosted
Strapi açık kaynaklı bir headless CMS'tir; kendi altyapınızda çalıştırılabilir veya sağlayıcının yönetilen bulut seçeneği değerlendirilebilir. Self-hosting daha fazla altyapı kontrolü verir, ancak güvenlik güncellemesi, yedekleme, veritabanı ve medya teslimatı sorumluluğunu ortadan kaldırmaz.
Güçlü Yanları
Altyapı kontrolü ve özelleştirme:
type StrapiPost = {
documentId: string;
title: string;
slug: string;
content: string;
image?: { url?: string };
publishedAt: string;
};
type StrapiCollectionResponse<T> = { data: T[] };
type BlogPostView = {
id: string;
title: string;
slug: string;
content: string;
image?: string;
publishedAt: string;
};
// Strapi 5 REST API ile veri çekme
async function getPosts(): Promise<BlogPostView[]> {
const res = await fetch(
`${STRAPI_URL}/api/posts?populate=*&sort=publishedAt:desc`,
{
headers: {
Authorization: `Bearer ${STRAPI_TOKEN}`,
},
next: { revalidate: 60 }, // Örnek güncellik politikası
}
);
if (!res.ok) throw new Error(`Strapi isteği başarısız: ${res.status}`);
const payload = (await res.json()) as StrapiCollectionResponse<StrapiPost>;
return payload.data.map((item) => ({
id: item.documentId,
title: item.title,
slug: item.slug,
content: item.content,
image: item.image?.url,
publishedAt: item.publishedAt,
}));
}
Strapi 5 REST yanıtları önceki sürümdeki attributes sarmalayıcısını kullanmaz; güncel Strapi dokümantasyonu kurulan sürüm için esas alınmalıdır. Yukarıdaki TypeScript assertion runtime doğrulama yapmaz. Dış API yanıtı, üretimde şema doğrulayıcıyla kontrol edilmeli; token yalnızca sunucu ortamında tutulmalıdır.
Genişletme modeli: Strapi özellikleri eklenti veya özel kodla genişletilebilir. Eklentinin Strapi sürümü, lisansı, bakım durumu ve güvenlik geçmişi kurulumdan önce kontrol edilmelidir.
Content Types Builder: Görsel arayüzden veya kod ile içerik tiplerini tanımlayın.
Yerelleştirme: İçerik locale'leri ile yönetim arayüzünün dili ayrı gereksinimlerdir. Kullanılan Strapi sürümünde i18n davranışı, slug normalizasyonu, arama/sıralama ve Türkçe karakter akışları örnek içerikle test edilmelidir.
Zayıf Yanları
- İşletim yükü: Self-hosted kurulumda sunucu, güncelleme, yedekleme ve güvenlik ekibin sorumluluğundadır.
- Kapasite planlama: Sorgular, veritabanı bağlantıları ve cache yoğun trafikte ölçülmelidir.
- Medya mimarisi: Yerel disk yerine kalıcı object storage/CDN gereksinimi dağıtım ortamına göre tasarlanmalıdır.
- Eklenti bağımlılığı: Major sürüm geçişlerinde üçüncü taraf eklenti uyumluluğu ayrıca incelenmelidir.
Maliyet Modeli
Strapi'nin açık kaynak lisansı, toplam işletim maliyetinin sıfır olduğu anlamına gelmez. Self-hosting hesabına uygulama compute'u, veritabanı, object storage/CDN, log, yedekleme, güvenlik bakımı ve ekip zamanı eklenmelidir. Yönetilen seçenekte plan, koltuk ve kullanım sınırları resmî Strapi fiyatlandırmasından teklif tarihinde kontrol edilmelidir.
Kimin İçin Uygun?
- Teknik ekibi olan projeler
- Altyapı konumu ve işletim kontrolünü kendi uyumluluk planı içinde yönetmek isteyen kurumlar
- Özelleştirme ihtiyacı yüksek projeler
- Self-hosting sorumluluğunu ölçebilen ekipler
Sanity: Yönetilen Content Lake ve Studio
Sanity, içeriği yönetilen Content Lake'te saklar; sorgu için GROQ, editör arayüzü için özelleştirilebilir Sanity Studio sunar. Content Lake dokümanı, gerçek zamanlı API ve veri katmanının temel davranışlarını açıklar.
Güçlü Yanları
GROQ sorgu dili:
// GROQ ile veri çekme
import { createClient } from "@sanity/client";
const client = createClient({
projectId: "your-project-id",
dataset: "production",
useCdn: true, // Herkese açık, cache'lenebilir production okumaları
apiVersion: "2026-01-01",
});
// GROQ sorgusu
async function getPosts() {
return client.fetch(`
*[_type == "post" && !(_id in path("drafts.**"))] | order(publishedAt desc) {
_id,
title,
slug,
excerpt,
publishedAt,
"author": author->{ name, image },
"categories": categories[]->{ title, slug },
"mainImage": mainImage.asset->url
}
`);
}
// İlişkisel veri çekme — tek sorguda
async function getPostWithRelated(slug: string) {
return client.fetch(`
*[_type == "post" && slug.current == $slug][0] {
...,
"author": author->{ name, bio, image },
"related": *[_type == "post" && slug.current != $slug &&
count(categories[@._ref in ^.^.categories[]._ref]) > 0
] | order(publishedAt desc) [0...3] {
title, slug, excerpt, mainImage
}
}
`, { slug });
}
useCdn: true taslak önizlemesi veya en güncel mutasyonun hemen okunması gereken her akış için uygun değildir. Token, perspective, CDN ve cache seçimi production ile preview istemcilerinde ayrı yapılandırılmalıdır.
Gerçek zamanlı işbirliği: Birden fazla editör aynı içerik üzerinde çalışabilir; çatışma davranışı ve rol yetkileri gerçek editoryal akışla denenmelidir.
Portable Text: Zengin metin içeriği, yapılandırılmış veri olarak saklanır. Her frontend kendi render'ını yapabilir.
Sanity Studio: React tabanlı editör uygulaması şema ve eklentilerle özelleştirilebilir. “Tamamen özelleştirilebilir” varsayımı yerine gereken alan bileşeni, önizleme ve erişim kontrolleri prototiplenmelidir.
Zayıf Yanları
- Kullanıma bağlı maliyet: Koltuk, API/CDN, asset ve özellik sınırları planla birlikte değerlendirilmelidir.
- Öğrenme eğrisi: GROQ ve Portable Text yeni kavramlar
- Taşınabilirlik işi: Dataset dışa aktarılabilse de referanslar, Portable Text ve asset akışı hedef sisteme dönüştürülmelidir.
Maliyet Modeli
Sanity'nin plan adları, dahil kotaları ve aşım ücretleri zamanla değişebilir. Güncel koltuk, dataset, API, asset ve özellik sınırları resmî Sanity fiyatlandırmasından kontrol edilmeli; production, preview ve geliştirme trafiği ayrı tahmin edilmelidir.
Kimin İçin Uygun?
- İçerik ekibi birden fazla kişiyse (gerçek zamanlı işbirliği)
- Esnek ve yapılandırılmış içerik modeli gerekiyorsa
- Studio'yu şema ve özel bileşenlerle yönetebilecek frontend ekibi varsa
- Yönetilen içerik altyapısının maliyet ve veri konumu koşulları uygunsa
Contentful: Yönetilen İçerik Platformu
Contentful, içerik modeli ile teslimat API'lerini yönetilen bir hizmet olarak sunar. Uygunluğu marka iddiası veya pazar sıralamasıyla değil; model limitleri, editör akışı, ortam yönetimi, API kotaları, veri bölgesi ve sözleşme koşullarıyla değerlendirilmelidir.
Güçlü Yanları
İçerik modelleme:
Contentful içerik modeli, content type, field ve entry ilişkileri üzerine kurulur. Kullanılabilir alan tipleri ve plan limitleri çalışma alanında doğrulanmalı; şema değişiklikleri migration ve geriye dönük uyumluluk planıyla yönetilmelidir.
GraphQL ve REST API:
// Contentful GraphQL API
const GET_POSTS = `
query GetPosts($limit: Int!, $skip: Int!) {
blogPostCollection(
limit: $limit
skip: $skip
order: publishedAt_DESC
) {
total
items {
title
slug
excerpt
publishedAt
featuredImage {
url
width
height
}
author {
name
avatar {
url
}
}
contentBody {
json
links {
assets {
block {
sys { id }
url
description
}
}
}
}
}
}
}
`;
async function getPosts(page = 1, perPage = 10) {
if (!Number.isInteger(page) || page < 1) {
throw new RangeError("page pozitif bir tam sayı olmalı");
}
if (!Number.isInteger(perPage) || perPage < 1) {
throw new RangeError("perPage pozitif bir tam sayı olmalı");
}
const res = await fetch(
`https://graphql.contentful.com/content/v1/spaces/${SPACE_ID}/environments/${ENVIRONMENT_ID}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${CONTENTFUL_TOKEN}`,
},
body: JSON.stringify({
query: GET_POSTS,
variables: { limit: perPage, skip: (page - 1) * perPage },
}),
next: { revalidate: 60 }, // Örnek güncellik politikası
}
);
if (!res.ok) throw new Error(`Contentful isteği başarısız: ${res.status}`);
const payload = (await res.json()) as {
data?: { blogPostCollection?: unknown };
errors?: Array<{ message: string }>;
};
if (payload.errors?.length || !payload.data?.blogPostCollection) {
throw new Error("Contentful geçerli bir koleksiyon döndürmedi");
}
return payload.data.blogPostCollection;
}
GraphQL şeması içerik modelinden üretilir; sorgu karmaşıklığı, hata yanıtları ve limitler Contentful GraphQL API dokümanına göre ele alınmalıdır. TypeScript tipi tek başına API yanıtını runtime'da doğrulamaz. Delivery/Preview token'ı yalnızca sunucuda tutulmalı ve gereken en dar erişimle kullanılmalıdır.
Yönetim özellikleri: Rol, iş akışı, webhook, ortam ve denetim yeteneklerinin kapsamı plana göre değişebilir; satın alma kararında gereken özelliklerin dahil olduğu yazılı olarak doğrulanmalıdır.
API ve entegrasyonlar: REST ve GraphQL istemcileri farklı frontend'lerle kullanılabilir. Her SDK veya entegrasyonun resmî bakım durumu ve kullanılan runtime sürümü ayrıca kontrol edilmelidir.
Zayıf Yanları
- Plan ve kullanım maliyeti: Koltuk, space, locale, API, asset ve özellik ihtiyacı birlikte fiyatlanmalıdır.
- Şema yönetişimi: Referans ağı ve ortamlar büyüdükçe migration disiplini gerekir.
- Rich text entegrasyonu: Gömülü entry ve asset'ler frontend tarafında açık render kuralları ister.
- API limitleri: Sorgu ve teslimat trafiği yayın mimarisinde ölçülmelidir.
Maliyet Modeli
Sabit fiyat ve kota tablosu hızla eskir. Güncel planlar, dahil kullanıcılar, içerik/model limitleri ve sözleşme özellikleri resmî Contentful fiyatlandırmasından kontrol edilmelidir. Aylık tahmin; production ve preview çağrıları, asset trafiği, ekip büyümesi ve ortam sayısını içermelidir.
Kimin İçin Uygun?
- Yönetilen SaaS işletim modeli kurumun veri ve satın alma koşullarına uyuyorsa
- API tabanlı çok kanallı içerik dağıtımı gerekiyorsa
- Gereken rol, ortam ve onay akışları seçilen planda doğrulanmışsa
- Kullanım büyümesi ve çıkış maliyeti toplam sahip olma hesabına dahil edilmişse
Kapsamlı Karşılaştırma
| Karar Alanı | Strapi | Sanity | Contentful |
|---|---|---|---|
| İşletim modeli | Self-hosted veya Strapi Cloud | Yönetilen Content Lake; dağıtılabilir Studio | Yönetilen içerik platformu |
| Sorgu arayüzü | REST; GraphQL eklentisi seçeneği | GROQ; dağıtılan GraphQL API seçeneği | REST ve GraphQL |
| Özelleştirme sınırı | Backend kodu, admin ve eklentiler | Şema, Studio ve özel bileşenler | İçerik modeli, uygulamalar ve entegrasyonlar |
| Başlıca maliyet etkeni | Altyapı/operasyon veya cloud planı | Koltuk, kullanım, asset ve özellikler | Koltuk, space, kullanım ve özellikler |
| Taşıma işi | Veritabanı, medya ve özel eklentiler | Dataset, referanslar ve Portable Text dönüşümü | Entry, asset, referans ve rich text dönüşümü |
| Kontrol edilmesi gerekenler | Sürüm/eklenti uyumu ve operasyon | Preview/CDN ayrımı ve Studio bakımı | Model limitleri, ortamlar ve sözleşme kapsamı |
Bu tablo kalite puanı veya fiyat teklifi değildir. Locale modeli, rol matrisi, preview, webhook güvenilirliği, veri bölgesi, yedekleme/geri yükleme ve çıkış planı her sağlayıcıda ayrıca doğrulanmalıdır.
CMS Seçim Rehberi
Strapi'yi değerlendirin, eğer:
- Self-hosting veya backend özelleştirmesi için operasyon kapasiteniz varsa
- Veritabanı, medya ve ağ konumunu kendi uyumluluk tasarımınız içinde yönetmeniz gerekiyorsa
- Eklenti ve major sürüm bakımını üstlenebiliyorsanız
Sanity'yi değerlendirin, eğer:
- Birden fazla editör aynı anda çalışacaksa
- GROQ ve Portable Text veri modeli ihtiyaçlarınıza uyuyorsa
- Özel editör deneyimini Studio içinde geliştirecek ekibiniz varsa
Contentful'u değerlendirin, eğer:
- Yönetilen ortamlar ve API tabanlı çok kanallı dağıtım gerekiyorsa
- İçerik modeli ile rol/iş akışı gereksinimleri seçilen planda karşılanıyorsa
- Gereken destek ve SLA koşulları sözleşmede doğrulanabiliyorsa
Maviona'nın Değerlendirme Çerçevesi
CMS seçimi; içerik ekibinin günlük akışı, yayın sıklığı, preview/onay ihtiyacı, locale sayısı, entegrasyonlar ve belirlenen planlama dönemi boyunca işletim sorumluluğu birlikte değerlendirilerek yapılmalıdır. Dosya tabanlı içerik yönetimi (MDX/Markdown + Git) de bazı kapsamlar için bir seçenektir:
- Commit edilen içerik değişiklikleri Git geçmişinde izlenebilir.
- İçerik şeması kod inceleme ve CI kontrollerine bağlanabilir.
- Ayrı CMS sunucusu gerekmeyebilir; build, preview, repository ve teslimat maliyeti yine vardır.
- Teknik olmayan editörler için Git tabanlı akış ek eğitim veya özel arayüz gerektirebilir.
Bu yaklaşımın ölçeği sınırsız değildir; build süresi, repository büyüklüğü, eşzamanlı düzenleme ve yayın gecikmesi ölçülmelidir. Teknik olmayan editörlerin sık yayın yaptığı projelerde yönetilen veya self-hosted CMS seçenekleri gerçek bir içerik göreviyle prototiplenmelidir.
Sonuç
Headless CMS seçimi ürünün içeriği kadar ekibin işletim modelini de belirler. Sağlayıcı demosunun yanında şema migration'ı, preview, rol yetkisi, cache invalidation, export ve geri yükleme senaryosu denenmeden uzun vadeli uygunluk varsayılmamalıdır.
Kaynak ve Yöntem Notu
Strapi 5 yanıt modeli ile Strapi, Sanity ve Contentful ürün/fiyat bilgileri yukarıda bağlanan resmî dokümantasyon ve fiyat sayfalarından 14 Temmuz 2026'da kontrol edildi. Fiyatlar ve kotalar sabitlenmedi; satın alma tarihinde yeniden doğrulanmalıdır. Kod örnekleri öğretici ve hipotetiktir, gerçek Maviona müşteri entegrasyonu veya ölçülmüş sonuç değildir. Kaynaklar Maviona'yı değerlendirmez veya onaylamaz.
CMS seçimi ve entegrasyonu konusunda yardıma ihtiyacınız varsa, Maviona ile iletişime geçin.
