Sanity CMS + Next.js — od instalacji po live preview i Visual Editing
Jak zintegrować Sanity CMS z Next.js App Router? Schema, GROQ queries, ISR, live preview, Visual Editing i deploy — kompletny setup headless CMS dla strony usługowej.
Sanity to headless CMS z edycją w czasie rzeczywistym, schematem definiowanym w kodzie i dopracowaną integracją z Next.js. W porównaniu z Contentful wyróżnia się schema-as-code — typy treści definiujesz w TypeScript, nie przez GUI, więc schema żyje w repozytorium razem z kodem. W porównaniu ze Strapi nie wymaga własnego serwera i bazy danych — Sanity hostuje wszystko za Ciebie.
Dla stron usługowych w Next.js — Sanity pozwala klientowi edytować treści (teksty, zdjęcia, meta tagi, FAQ) bez Twojej pomocy.
Setup
Code
# Inicjalizacja Sanity w projekcie Next.jsnpm create sanity@latest -- --project-id xxx --dataset production --template cleannpm install next-sanity @sanity/image-url @portabletext/react
Sanity Studio (panel admina) działa jako route w Twojej aplikacji Next.js — na /studio.
Wygeneruj typy TypeScript ze schemy, żeby uniknąć any w komponentach:
Code
npx sanity typegen generate
Tworzy sanity.types.ts — importuj stamtąd typy zamiast pisać je ręcznie.
Zapytania GROQ
GROQ to język zapytań Sanity — podobny do GraphQL, ale prostszy. Każde zapytanie powinno deklarować cache tagi, żeby on-demand revalidation działała poprawnie:
Zamiast czekać na rewalidację czasową — odśwież stronę natychmiast po edycji w Sanity:
Code
// app/api/revalidate/route.tsimport { revalidateTag } from 'next/cache'import { NextRequest, NextResponse } from 'next/server'import { parseBody } from 'next-sanity/webhook'export async function POST(req: NextRequest) { try { const { isValidSignature, body } = await parseBody( req, process.env.SANITY_WEBHOOK_SECRET, ) if (!isValidSignature) { return NextResponse.json({ error: 'Invalid signature' }, { status: 401 }) } const { _type, slug } = body if (_type === 'post') { revalidateTag('posts') if (slug?.current) revalidateTag(`post-${slug.current}`) } return NextResponse.json({ revalidated: true }) } catch (error) { return NextResponse.json({ error: 'Bad Request' }, { status: 400 }) }}
W panelu Sanity: Manage → API → Webhooks → dodaj URL (https://twoja-domena.pl/api/revalidate) i secret.
Draft Mode — włączanie podglądu
Draft Mode to mechanizm Next.js, który przełącza rendering z cache'owanych danych na dane na żywo z Sanity (drafty). Aby wszystko działało poprawnie, zazwyczaj potrzebujesz dwóch route'ów: jednego do włączania podglądu (enable) i drugiego do jego wyłączania (disable):
Code
// app/api/draft/enable/route.tsimport { draftMode } from 'next/headers'import { redirect } from 'next/navigation'import { NextRequest } from 'next/server'export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url) if (searchParams.get('secret') !== process.env.SANITY_PREVIEW_SECRET) { return new Response('Invalid token', { status: 401 }) } const draft = await draftMode() draft.enable() redirect(searchParams.get('redirect') || '/')}
Code
// app/api/draft/disable/route.tsimport { draftMode } from 'next/headers'import { redirect } from 'next/navigation'export async function GET() { const draft = await draftMode() draft.disable() redirect('/')}
W Sanity Studio skonfiguruj Presentation Tool z URL podglądu:
Live Preview umożliwia podgląd zmian w czasie rzeczywistym i aby go zaimplementować, Next.js musi wejść w tryb Draft Mode, który pozwala pobierać nieopublikowane wersje robocze z Sanity. W tym trybie, zamiast domyślnego klienta, używamy previewClient:
previewClient ma perspective: 'previewDrafts' — zwraca nieopublikowane zmiany. Dla pełnego preview na żywo z aktualizacjami w czasie rzeczywistym (bez przeładowania strony) użyj VisualEditing razem z @sanity/preview-kit — dane są wtedy synchronizowane przez WebSocket w momencie każdej zmiany w edytorze.
Visual Editing — edycja treści na żywej stronie
Sanity Visual Editing pozwala klientowi kliknąć dowolny element na stronie i edytować go inline, ma to miejsce bez otwierania panelu Studio:
Klient widzi stronę jak użytkownik, ale edytowalne elementy dostają overlay prowadzący do Sanity Studio lub Presentation Tool. Jeśli Studio jest osadzone w tej samej aplikacji, trzymaj jego route w osobnej grupie layoutów i nie renderuj VisualEditing nad panelem Studio.
Podsumowanie
Połączenie Sanity CMS z Next.js to rewelacyjny wybór dla stron opartych na treści: zyskujesz szybkość statycznej witryny, ale z możliwością natychmiastowej aktualizacji po każdej zmianie w panelu. Dodatkowo, klient może edytować teksty i zdjęcia, klikając je bezpośrednio na podglądzie strony, co jest niezwykle intuicyjne. Dla typowych stron firmowych, blogów czy portfolio, taki zestaw w zupełności wystarcza do wygodnego zarządzania treścią, bez potrzeby tworzenia dedykowanego panelu od podstaw.
Najczęściej zadawane pytania
Ile kosztuje Sanity?
Sanity posiada darmowy plan, ale limity zapytań, CDN, bandwidth i assetów zmieniają się wraz z cennikiem. Generalnie, przy małych stronach darmowy plan może wystarczyć, ale przy większym ruchu lub wielu redaktorach, powinieneś sprawdzić aktualne limity przed wyceną.
Sanity vs Strapi — co wybrać?
Sanity działa w chmurze i jest gotowe do użycia od razu, co oznacza mniej technicznej pracy po Twojej stronie. Oferuje nowoczesne funkcje, jak edycja treści bezpośrednio na stronie (Visual Editing), co jest bardzo wygodne dla klientów. Strapi z kolei instalujesz na własnym serwerze, co daje Ci pełną kontrolę nad danymi i infrastrukturą, ale z drugiej strony wymaga więcej konfiguracji. Sanity to wybór, jeśli cenisz wygodę i nowoczesny interfejs dla redaktorów, a Strapi, jeśli priorytetem jest pełna kontrola nad hostingiem i danymi.
Czy mogę użyć Sanity bez Studio w Next.js?
Tak, Studio to opcjonalny panel admina. Możesz korzystać z Sanity API bezpośrednio z Server Components, bez osadzania Studio w aplikacji, ale Studio w /studio to najwygodniejsze rozwiązanie dla klienta.
Pracuję z tym zawodowo.
Jeśli chcesz przełożyć ten temat na lepszą architekturę frontendu, uporządkować React lub Next.js i podnieść jakość pracy zespołu, skontaktuj się ze mną. Pomagam zamieniać wiedzę z artykułów w praktyczne decyzje technologiczne.
Maciej Sala — project manager i frontendowiec z doświadczeniem w marketingu internetowym. Na co dzień pracuję z Reactem, Next.js i TypeScriptem, łącząc perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat związany z branżą gier wideo jako project manager i game designer.
Absolwent historii na Uniwersytecie Jagiellońskim i studiów podyplomowych z marketingu internetowego na Akademii Górniczo-Hutniczej w Krakowie. Poza pracą trenuje na siłowni, maluje figurki i realizuje własne projekty.
WordPress → Next.js — migracja treści, redirecty 301 i zachowanie pozycji SEO
Jak przenieść stronę z WordPress na Next.js bez utraty pozycji w Google? Eksport treści, mapowanie URL, redirecty 301, migracja obrazów i weryfikacja indeksacji.
Google Search Console + Next.js — indeksacja, błędy, performance i co z nimi robić
Jak korzystać z Google Search Console dla strony Next.js? Weryfikacja, sitemap, indeksacja, Core Web Vitals, crawl budget i najczęstsze problemy — praktyczny poradnik.
Hreflang i canonical w Next.js — SEO wielojęzycznych stron bez duplikacji
Jak poprawnie ustawić hreflang i canonical w Next.js App Router? Unikanie duplikacji treści, konfiguracja metadata API, wielojęzyczna sitemap i typowe błędy SEO.