Úvod: Co je Headless WordPress a proč o něm v roce 2026 mluvíme

Tradiční WordPress funguje jako monolitická aplikace – backend a frontend jsou pevně spojené. Když návštěvník požádá o stránku, WordPress:

  1. Přijme request
  2. Spustí PHP kód
  3. Dotáže se databáze
  4. Vygeneruje HTML
  5. Pošle kompletní stránku prohlížeči

Tento proces fungoval skvěle posledních 20 let. Ale v roce 2026 máme vyšší nároky: bleskové načítání, interaktivní UI, multi-platform dostupnost (web, mobilní app, chytré hodinky).

Headless WordPress odděluje backend (správu obsahu) od frontendu (zobrazení). WordPress slouží pouze jako API poskytující data, zatímco frontend je postavený v moderním frameworku jako React, Vue nebo Next.js.

Tento článek vysvětlí, kdy headless přístup dává smysl pro české klienty, jak to implementovat ve WordPressu a co to znamená pro vaši agenturu.

1. Tradiční vs. Headless WordPress: Klíčové rozdíly

Architektura: Jak to funguje

Tradiční WordPress:

Uživatel → WordPress (PHP) → Databáze → WordPress → HTML → Uživatel
           [Backend + Frontend spojené]

Headless WordPress:

Uživatel → Next.js App → API Request → WordPress (REST/GraphQL) → Data
          [Modern Frontend]              [Pouze Backend]

Výhody headless přístupu

1. Výkon a rychlost

Tradiční WordPress:

  • Každý request = PHP execution + DB queries
  • Generování HTML na serveru
  • Závislost na hosting výkonu
  • Typicky 1.5-3s load time

Headless WordPress:

  • Staticky generované stránky (SSG)
  • Nebo server-side rendering (SSR)
  • CDN distribuce globálně
  • Typicky 0.3-0.8s load time

Reálný příklad: E-shop s 10.000 produktů:

  • Tradiční WooCommerce: 2.8s průměrný load time
  • Headless (Next.js + WooCommerce REST API): 0.6s
  • Zlepšení: 78%

2. Bezpečnost

Tradiční:

  • WordPress admin přístupný na /wp-admin
  • PHP zranitelnosti
  • Plugin security issues
  • Častý cíl hackerů

Headless:

  • WordPress backend není veřejně přístupný
  • Frontend je statický (nelze hacknout HTML)
  • Menší attack surface
  • Citlivá data nejsou v DOM

3. Škálovatelnost

Tradiční:

  • Limitováno výkonem PHP serveru
  • Potřeba silnějšího hostingu při růstu trafficu
  • Náklady rostou lineárně

Headless:

  • Statické stránky = infinite scale na CDN
  • API caching redukuje zátěž
  • Náklady rostou minimálně

4. Multi-platform

Tradiční:

  • Primárně pro web
  • Mobilní app = kompletně separátní vývoj

Headless:

  • Jedna API pro web, iOS, Android, IoT
  • Obsah jednou, distribuce všude
  • Konzistentní data napříč platformami

5. Developer Experience

Tradiční:

  • PHP + WordPress šablony
  • Omezené možnosti moderních JS frameworků
  • Složitější testing

Headless:

  • Moderní JS/TS stack
  • React/Vue komponenty
  • Hot reload, type safety
  • Lepší dev tools

Nevýhody headless (buďme čestní)

1. Vyšší komplexita

Musíte spravovat:

  • WordPress backend
  • Frontend aplikaci
  • API komunikaci
  • Deployment pipeline

2. Vyšší náklady na vývoj

Headless projekt zabere typicky 2-3× více času než tradiční WordPress:

  • Tradiční: 40-60 hodin
  • Headless: 100-150 hodin

3. Ztrácíte některé WordPress funkce

Co nefunguje “out of the box”:

  • Preview funkcionalita
  • Some plugins (page builders apod.)
  • Real-time editing
  • Comments system

(Lze ale re-implementovat)

4. Náročnější údržba

Potřebujete skills v:

  • WordPress + PHP
  • React/Next.js + JavaScript
  • API design
  • Deployment a DevOps

5. Není vhodné pro všechny projekty

Headless overkill pro:

  • Jednoduché prezentační weby
  • Blogy bez speciálních požadavků
  • Klienti potřebující drag-and-drop page builders

2. Kdy má headless smysl: Decision framework

Použijte headless když…

Vysoký traffic (50.000+ návštěv měsíčně)

  • ROI z rychlosti a škálovatelnosti
  • Úspora na hostingu

E-commerce s velkým katalogem

  • Tisíce produktů
  • Potřeba blazing fast UX
  • Konkurenční výhoda ve speed

Multi-platform ambice

  • Mobilní app v plánu
  • Integrace s IoT
  • Syndikace obsahu

International expansion

  • Multilanguage weby
  • Edge caching pro globální rychlost
  • Různé domény, jeden content source

Komplexní custom UI/UX

  • Interaktivní features
  • Real-time data
  • Single-page application feeling

Integrační requirements

  • Propojení s externími systémy
  • Microservices architektura
  • Headless CMS jako součást většího ekosystému

Zůstaňte u tradičního WordPressu když…

Malý web s nízkým trafficem

  • Pod 10.000 návštěv měsíčně
  • Headless = overkill

Limitovaný rozpočet

  • Tight budget na vývoj
  • Potřeba rychlého spuštění

Klient potřebuje jednoduchou editaci

  • Non-tech klient
  • Chce vizuální page builder
  • Žádná IT podpora

Standardní blog nebo portfolio

  • Běžné use cases
  • Žádné speciální performance nebo UX požadavky

Žádný developer na údržbu

  • Klient spoléhá na vaši podporu
  • Chybí resources pro komplexnější řešení

Decision matrix

Faktor Body Hodnocení
Monthly traffic > 50k +3
E-commerce +2
Multi-platform plány +3
Custom UX requirements +2
International +2
Budget > 500k Kč +2
Dev team available +2
Simple content needs -2
Tight deadline -2
Non-tech client -2

Skóre:

  • 8+: Silně doporučeno headless
  • 4-7: Zvažte headless
  • 0-3: Tradiční WordPress lepší volba
  • Negativní: Určitě tradiční

3. Tech Stack: WordPress + Next.js v roce 2026

Proč Next.js?

V roce 2026 je Next.js de-facto standard pro headless WordPress frontends. Proč?

1. Nejlepší z obou světů

  • Static Site Generation (SSG)
  • Server-Side Rendering (SSR)
  • Client-Side Rendering (CSR)
  • Incremental Static Regeneration (ISR)

2. Výborný developer experience

  • File-based routing
  • Built-in optimalizace (images, fonts)
  • TypeScript support
  • Fast Refresh

3. Produkční ready

  • Používá ho Netflix, Uber, Nike
  • Stabilní a battle-tested
  • Excellent dokumentace

4. Vercel deployment

  • One-click deploy
  • Global CDN
  • Automatic scaling
  • Generous free tier

Základní setup: WordPress + Next.js

Krok 1: WordPress jako Headless CMS (30 min)

  1. Čerstvá WordPress instalace
    • Minimální téma (Twenty Twenty-Five)
    • Žádné page buildery
  2. Povolte REST API WordPress má REST API vestavěné, ale optimalizujeme:
php
// functions.php
// Přidejte custom fields do API
function add_custom_fields_to_api() {
    register_rest_field('post', 'custom_field', array(
        'get_callback' => function($post) {
            return get_post_meta($post['id'], 'custom_field', true);
        }
    ));
}
add_action('rest_api_init', 'add_custom_fields_to_api');
  1. Zabezpečte WordPress admin
   # .htaccess - limit wp-admin access
   <Files wp-login.php>
       Order Deny,Allow
       Deny from all
       Allow from YOUR_IP
   </Files>
  1. Nainstalujte klíčové pluginy
    • WPGraphQL (GraphQL API, lepší než REST)
    • WPGraphQL for ACF (pokud používáte Advanced Custom Fields)
    • Headless Mode (disabluje frontend WordPress)
    • JWT Authentication (API auth)

Krok 2: Next.js aplikace (60 min)

  1. Vytvoření projektu
bash
npx create-next-app@latest my-headless-site
cd my-headless-site
  1. Instalace závislostí
bash
npm install axios graphql-request
npm install -D @types/node typescript
  1. Environment variables
env
# .env.local
WORDPRESS_API_URL=https://your-wp-site.com/graphql
NEXT_PUBLIC_SITE_URL=https://your-frontend.com
  1. GraphQL klient setup
typescript
// lib/graphql.ts
import { GraphQLClient } from 'graphql-request';

const endpoint = process.env.WORDPRESS_API_URL;

export const graphQLClient = new GraphQLClient(endpoint, {
  headers: {
    // Auth header pokud potřeba
  },
});
  1. Fetch posts z WordPress
typescript
// lib/api.ts
import { graphQLClient } from './graphql';

const GET_ALL_POSTS = `
  query GetAllPosts {
    posts {
      nodes {
        id
        title
        slug
        excerpt
        date
        featuredImage {
          node {
            sourceUrl
          }
        }
      }
    }
  }
`;

export async function getAllPosts() {
  const data = await graphQLClient.request(GET_ALL_POSTS);
  return data.posts.nodes;
}
  1. Homepage s posty
typescript
// app/page.tsx
import { getAllPosts } from '@/lib/api';
import Link from 'next/link';
import Image from 'next/image';

export default async function Home() {
  const posts = await getAllPosts();

  return (
    <div className="container mx-auto px-4 py-8">
      <h1 className="text-4xl font-bold mb-8">Blog</h1>
      
      <div className="grid md:grid-cols-3 gap-6">
        {posts.map((post) => (
          <article key={post.id} className="border rounded-lg overflow-hidden">
            {post.featuredImage && (
              <Image
                src={post.featuredImage.node.sourceUrl}
                alt={post.title}
                width={400}
                height={250}
                className="w-full"
              />
            )}
            
            <div className="p-4">
              <h2 className="text-2xl font-semibold mb-2">
                <Link href={`/posts/${post.slug}`}>
                  {post.title}
                </Link>
              </h2>
              
              <div dangerouslySetInnerHTML={{ __html: post.excerpt }} />
              
              <Link 
                href={`/posts/${post.slug}`}
                className="text-blue-600 hover:underline mt-2 inline-block"
              >
                Číst více →
              </Link>
            </div>
          </article>
        ))}
      </div>
    </div>
  );
}
  1. Dynamic route pro jednotlivé posty
typescript
// app/posts/[slug]/page.tsx
import { getPostBySlug, getAllPosts } from '@/lib/api';
import Image from 'next/image';

export async function generateStaticParams() {
  const posts = await getAllPosts();
  return posts.map((post) => ({
    slug: post.slug,
  }));
}

export default async function Post({ params }) {
  const post = await getPostBySlug(params.slug);

  return (
    <article className="container mx-auto px-4 py-8 max-w-4xl">
      <h1 className="text-5xl font-bold mb-4">{post.title}</h1>
      
      <div className="text-gray-600 mb-6">
        {new Date(post.date).toLocaleDateString('cs-CZ')}
      </div>
      
      {post.featuredImage && (
        <Image
          src={post.featuredImage.node.sourceUrl}
          alt={post.title}
          width={1200}
          height={630}
          className="w-full rounded-lg mb-8"
        />
      )}
      
      <div 
        className="prose prose-lg max-w-none"
        dangerouslySetInnerHTML={{ __html: post.content }}
      />
    </article>
  );
}

Hotovo! Máte funkční headless WordPress + Next.js setup.

ISR: Incremental Static Regeneration

Největší výhoda Next.js – kombinace statického buildu s dynamic updates:

typescript
// app/posts/[slug]/page.tsx

export const revalidate = 60; // Revalidate každých 60 sekund

export default async function Post({ params }) {
  // ...
}

Jak to funguje:

  1. Build-time: Všechny stránky se vygenerují staticky
  2. Runtime: Po 60 sekundách se stránka revaliduje na požádání
  3. Uživatelé dostanou rychlý static page
  4. Content je max. 60 sekund starý

Benefit:

  • Rychlost statického
  • Aktualita dynamického
  • Bez nutnosti full rebuild

WooCommerce headless

Pro e-shopy je headless ještě komplexnější, ale přínosy jsou větší.

Stack:

  • WordPress + WooCommerce (backend)
  • Next.js (frontend)
  • WPGraphQL + WooGraphQL (API)
  • Stripe/Braintree (payment)

Klíčové komponenty:

  1. Product listing
typescript
const GET_PRODUCTS = `
  query GetProducts {
    products(first: 20) {
      nodes {
        id
        name
        slug
        price
        image {
          sourceUrl
        }
      }
    }
  }
`;
  1. Shopping cart
  • Používejte Context API nebo Zustand pro state management
  • Cart data v localStorage (pro persistence)
  1. Checkout
  • Custom checkout form
  • API call k WooCommerce pro order creation
  • Stripe integration pro payment

Výhody headless WooCommerce:

  • Dramaticky rychlejší než běžný WooCommerce
  • Custom checkout UX (conversion rate boost)
  • Lepší mobile experience

Case study: Český fashion e-shop (15k SKU):

  • Tradiční WooCommerce: 3.2s load, 2.1% conversion
  • Headless: 0.7s load, 3.4% conversion
  • +62% conversion rate!

4. Deployment a hosting

Doporučená architektura

WordPress backend:

  • Hosting: Cloudways, WP Engine, nebo Kinsta
  • Důvod: Managed WordPress hosting s vysokým výkonem
  • Cena: 600-2.500 Kč/měsíc

Next.js frontend:

  • Hosting: Vercel (best choice)
  • Alternativy: Netlify, AWS Amplify
  • Cena: 0-2.000 Kč/měsíc (free tier dostačující pro většinu)

CDN:

  • Cloudflare (zdarma až 4.500 Kč/měsíc pro Enterprise)
  • Distribuuje static assets globálně

Deployment workflow

yaml
# .github/workflows/deploy.yml
name: Deploy to Vercel

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v2
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
      
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v20
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}

Proces:

  1. Push do Git → GitHub Actions trigger
  2. Build Next.js aplikace
  3. Deploy na Vercel
  4. Automatic cache invalidation
  5. Live za ~2 minuty

Preview functionality

Jedna z “nevýhod” headless je ztráta WordPress preview. Ale lze to vyřešit:

Draft posts API:

typescript
// lib/api.ts
export async function getPostPreview(id: string, authToken: string) {
  const query = `
    query GetPostPreview($id: ID!) {
      post(id: $id, idType: DATABASE_ID) {
        title
        content
        status
      }
    }
  `;
  
  const client = new GraphQLClient(endpoint, {
    headers: {
      Authorization: `Bearer ${authToken}`,
    },
  });
  
  return client.request(query, { id });
}

Preview route:

typescript
// app/api/preview/route.ts
export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const id = searchParams.get('id');
  const token = searchParams.get('token');
  
  // Validate token...
  
  const post = await getPostPreview(id, token);
  
  return Response.redirect(`/posts/${post.slug}?preview=true`);
}

WordPress plugin pro preview button:

php
// Preview button v WordPress adminu
function add_headless_preview_button() {
    global $post;
    $preview_url = 'https://your-frontend.com/api/preview?id=' . $post->ID;
    echo '<a href="' . $preview_url . '" target="_blank">Preview on Frontend</a>';
}
add_action('post_submitbox_misc_actions', 'add_headless_preview_button');

5. Performance optimalizace

Obrázky: Next.js Image komponenta

typescript
import Image from 'next/image';

<Image
  src={post.featuredImage.node.sourceUrl}
  alt={post.title}
  width={1200}
  height={630}
  priority // Pro above-the-fold images
  placeholder="blur" // Blur placeholder při načítání
  blurDataURL={post.featuredImage.node.blurDataUrl}
/>

Next.js automaticky:

  • Resizuje pro různá zařízení
  • Konvertuje do WebP/AVIF
  • Lazy loading (kromě priority images)
  • Cachuje optimalizované verze

Caching strategie

1. Next.js cache (ISR)

typescript
export const revalidate = 3600; // 1 hodina

2. Cloudflare cache

typescript
// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 's-maxage=3600, stale-while-revalidate',
          },
        ],
      },
    ];
  },
};

3. WordPress API caching Plugin WP REST Cache cachuje API responses.

Bundle size optimalizace

bash
npm run analyze

Techniky:

  • Code splitting (automatic v Next.js)
  • Dynamic imports pro velké komponenty
  • Tree shaking
  • Optimalizace závislostí

Před:

  • Bundle size: 450 kB
  • First Load JS: 180 kB

Po optimalizaci:

  • Bundle size: 180 kB
  • First Load JS: 85 kB

6. Bezpečnost headless setupu

WordPress backend security

1. Skryjte WordPress admin

apache
# .htaccess
RewriteRule ^wp-admin$ https://different-domain.com/secret-admin [R,L]

2. IP whitelisting Povolit přístup k /wp-admin jen z:

  • Vaší IP
  • VPN IP
  • Office IP

3. API authentication

php
// JWT authentication
add_filter('rest_authentication_errors', function($result) {
    if (!empty($result)) return $result;
    
    if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
        return new WP_Error('rest_forbidden', 'Authentication required', array('status' => 401));
    }
    
    // Validate JWT token...
    
    return $result;
});

Frontend security

1. Environment variables Nikdy nehardcodujte API keys:

typescript
// ✅ Správně
const apiKey = process.env.NEXT_PUBLIC_API_KEY;

// ❌ Špatně
const apiKey = 'abc123xyz';

2. Rate limiting

typescript
// middleware.ts
import { Ratelimit } from '@upstash/ratelimit';

const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(10, '10 s'),
});

export async function middleware(request: Request) {
  const ip = request.ip ?? '127.0.0.1';
  const { success } = await ratelimit.limit(ip);
  
  if (!success) {
    return new Response('Too many requests', { status: 429 });
  }
}

3. CSP headers

typescript
// next.config.js
const securityHeaders = [
  {
    key: 'Content-Security-Policy',
    value: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline';"
  }
];

7. ROI a business case pro české klienty

Nákladová analýza

Tradiční WordPress projekt (40-60 hodin):

  • Design: 20 hodin × 1.200 Kč = 24.000 Kč
  • Vývoj: 40 hodin × 1.000 Kč = 40.000 Kč
  • Celkem: 64.000 Kč

Headless projekt (100-150 hodin):

  • Design: 20 hodin × 1.200 Kč = 24.000 Kč
  • Backend setup: 30 hodin × 1.000 Kč = 30.000 Kč
  • Frontend vývoj: 80 hodin × 1.200 Kč = 96.000 Kč
  • Celkem: 150.000 Kč

Rozdíl: +86.000 Kč (+134%)

Provozní náklady (měsíčně)

Tradiční:

  • Hosting (Cloudways): 1.200 Kč
  • CDN: 0 Kč (included)
  • Celkem: 1.200 Kč/měsíc

Headless:

  • WordPress hosting: 1.200 Kč
  • Vercel (frontend): 0-800 Kč
  • Cloudflare Pro: 500 Kč
  • Celkem: 1.700-2.500 Kč/měsíc

Rozdíl: +500-1.300 Kč měsíčně

Kdy se headless vyplatí?

Scénář: E-commerce s 100.000 návštěv měsíčně

Improvement metrics:

  • Load time: 2.8s → 0.6s (-79%)
  • Conversion rate: 2.0% → 3.2% (+60%)

Revenue impact:

  • 100k návštěv × 3.2% conversion = 3.200 objednávek
  • Původně: 100k × 2.0% = 2.000 objednávek
  • +1.200 objednávek měsíčně

Při průměrné objednávce 800 Kč:

  • +1.200 × 800 Kč = +960.000 Kč revenue/měsíc

ROI:

  • Extra investice: 86.000 Kč
  • Návratnost: Za 3 dny (!)
  • Roční benefit: 11.5 mil. Kč

I při konzervativnějších číslech (menší traffic, nižší improvement) se headless vyplatí pro e-commerce a high-traffic weby.

Závěr: Je headless pro vás?

Headless WordPress není trendy buzzword – je to legitimní architekturální volba s reálnými benefity. Ale není pro každého.

Headless je skvělá volba když:

  • Klient má ambice (růst, expansion)
  • Performance je kritická (e-commerce, news sites)
  • Budget umožňuje investici do quality
  • Máte dev team schopný to udržovat

Tradiční WordPress zůstává lepší pro:

  • Malé projekty s omezeným budgetem
  • Klienti bez tech zázemí
  • Rychlé time-to-market
  • Projekty kde není performance kritická

Akční plán:

  1. Vyhodnoťte své projekty pomocí decision matrix
  2. Vyzkoušejte headless na interním projektu
  3. Nabídněte headless jako premium option pro vhodné klienty
  4. Vzdělávejte tým v Next.js/React

Budoucnost web developmentu je headless. Otázka není “jestli”, ale “kdy” začnete.