Headless CMS to system zarządzania treścią, który przechowuje i edytuje treści, ale nie ma własnej warstwy wyświetlania: udostępnia je przez API (najczęściej w formacie JSON), a stronę lub aplikację budujesz osobno, na przykład w Next.js. Opłaca się, gdy frontend i tak piszą programiści albo ta sama treść ma trafiać w kilka miejsc naraz. Dla prostej strony wizytówki tradycyjny CMS lub kreator jest zwykle tańszy.
Headless CMS to jedno z haseł, które najczęściej pojawia się obok Next.js i Reacta. Poniżej wyjaśniamy, czym jest i jak działa, pokazujemy działający przykład w Strapi, opisujemy najczęstsze problemy i podpowiadamy, kiedy się opłaca. Jeśli dopiero poznajesz systemy zarządzania treścią, zacznij od artykułu Czym jest CMS.
Czym jest headless CMS?
Headless CMS to system zarządzania treścią bez „głowy”, czyli bez gotowej warstwy, która zamienia treść na stronę widoczną w przeglądarce. Dostajesz panel dla redaktorów, bazę i API. Wygląd strony budujesz samodzielnie, w dowolnej technologii. To podejście bywa nazywane API-first.
W tradycyjnym CMS-ie, takim jak WordPress, panel, baza i wyświetlanie to jedna aplikacja. W headless CMS są to dwie osobne części, które łączy API:
| Etap | Co się dzieje | Kto za to odpowiada |
|---|---|---|
| 1. Redakcja | redaktor pisze i publikuje treść w panelu | CMS |
| 2. Przechowywanie | treść trafia do bazy według modelu treści (content model) | CMS |
| 3. Udostępnianie | CMS wystawia treść przez REST API lub GraphQL | CMS |
| 4. Wyświetlanie | frontend pobiera dane i buduje stronę | Twoja aplikacja, np. Next.js |
Czym headless CMS różni się od tradycyjnego?
| Cecha | Tradycyjny CMS (np. WordPress) | Headless CMS |
|---|---|---|
| Wygląd strony | motyw w samym systemie | dowolny frontend pisany osobno |
| Dostarczanie treści | strona HTML z systemu | JSON przez API |
| Wiele kanałów (www, aplikacja mobilna) | trudniejsze | naturalne, jedno źródło treści |
| Potrzebny programista | niekoniecznie | tak, do frontendu |
| Czas startu | krótki, gotowe motywy | dłuższy, trzeba zbudować frontend |
| Powierzchnia ataku | panel i wtyczki na tej samej domenie | panel osobno, frontend zwykle bez wtyczek |
Zalety i wady wynikają z tej różnicy. Zyskujesz swobodę technologiczną, jedno źródło treści i możliwość zbudowania szybkiego frontendu. Płacisz dłuższym startem, koniecznością zbudowania wszystkiego samodzielnie (podglądu, wyszukiwarki, formularzy) i tym, że do każdej zmiany układu potrzebny jest programista.
Jak wygląda headless CMS w praktyce? Przykład ze Strapi
Najłatwiej zrozumieć to na działającym przykładzie. Użyjemy Strapi, otwartoźródłowego headless CMS-a napisanego w JavaScripcie. Przykład uruchomiliśmy w wersji 5.61.0 na Node 22 z bazą SQLite. Strapi wspiera obecnie Node 22, 24 i 26 (wersje nieparzyste nie są wspierane).
Jak utworzyć projekt?
npx create-strapi@latest blog-cms --non-interactive --skip-cloud --use-npm
cd blog-cms
npm run develop
Pierwsze polecenie tworzy projekt z domyślną bazą SQLite, bez logowania do chmury Strapi i bez przykładowych danych. Po instalacji npm run develop uruchamia serwer pod adresem http://localhost:1337, a panel administracyjny jest dostępny pod /admin. Przy pierwszym wejściu tworzysz konto administratora.
Jak dodać typ treści?
W panelu wchodzisz w Content-Type Builder i tworzysz typ „Article” z polami title (tekst), slug (identyfikator URL), body (tekst) oraz relacją do typu „Author”. To właśnie jest model treści, czyli opis tego, jakie dane przechowujesz. Strapi na tej podstawie sam wystawia adres /api/articles.
Dlaczego dostaję błąd 403, zanim pobiorę jakiekolwiek dane?
To najczęstszy problem początkujących. Pierwsze zapytanie do świeżego projektu:
const res = await fetch("http://localhost:1337/api/articles");
console.log(res.status);
zwraca 403 Forbidden. Nie znaczy to, że serwer się zepsuł. Wszystkie typy treści są domyślnie prywatne. Masz dwie możliwości: nadać rolę Public uprawnienie find w Settings → Users & Permissions → Roles → Public albo wysłać zapytanie z tokenem w nagłówku Authorization: Bearer <token>. Po nadaniu uprawnienia to samo zapytanie zwraca 200 i listę opublikowanych wpisów.
Jak pobrać artykuły razem z autorem?
Funkcja, którą uruchomiliśmy w Node 22:
async function getArticles() {
const res = await fetch("http://localhost:1337/api/articles?populate=author");
if (!res.ok) throw new Error(`CMS HTTP ${res.status}`);
const { data, meta } = await res.json();
return {
articles: data.map((a) => ({ title: a.title, author: a.author?.name ?? "brak autora" })),
total: meta.pagination.total,
};
}
console.log(await getArticles());
Wynik dla przykładowych danych to { articles: [{ title: 'Pierwszy wpis', author: 'Ola Nowak' }], total: 1 }. Odpowiedź ma trzy części: data z dokumentami, meta z paginacją (domyślnie 25 wpisów na stronę) i error tylko przy błędzie. Pola leżą na najwyższym poziomie dokumentu, a pojedynczy dokument pobierasz po jego documentId.
Przydatne parametry zapytania sprawdziliśmy w praktyce:
| Cel | Parametr | Wynik w naszym teście |
|---|---|---|
| Powiązane dane | populate=author | do wpisu dochodzi obiekt autora |
| Tylko wybrane pola | fields[0]=title | odpowiedź zawiera tytuł i identyfikatory |
| Filtr | filters[title][$contains]=Pierwszy | jeden pasujący wpis |
| Sortowanie i strona | sort=title:asc&pagination[pageSize]=1 | jeden wpis na stronę |
| Wersje robocze | status=draft | szkice zamiast opublikowanych |
Jakie są najczęstsze problemy z headless CMS?
Pytania ze Stack Overflow pokazują, że w większości przypadków przyczyną jest konfiguracja, nie błąd w kodzie. W naszych testach powtórzyły się trzy objawy:
| Objaw | Przyczyna | Co zrobić |
|---|---|---|
| 403 Forbidden | typ treści jest prywatny | nadaj uprawnienie find roli Public albo użyj tokenu |
| Brakuje autora, obrazu lub komponentu | relacje i media nie są domyślnie w odpowiedzi | dodaj populate |
| Brakuje wpisu, który widać w panelu | wpis jest szkicem | opublikuj go albo zapytaj z status=draft |
ECONNREFUSED | serwer CMS nie działa | uruchom go przed frontendem |
Dwie uwagi praktyczne. Po pierwsze, sprawdź, czy pole slug jest wypełnione: w naszym teście wpisy utworzone przez API miały slug: null, więc filtr po slugu nic nie zwrócił, a w panelu administracyjnym slug wypełnia się z tytułu. Po drugie, na forach często pojawiają się też pytania o wdrożenie Strapi na Vercel i o błąd modułu sharp na Windowsie. Tych przypadków nie testowaliśmy, więc sprawdź dokumentację przed wdrożeniem.
Jakie headless CMS-y są dziś najpopularniejsze?
| CMS | Model | Co warto wiedzieć |
|---|---|---|
| Strapi | otwarte źródło, hostujesz sam | ok. 73 tys. gwiazdek na GitHubie, wersja 5.61.0 |
| Payload | otwarte źródło (MIT), działa w aplikacji Next.js | ok. 46 tys. gwiazdek, wymaga nowszego Node (^22.23.4 lub 24.22.1+) |
| Sanity | chmura, edytor Studio na otwartej licencji | plan Free: 20 miejsc, 250 tys. zapytań API miesięcznie |
| Contentful | platforma chmurowa | popularny w dużych firmach, płatny |
| Directus | otwarte źródło, nakładka na istniejącą bazę SQL | ok. 39 tys. gwiazdek |
| Ghost | otwarte źródło (MIT), nastawiony na blogi i newslettery | ok. 56 tys. gwiazdek |
Liczby z GitHuba pochodzą z 8 listopada 2026 i rosną z dnia na dzień, a ceny planów chmurowych pomijamy, bo często się zmieniają. Przetestowaliśmy tylko Strapi, więc opisy pozostałych opierają się na ich dokumentacji. Pełniejsze porównanie z systemami tradycyjnymi znajdziesz w artykule o CMS-ach.
Kiedy warto wybrać headless CMS?
| Sytuacja | Lepszy wybór |
|---|---|
| Frontend w Next.js lub Reakcie piszą programiści | headless |
| Ta sama treść ma trafiać na stronę, do aplikacji mobilnej i innych miejsc | headless |
| Zależy Ci na minimalnej liczbie punktów ataku na stronie publicznej | headless z frontendem generowanym wcześniej |
| Prosta strona firmowa bez programisty | WordPress lub kreator |
| Mały sklep bez programisty | Shopify lub Wix |
Nasza prosta reguła: headless wybierz wtedy, gdy frontend i tak piszą programiści, a nie dlatego, że jest modny. Jeśli redaktor chce tylko zmienić tekst na stronie wizytówki, WordPress lub kreator będzie tańszy i szybszy do uruchomienia, a headless dołoży Ci pracy bez widocznej korzyści. Zaczyna się opłacać, gdy masz programistę i zależy Ci na swobodzie. W sklepach działa to podobnie: Shopify oferuje podejście headless w ramach frameworka Hydrogen, o czym piszemy w artykule o zawodzie Shopify developera.
Czy headless CMS wymaga znajomości Next.js i Reacta?
Nie musi, bo API jest niezależne od technologii, a pobierać dane możesz z dowolnego języka. W praktyce headless CMS najczęściej łączy się z Next.js i Reactem, bo dobrze radzą sobie z tworzeniem stron wcześniej, co jest ważne dla szybkości i indeksacji w wyszukiwarkach. Jeśli chcesz pójść tą drogą, zacznij od czym jest React, potem przejdź do Next.js, a podstawy HTML, CSS i JavaScript możesz utrwalić w naszym kursie frontendu.


