Astro i Headless CMS: Integracja Sanity, Storyblok, Strapi

Opublikowano
29 maja 2026
Aktualizacja
4 czerwca 2026
Czas czytania
5 min czytania

W serii o Astro trzymaliśmy treść w plikach i jest to świetne rozwiązanie dla technicznego bloga pisanego przez programistów (takich, jak właśnie blog StriveLab). W projekcie z redakcją wygląda to inaczej, ponieważ klient nie powinien edytować MDX-a w repozytorium, żeby zmienić opis usługi. Do tego właśnie służy , a Astro spina się z nim bez problemowo.

Czym jest headless CMS i czym różni się od WordPressa

Klasyczny WordPress robi dwie rzeczy jednocześnie. Z jednej strony daje panel do pisania treści, a z drugiej generuje stronę, która ją wyświetla. rozdziela te role:

  • Głowa (frontend) jest odcięta od reszty, a treść nie jest renderowana przez CMS.
  • Backend treści, czyli panel do pisania, baza i API, z którego pobierasz dane.

Frontend budujesz osobno, w tym przypadku w Astro. Dzięki temu zyskujesz pełną kontrolę nad HTML-em, wydajnością i sposobem renderowania, podczas gdy redaktor swobodnie pracuje w panelu. To esencja headlessa, który oznacza wygodę dla redakcji bez oddawania frontendu CMS-owi.

Dwa sposoby podłączenia CMS do Astro

Astro daje dwie ścieżki integracji, a wybór zależy od tego, czy pracujesz na kolekcji treści, czy na pojedynczym zapytaniu z większą liczbą warunków.

Wariant 1: loader w Content Collections (dla blogów i list)

Najczystsze podejście dla treści, która jest kolekcją (artykuły, produkty, autorzy). Definiujesz w content.config.ts, a CMS staje się źródłem typowanej kolekcji — czytanej tak samo jak pliki lokalne:

Code
// src/content.config.ts — przykład ze Storyblokiem
import { defineCollection } from 'astro:content'
import { storyblokLoader } from '@storyblok/astro'
import { z } from 'astro/zod'
 
const articles = defineCollection({
  loader: storyblokLoader({
    accessToken: import.meta.env.STORYBLOK_TOKEN,
    contentTypes: ['article'],
    version: 'published',
  }),
  schema: z.object({
    title: z.string(),
    body: z.string(),
    seo: z.object({
      title: z.string(),
      description: z.string(),
    }),
  }),
})
 
export const collections = { articles }

Efekt: treść z CMS i treść z plików obsługujesz identycznie przez getCollection('articles'), z tym samym typowaniem i walidacją Zod. CMS staje się jednym z wielu źródeł, bez specjalnej ścieżki w kodzie.

Code
---
import { getCollection } from 'astro:content'
 
const articles = await getCollection('articles')
---
 
<ul>
  {articles.map((article) => (
    <li><a href={`/blog/${article.id}/`}>{article.data.title}</a></li>
  ))}
</ul>

Wariant 2: bezpośrednie API (dla dynamicznych zapytań i podglądu)

Zamiast loadera wywołujesz API CMS bezpośrednio we frontmatterze .astro, co daje pełną kontrolę nad zapytaniem — projekcje, filtry, relacje. Sanity używa do tego @sanity/client z językiem zapytań GROQ:

Code
---
// src/pages/produkt/[slug].astro — przykład z Sanity
import { createClient } from '@sanity/client'
 
const client = createClient({
  projectId: import.meta.env.SANITY_PROJECT_ID,
  dataset: 'production',
  useCdn: true,
  apiVersion: '2024-01-01',
})
 
const { slug } = Astro.params
 
const product = await client.fetch(
  `*[_type == "product" && slug.current == $slug][0]`,
  { slug },
)
---
 
<h1>{product.name}</h1>
<p>{product.price} zł</p>

Pełna kontrola nad zapytaniem (projekcje, filtry, relacje) jest możliwa, ale kosztem spójności z systemem kolekcji. Jest to naturalny wybór dla pojedynczych, dynamicznych stron oraz trybu podglądu.

SEO: treść z CMS musi trafić do HTML

Najczęstszy błąd przy integracji CMS z frontendem to pobieranie treści po stronie klienta. Dlaczego? Ponieważ, wtedy crawler dostaje pusty szkielet, a treść dochodzi dopiero po wykonaniu JavaScriptu, co jest bardzo szkodliwe dla SEO. W Astro tego problemu nie ma, bo treść pobierasz w build time albo na serwerze:

  • SSG w Astro pobiera treść z CMS podczas builda i wstawia ją do statycznego HTML. Idealne dla bloga i stron, które zmieniają się rzadko.
  • SSR w Astro pobiera treść na żądanie i renderuje na serwerze, jest to potrzebne przy podglądzie na żywo i częstych zmianach.

W obu wypadkach Google dostaje gotową treść w pierwszej odpowiedzi, bez kosztu renderowania po stronie klienta i bez ryzyka, że ważna treść nie zostanie zaindeksowana. Szerzej o tym w artykule SEO w Astro.

Podgląd na żywo — komfort redakcji

Najmocniejszy argument za CMS dla redakcji to — redaktor widzi zmiany na prawdziwym layoucie, jeszcze zanim opublikuje. To wymaga trybu serwerowego, ponieważ treść musi odświeżać się na żądanie:

  • Tryb draft/preview w Astro pobiera nieopublikowaną wersję treści (version: 'draft' w loaderze albo dedykowany klient podglądu).
  • CMS-y takie jak Storyblok i Sanity dostarczają dedykowane narzędzia podglądu (Visual Editing) wpinane w ten tryb.

Który CMS wybrać

Astro wspiera 50+ systemów. Cztery najlepiej zintegrowane:

CMSMocna stronaDla kogo
SanityElastyczny model treści (GROQ), Visual Editing, hojny darmowy planProjekty wymagające nietypowych struktur treści
StoryblokWizualny edytor blokowy, dedykowana integracja AstroRedakcje ceniące podgląd komponentowy
StrapiHostowany samodzielnie, pełna kontrola nad danymi, open sourceWymogi rezydencji danych, własna infrastruktura
ContentfulDojrzały, enterprise, mocne APIDuże organizacje z istniejącym stackiem

Wybór CMS-a to decyzja o redakcji i danych, nie o Astro — Astro pobierze treść z każdego z nich tym samym wzorcem (loader albo bezpośrednie API).

Kiedy NIE używać CMS — zostań przy plikach

Headless CMS dokłada zależność, koszt i punkt awarii. Nie zawsze się opłaca:

  • Treść piszą programiści — pliki Markdown/MDX w repozytorium dają wersjonowanie w Git, brak zewnętrznej zależności i pełną kontrolę. CMS byłby tu zbędnym narzutem.

  • Mały, statyczny serwis — strona firmowa na kilka podstron rzadko potrzebuje panelu. Content Collections w zupełności wystarczą.

  • Budżet i czas są napięte, czyli integracja CMS, modelowanie treści i konfiguracja podglądu to realna praca. Dla MVP pliki są szybsze.

CMS powinien być wtedy stosowany, kiedy komfort redakcji nietechnicznej albo wielokanałowość treści przeważają nad prostotą plików. Dla mnie osobiście, praca na plikach mdx jest dużo bardziej wygodna i efektywna, ale to moja własna obserwacja, być może wykrzywiona kontrolą nad innymi elementami poza tekstem (komponenty, prosty kod etc.).

Ultraszybkie projekty, łączące lekkość ze skalowalnością.
Astro

Często zadawane pytania

Kiedy headless CMS ma sens w Astro zamiast plików Markdown?

Pliki Markdown/MDX są lepszym rozwiązaniem, gdy treść tworzą, współtworzą lub dostosowują programiści i chcesz wersjonowania w Git. Headless CMS ma sens, gdy treść redagują osoby nietechniczne bez dostępu do repozytorium, gdy potrzebujesz panelu z podglądem na żywo, albo gdy ta sama treść zasila wiele frontendów (strona, aplikacja, newsletter).

Oba podejścia są poprawne. Loader w content.config.ts pobiera treść CMS do typowanej kolekcji, którą czytasz przez getCollection — spójnie z plikami lokalnymi. Bezpośrednie wywołanie API we frontmatterze .astro daje więcej kontroli przy złożonych zapytaniach i podglądzie na żywo. Loader dla blogów i list, bezpośrednie API dla dynamicznych, pojedynczych zapytań.

Astro wspiera 50+ systemów CMS. Najlepiej zintegrowane to Sanity, Storyblok, Strapi i Contentful — część z dedykowanymi pakietami (np. @storyblok/astro), część przez własne SDK (Sanity używa @sanity/client z GROQ). Sprawdź katalog integracji Astro dla aktualnego stanu danego CMS.

Tak, jeśli pobierasz ją w build time (SSG) lub na serwerze (SSR) — wtedy trafia do gotowego HTML, który crawler widzi od razu. Problem pojawia się tylko przy pobieraniu treści po stronie klienta przez JavaScript; w Astro domyślnie tego unikasz, bo treść renderuje się na serwerze albo podczas builda.

Wymaga trybu serwerowego (SSR), bo treść musi odświeżać się na żądanie zamiast być zamrożona w buildzie. Redaktor edytuje w panelu CMS, a tryb draft/preview w Astro pobiera nieopublikowaną wersję na bieżąco. Część CMS-ów (np. Storyblok, Sanity) dostarcza dedykowane narzędzia podglądu wpinane w ten tryb.

O autorze

Maciej Sala

Maciej Sala — Product Manager i Frontend Developer z bogatym doświadczeniem w marketingu internetowym oraz SEO. Na co dzień pracuje z Reactem, Next.js i TypeScriptem, a ostatnio także z Astro i narzędziami do automatyzacji procesów AI. Sprawnie łączy perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat był związany z branżą gier wideo jako project manager i game designer. Absolwent historii na Uniwersytecie Jagiellońskim oraz studiów podyplomowych z marketingu internetowego na AGH w Krakowie. Po godzinach trenuje na siłowni, maluje figurki i rozwija własne projekty side-projecty.

Pomagam przekładać takie tematy na konkretne wdrożenia w frontendzie, SEO, analityce i procesie produktowym.

Skontaktuj się ze mną

Biblioteka wiedzy

Czytaj dalej

Zobacz więcej wpisów

Dynamiczna sitemap.xml w Astro z API CMS-a

Dynamiczna sitemap.xml w Astro z API CMS-a

Jak wygenerować sitemap.xml w Astro z Payload lub Sanity? Praktyczny wzorzec z getStaticPaths, lastmod, sitemap-index i przykładami na example.com.

Maciej Sala

Maciej Sala

Founder StriveLab