 Autor: [Monika Wojciechowska](/autorzy/monika-wojciechowska) Specjalistka SEO i treści webowych · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  Headless WordPress z WPGraphQL

# Headless WordPress z WPGraphQL i Next.js 14

Opublikowano: 10 kwietnia 2026 · Kategoria: WordPress

WordPress rządzi rynkiem CMS z dobrych powodów: intuicyjny edytor Gutenberg, tysiące pluginów, znany przez redaktorów. Ale klasyczny motyw WordPress ma ograniczenia wydajnościowe i technologiczne. Rozwiązanie: headless architecture — WordPress tylko jako backend API, a nowoczesny Next.js jako frontend. Redaktorzy pracują w znajomym panelu WP, deweloperzy piszą React i TypeScript, a użytkownicy dostają błyskawicznie szybką stronę generowaną statycznie przez ISR.

## REST API vs GraphQL — porównanie

Kryterium

WordPress REST API

WPGraphQL

Endpoint

/wp-json/wp/v2/posts

/graphql (jeden endpoint)

Selektywne pola

Ograniczone (\_fields param)

Pelna kontrola (tylko to co prosisz)

Powiązane dane

Wiele requestów (posts + authors + tags)

Jeden request (wszystko naraz)

Typowanie

Brak (JSON bez schematu)

Silnie typowany schemat GraphQL

Custom Post Types

Automatyczne, ograniczone

register\_graphql\_object\_type()

Cache

Łatwy (URL-based)

Persisted Queries lub APQ

Krzywa uczenia

Niska

Średnia (GraphQL query language)

## Instalacja WPGraphQL

WPGraphQL to plugin do WordPressa. Instalujesz go jak każdy inny plugin — przez panel admina lub WP-CLI.

\# Przez WP-CLI (SSH na hosting/VPS)
wp plugin install wp-graphql --activate

# Lub przez panel WP: Pluginy > Dodaj nowy > szukaj "WPGraphQL" > Zainstaluj

# Sprawdz ze GraphQL endpoint dziala
curl -X POST https://twojadomena.pl/graphql \\
  -H "Content-Type: application/json" \\
  -d '{"query": "{ posts { nodes { id title } } }"}'

# GraphiQL IDE (w przegladarce — panel WP)
# WP Admin > GraphQL > GraphiQL IDE
# Interaktywne testowanie zapytan

# Przykładowe zapytanie GraphQL — pobierz posty z autorami i tagami
# query {
#   posts(first: 10) {
#     nodes {
#       id
#       title
#       slug
#       date
#       excerpt
#       content
#       featuredImage {
#         node {
#           sourceUrl
#           altText
#         }
#       }
#       author {
#         node {
#           name
#           avatar {
#             url
#           }
#         }
#       }
#       tags {
#         nodes {
#           name
#           slug
#         }
#       }
#     }
#   }
# }

## Next.js 14 — projekt i pobieranie danych

\# Utwórz projekt Next.js
npx create-next-app@latest my-headless-wp \\
  --typescript --tailwind --eslint --app
cd my-headless-wp

# Zainstaluj klienta GraphQL
npm install graphql-request graphql

# .env.local
# WORDPRESS\_API\_URL=https://twojadomena.pl/graphql
# WORDPRESS\_PREVIEW\_SECRET=twoj-tajny-token-preview

# lib/graphql.ts — klient zapytan
# import { GraphQLClient } from 'graphql-request';
#
# export const client = new GraphQLClient(
#   process.env.WORDPRESS\_API\_URL!
# );
#
# export async function getAllPosts() {
#   const query = \`
#     query AllPosts {
#       posts(first: 20, where: { status: PUBLISH }) {
#         nodes {
#           id
#           slug
#           title
#           date
#           excerpt(format: RENDERED)
#           featuredImage {
#             node { sourceUrl altText }
#           }
#         }
#       }
#     }
#   \`;
#   const data = await client.request(query);
#   return data.posts.nodes;
# }
#
# export async function getPostBySlug(slug: string) {
#   const query = \`
#     query PostBySlug($slug: String!) {
#       postBy(slug: $slug) {
#         id title content date
#         author { node { name } }
#         tags { nodes { name slug } }
#       }
#     }
#   \`;
#   const data = await client.request(query, { slug });
#   return data.postBy;
# }

## App Router — strony z ISR

Next.js App Router pozwala na Incremental Static Regeneration przez pole `revalidate`. Strony są wstępnie generowane przy buildzie i odświeżane w tle co określony czas:

\# app/page.tsx — strona glowna z lista postow (ISR co 60s)
# import { getAllPosts } from '@/lib/graphql';
#
# export const revalidate = 60;  // ISR: odswiezaj co 60 sekund
#
# export default async function HomePage() {
#   const posts = await getAllPosts();
#
#   return (
#     <main>
#       <h1>Blog</h1>
#       <ul>
#         {posts.map((post) => (
#           <li key={post.id}>
#             <a href={\`/posts/${post.slug}\`}>{post.title}</a>
#           </li>
#         ))}
#       </ul>
#     </main>
#   );
# }

# app/posts/\[slug\]/page.tsx — dynamiczna strona posta z ISR
# import { getPostBySlug, getAllPosts } from '@/lib/graphql';
# import { notFound } from 'next/navigation';
#
# export const revalidate = 3600;  // ISR: co godzine
#
# // Generuj sciezki statycznie przy buildzie
# export async function generateStaticParams() {
#   const posts = await getAllPosts();
#   return posts.map((post) => ({ slug: post.slug }));
# }
#
# export default async function PostPage({ params }) {
#   const post = await getPostBySlug(params.slug);
#   if (!post) notFound();
#
#   // Renderowanie treści z WordPress — pamiętaj o sanitizacji
#   // (wp\_kses\_post() po stronie WP czyści HTML przed zapisem do bazy)
#   return (
#     <article>
#       <h1>{post.title}</h1>
#       <time>{new Date(post.date).toLocaleDateString('pl-PL')}</time>
#       <div class="post-content" />  {/\* wstaw tresc przez set innerHTML po sanitizacji \*/}
#     </article>
#   );
# }

## Webhook — natychmiastowe ISR revalidation

ISR odświeża strony co określony czas. Jeśli chcesz żeby strona odświeżyła się natychmiast po publikacji posta w WordPress, użyj mechanizmu On-Demand Revalidation:

\# app/api/revalidate/route.ts — endpoint do rewalidacji
# import { revalidatePath } from 'next/cache';
# import { NextRequest } from 'next/server';
#
# export async function POST(req: NextRequest) {
#   const secret = req.nextUrl.searchParams.get('secret');
#   if (secret !== process.env.WORDPRESS\_PREVIEW\_SECRET) {
#     return Response.json({ message: 'Invalid secret' }, { status: 401 });
#   }
#
#   const body = await req.json();
#   const slug = body?.post?.post\_name;
#
#   if (slug) {
#     revalidatePath(\`/posts/${slug}\`);
#   }
#   revalidatePath('/');  // strona glowna
#
#   return Response.json({ revalidated: true, slug });
# }

# WordPress — dodaj w functions.php do motywu lub pluginie
# function send\_nextjs\_revalidation\_webhook($post\_id) {
#   $post = get\_post($post\_id);
#   $payload = json\_encode(array('post' => array('post\_name' => $post->post\_name)));
#   wp\_remote\_post(
#     'https://twoj-nextjs.pl/api/revalidate?secret=TWOJ\_SECRET',
#     array(
#       'body'    => $payload,
#       'headers' => array('Content-Type' => 'application/json')
#     )
#   );
# }
# add\_action('publish\_post', 'send\_nextjs\_revalidation\_webhook');

## Deployment na VPS — Next.js z PM2

\# Na VPS — instalacja Node.js LTS
curl -fsSL https://deb.nodesource.com/setup\_20.x | sudo bash -
sudo apt install nodejs -y
npm install -g pm2

# Build i uruchomienie
cd /var/www/my-headless-wp
npm install
npm run build

# PM2 ekosystem (ecosystem.config.js)
# module.exports = {
#   apps: \[{
#     name: 'nextjs-blog',
#     script: 'node\_modules/.bin/next',
#     args: 'start',
#     env: {
#       NODE\_ENV: 'production',
#       PORT: 3000,
#       WORDPRESS\_API\_URL: 'https://wp.example.com/graphql'
#     }
#   }\]
# };

pm2 start ecosystem.config.js
pm2 save
pm2 startup   # autostart po restarcie serwera

# Nginx reverse proxy do Next.js
# server {
#     listen 443 ssl;
#     server\_name blog.example.com;
#     location / {
#         proxy\_pass http://localhost:3000;
#         proxy\_http\_version 1.1;
#         proxy\_set\_header Upgrade $http\_upgrade;
#         proxy\_set\_header Connection 'upgrade';
#         proxy\_set\_header Host $host;
#         proxy\_cache\_bypass $http\_upgrade;
#     }
# }

# Deploy bez downtime
git pull
npm ci
npm run build
pm2 reload nextjs-blog   # zero-downtime reload

## Najczęstsze pytania

Czym jest headless WordPress i kiedy warto go stosować? +

Headless WordPress oznacza użycie WordPressa wyłącznie jako CMS (zarządzanie treścią, panel admina, baza danych), podczas gdy frontend (to co widzi użytkownik) jest osobną aplikacją (Next.js, Astro, Gatsby, Nuxt). WordPress udostępnia treść przez API (REST lub GraphQL). Warto stosować gdy chcesz szybkości nowoczesnego frontendu (React, SSR, ISR) z wygodą redakcyjną WordPress, gdy masz zespół frontendowy preferujący React, lub gdy potrzebujesz serwować treść na wielu platformach (web, mobile app, newsletter).

Dlaczego WPGraphQL zamiast WordPress REST API? +

REST API WordPress pobiera z góry określony zestaw pól niezależnie od potrzeb — często za dużo danych (over-fetching) lub za mało (under-fetching, wymaga wielu requestów). GraphQL pozwala zapytać dokładnie o te pola, których potrzebujesz. Jeden request GraphQL może zastąpić 5-10 requestów REST. WPGraphQL jest oficjalnie wspieranym pluginem, ma bogatą dokumentację i jest powszechnie stosowany w ekosystemie headless WordPress (Gatsby, Next.js).

Czym jest ISR (Incremental Static Regeneration) w Next.js? +

ISR to funkcja Next.js łącząca zalety generowania statycznego (szybkość, bez serwera dla każdego żądania) z możliwością aktualizacji treści. Definiujesz revalidate: 60 — strona jest generowana statycznie, ale raz na 60 sekund Next.js regeneruje ją w tle jeśli były żądania. Stara wersja jest serwowana do chwili gotowości nowej. Idealne dla bloga WordPress: artykuły są statyczne i szybkie, ale nowe treści pojawiają się bez pełnego rebuild.

Gdzie hostować headless WordPress — WP osobno od Next.js? +

Tak, WP i Next.js to dwie oddzielne aplikacje. WordPress (PHP+MySQL) najlepiej na klasycznym hostingu WordPress lub VPS z PHP — nie potrzebuje dużo zasobów, bo obsługuje tylko requesty API (brak publicznego frontendu). Next.js (Node.js) wymaga VPS lub platformy obsługującej Node (Vercel, Netlify, self-hosted). Tanie rozwiązanie: WordPress na shared hostingu (LH.pl, CyberFolks) + Next.js na VPS lub Vercel free tier.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

VPS pod Next.js frontend — Node.js z PM2, nginx reverse proxy

Next.js VPS

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

Mikr.us

Tani VPS do testowania headless WP setup przed produkcją

Dev/Test

[Aktywuj rabat →](/out/mikrus)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/mikrus)

LH.pl

Hosting PHP dla WordPress backend (API-only, bez frontendu) — tanie i szybkie

WP Backend

[Aktywuj rabat →](/out/lh-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/lh-pl)

## Powiązane strony

-   [WordPress Multisite — konfiguracja i subdomeny](/baza-wiedzy/wordpress-multisite-konfiguracja)
-   [WooCommerce — optymalizacja na hostingu](/baza-wiedzy/woocommerce-optymalizacja-hosting)
-   [Node.js na hostingu współdzielonym](/baza-wiedzy/nodejs-na-hostingu-wspoldzielonym)
-   [Nginx load balancer — konfiguracja upstream](/baza-wiedzy/nginx-load-balancer-konfiguracja)
-   [Wszystkie artykuły](/baza-wiedzy/)