Strapi CMS. Dlaczego wybrałem go zamiast WordPress i jak go używam z Next.js
Kiedy zakładałem agencję interaktywną, musiałem wybrać stack, na którym będę budować projekty klientów. Frontend był oczywisty: Next.js z TypeScriptem. Ale co z backendem? Co z zarządzaniem treściami?
WordPress? Za ciężki, za wolny, za dużo legacy. Contentful? Drogi w skali. Sanity? Fajny, ale za dużo vendor lock-in.
Wybrałem Strapi CMS. Headless CMS, open source, z własnym hostingiem. I po kilkunastu projektach mogę powiedzieć: to była dobra decyzja. Nie idealna. Dobra.
Headless CMS, co to jest
Zanim wejdę w Strapi, wyjaśnijmy jedną rzecz, bo widzę dużo zamieszania wokół tego terminu.
Tradycyjny CMS (jak WordPress) to monolityczny system. Frontend (to, co widzi użytkownik) i backend (panel admina, baza danych) są ze sobą połączone. Edytujesz treść w panelu, WordPress generuje HTML i wyświetla stronę. Wszystko w jednym.
Headless CMS to CMS “bez głowy”. Ma backend (panel admina, API, bazę danych), ale nie ma frontendU. Nie generuje HTML. Zamiast tego udostępnia treści przez API (REST lub GraphQL), a Ty budujesz frontend w dowolnej technologii: Next.js, Nuxt, Astro, React Native, cokolwiek.
Dlaczego to ważne? Bo oddzielenie frontendu od backendu daje Ci wolność. Możesz zmienić frontend bez dotykania CMS. Możesz użyć tych samych treści na stronie, w aplikacji mobilnej i w newsletterze. Jeden backend, wiele frontendów.
Dlaczego Strapi CMS (a nie WordPress, Contentful, Sanity)
Porównajmy opcje, które rozważałem:
WordPress. Najpoprularniejszy CMS na świecie. 43% stron w internecie. Ogromny ekosystem pluginów. Ale: wolny, ciężki, problemy z bezpieczeństwem, trudny do customizacji poza szablonami. WordPress można użyć jako headless (WP REST API), ale to hack, nie native rozwiązanie. Pisałem o tym więcej w kontekście tworzenia stron internetowych.
Contentful. Headless CMS jako usługa (SaaS). Świetny produkt, ale drogi. Darmowy plan do 25 000 rekordów, potem zaczyna się od 300 USD/miesiąc. Dla agencji z wieloma projektami to się nie kalkuluje.
Sanity. Podobny do Contentful, ale z lepszym modelem cenowym i bardziej elastycznym edytorem (GROQ). Problem: Twoje dane są na ich serwerach. Migracja to koszmar. Vendor lock-in.
Strapi CMS. Open source. Self-hosted (Twój serwer, Twoje dane). Darmowy do użytku komercyjnego. Panel admina out of the box. REST i GraphQL API. Pełna kontrola nad modelami danych. I najważniejsze: TypeScript natywnie.
Strapi wygrał, bo:
- Darmowy. Zero opłat licencyjnych. Płacę tylko za hosting (VPS za 50-100 zł/miesiąc).
- Self-hosted. Moje dane, moje serwery, moje reguły. Zero vendor lock-in.
- TypeScript. Cały ekosystem w jednym języku: frontend (Next.js) i backend (Strapi) w TypeScript.
- Elastyczny. Definiujesz modele danych w panelu lub w kodzie. Custom fields, relacje, media, lokalizacja, wszystko.
- API-first. REST i GraphQL gotowe od razu. Podłączasz frontend i lecisz.
Mój setup: Next.js + Strapi w monorepo
Tu jest konkrety. Mój stack w agencji to TypeScript z Next.js na frontendzie i Strapi na backendzie. Trzymam to w monorepo, gdzie Strapi siedzi w katalogu _strapi wewnątrz projektu Next.js.
Struktura projektu:
projekt/
├── src/ ← Next.js frontend
│ ├── app/
│ ├── components/
│ └── lib/
├── _strapi/ ← Strapi CMS backend
│ ├── src/
│ │ ├── api/ ← modele danych i controllery
│ │ └── admin/ ← customizacja panelu
│ ├── config/
│ └── package.json
├── package.json ← root
└── tsconfig.json
Dlaczego monorepo? Bo nie chcę żonglować między repozytoriami. Jeden git clone, jeden CI/CD pipeline, jeden PR na zmianę, która dotyka frontendu i backendu jednocześnie. Prostota.
Jak to działa w praktyce:
- Strapi stoi na VPS (DigitalOcean, Hetzner, cokolwiek) i serwuje API.
- Next.js pobiera dane z API Strapi w
getStaticPropslubgetServerSideProps(zależnie od potrzeb). - Klient loguje się do panelu Strapi, edytuje treści (teksty, zdjęcia, SEO meta), klika “opublikuj”.
- Next.js przebudowuje stronę (ISR lub webhook + rebuild).
- Użytkownik widzi zaktualizowaną stronę.
Klient nie dotyka kodu. Nigdy. Ma panel z polami, które my definiujemy. Wpisuje tekst, uploaduje zdjęcie, gotowe. A my mamy pełną kontrolę nad tym, jak to wygląda na stronie.
Zalety Strapi w codziennej pracy
Po kilkunastu projektach na Strapi, oto co cenię najbardziej:
Content types builder. Definiujesz strukturę danych w panelu admina. Potrzebujesz typu “Artykuł” z polami: tytuł, treść, autor, kategoria, obrazek wyróżniający? Klikasz, nazywasz pola, ustawiasz typy. Strapi generuje API automatycznie. Nie piszesz ani jednej linii kodu na CRUD.
Customizacja bez ograniczeń. Kiedy out-of-the-box nie wystarczy, masz dostęp do kodu. Custom controllery, middleware, lifecycle hooks, custom fields. Strapi to framework, nie czarna skrzynka.
Rola i uprawnienia. Chcesz, żeby copywriter edytował tylko artykuły, a admin zarządzał użytkownikami? Role-based access control jest wbudowany. Ważne dla projektów z wieloma osobami.
Media library. Upload zdjęć, automatyczny resize, integracja z S3/Cloudinary. Klient uploaduje zdjęcie 5 MB, Strapi serwuje zoptymalizowaną wersję.
Internacjonalizacja (i18n). Wbudowane wsparcie dla wielu języków. Klient wpisuje treść po polsku i po angielsku w tym samym panelu. Frontend serwuje odpowiednią wersję.
Wady Strapi (bo nie ma idealnych narzędzi)
Nie będę udawał, że Strapi jest perfekcyjny.
Performance przy dużych zbiorach. Strapi na domyślnej konfiguracji (SQLite) nie obsłuży miliona rekordów. Na PostgreSQL jest OK, ale nadal nie jest to baza danych zoptymalizowana pod heavy read. Dla większości projektów to nie problem. Dla platform z milionami wpisów, rozważ dedykowany backend.
Aktualizacje bywają bolesne. Przejście z v4 na v5 wymagało pracy. Breaking changes, migracja bazy, zmiana API. Strapi rozwija się szybko, ale to znaczy, że upgrade path nie zawsze jest gładki.
Krzywa uczenia. Jeśli nigdy nie stawiałeś backendu, Strapi wymaga zrozumienia Node.js, baz danych, deploymentu na serwer. To nie jest WordPress, który hostujesz na shared hostingu za 10 zł/miesiąc.
Panel admina mógłby być lepszy. UX panelu jest OK, ale nie świetny. Klienci czasem potrzebują onboardingu, bo interfejs nie jest tak intuicyjny jak np. WordPress Gutenberg. Ale po kilku minutach ogarniają.
Kiedy Strapi, a kiedy nie
Użyj Strapi, kiedy:
- Budujesz custom frontend (Next.js, Nuxt, Astro) i potrzebujesz CMS dla klienta.
- Chcesz pełną kontrolę nad danymi (self-hosting).
- Projekt wymaga API (REST/GraphQL) do zasilania wielu frontendów.
- Pracujesz w TypeScript i chcesz spójny stack.
Nie używaj Strapi, kiedy:
- Potrzebujesz prostego bloga (użyj Jekyll/Hugo albo WordPress).
- Nie chcesz zarządzać serwerem (użyj Contentful lub Sanity).
- Projekt to strona wizytówka bez dynamicznych treści (statyczny generator wystarczy).
- Nie znasz JavaScript/TypeScript (krzywa uczenia będzie za stroma).
Strapi vs WordPress w 2026
To porównanie, o które pytają mnie klienci najczęściej.
WordPress: ogromny ekosystem, tysiące szablonów, niski próg wejścia, tani hosting. Ale: monolityczny, wolny, problemy z bezpieczeństwem, trudna customizacja.
Strapi CMS: API-first, nowoczesny stack, pełna kontrola, TypeScript. Ale: wymaga developera, self-hosting, mniejszy ekosystem pluginów.
Moja zasada: jeśli klient potrzebuje strony “jak każda inna” i ma mały budżet, WordPress jest OK. Jeśli klient potrzebuje czegoś custom, co ma rosnąć z biznesem, Strapi + Next.js nie ma konkurencji w tej klasie cenowej.
Na koniec
Strapi CMS to nie jest narzędzie dla każdego. Wymaga umiejętności technicznych, serwera i czasu na konfigurację. Ale jeśli budujesz nowoczesne aplikacje webowe i potrzebujesz headless CMS, który jest darmowy, open source i daje Ci pełną kontrolę, Strapi jest jednym z najlepszych wyborów w 2026 roku.
Obsidian zmienił sposób, w jaki prowadzę notatki. Strapi zmienił sposób, w jaki buduję aplikacje dla klientów. Oba narzędzia mają wspólną cechę: dają Ci własność nad Twoimi danymi. I w czasach, gdy wszystko idzie do chmury, to jest wartość, której nie da się przecenić.
Powiązane wpisy
-
TypeScript vs JavaScript. Dlaczego w agencji piszemy TS wszędzie i kiedy JS nadal ma sens
Kilka lat temu straciłem cały weekend na buga, który TypeScript znalazłby w 3 sekundy. Pole `userId` w API zwracało r...