HOSTING CEPATDOMAIN MURAHSSL GRATISSUPPORT 24/7UPTIME 99.9%SERVER INDONESIAHOSTING CEPATDOMAIN MURAHSSL GRATISSUPPORT 24/7UPTIME 99.9%SERVER INDONESIA
Tutorial

Cara Membuat Headless WordPress 2026: Decoupled Architecture dengan REST API & WPGraphQL

Tim HostingEkspres|1 Juni 2026|14 menit baca
cara membuat headless wordpressheadless wordpresswordpress rest apiwordpress decoupledwpgraphqlheadless wordpress nextjsdecoupled wordpress indonesiawordpress sebagai headless cms
Cara Membuat Headless WordPress 2026: Decoupled Architecture dengan REST API & WPGraphQL

Apa Itu Headless WordPress dan Mengapa Semakin Diminati?

Cara membuat headless WordPress adalah salah satu topik paling hangat dalam komunitas web development Indonesia saat ini. Headless WordPress adalah pendekatan di mana WordPress digunakan hanya sebagai backend untuk mengelola konten - tim editorial tetap menggunakan antarmuka WordPress yang sudah familiar - sementara tampilan frontend dibangun menggunakan teknologi modern seperti Next.js, Nuxt.js, atau Gatsby, yang berkomunikasi dengan WordPress melalui REST API atau GraphQL.

Disclosure: Beberapa link di artikel ini mengarah ke layanan HostingEkspres atau partner kami. Jika Anda melakukan pembelian melalui link tersebut, kami mungkin menerima komisi tanpa biaya tambahan untuk Anda. Konten dan rekomendasi di artikel ini independen dan didasarkan pada pengujian serta pengalaman tim kami.

Ini berbeda dari WordPress monolitik tradisional di mana tema PHP menangani sekaligus pengolahan data dan rendering tampilan. Dengan arsitektur decoupled (terpisah), Anda mendapatkan yang terbaik dari dua dunia: kenyamanan WordPress sebagai CMS yang sudah dikenal, plus performa dan fleksibilitas frontend modern.

Beberapa alasan utama mengapa developer Indonesia beralih ke headless WordPress:

  • Performa jauh lebih baik: Frontend Next.js yang di-render secara static atau hybrid jauh lebih cepat dibanding theme WordPress yang di-render server-side dengan PHP setiap request.
  • Tim konten tetap di zona nyaman: Editor dan penulis konten tidak perlu belajar CMS baru - mereka tetap menggunakan WordPress yang sudah dikuasai.
  • Keamanan lebih tinggi: Frontend tidak berjalan di atas WordPress/PHP, sehingga attack surface berkurang drastis. Direktori /wp-admin tidak perlu terekspos ke publik.
  • Fleksibilitas arsitektur: Konten WordPress bisa dikonsumsi oleh aplikasi mobile, website, atau platform digital lainnya secara bersamaan.
  • Developer experience lebih modern: Tim frontend bisa menggunakan TypeScript, React, Tailwind CSS, dan tools modern lainnya tanpa batasan ekosistem PHP WordPress.

Dua Cara Mengakses Konten WordPress Secara Headless

WordPress menyediakan dua cara utama untuk mengakses konten sebagai headless CMS:

cara membuat headless wordpress
Ilustrasi cara membuat headless wordpress

1. WordPress REST API (Built-in)

WordPress REST API adalah fitur bawaan yang hadir sejak WordPress 4.7. Tidak perlu install plugin tambahan - API sudah tersedia secara default di setiap instalasi WordPress modern. Endpoint utama yang sering digunakan:

  • GET /wp-json/wp/v2/posts - daftar semua post
  • GET /wp-json/wp/v2/posts/{id} - detail satu post
  • GET /wp-json/wp/v2/pages - daftar semua halaman
  • GET /wp-json/wp/v2/categories - daftar kategori
  • GET /wp-json/wp/v2/tags - daftar tag
  • GET /wp-json/wp/v2/media - daftar media

REST API sangat mudah digunakan dan tidak memerlukan konfigurasi tambahan. Kekurangannya adalah bisa terjadi over-fetching (data yang dikembalikan lebih banyak dari yang dibutuhkan) dan butuh beberapa request terpisah untuk data yang berelasi.

2. WPGraphQL (Plugin)

WPGraphQL adalah plugin populer yang menambahkan endpoint GraphQL ke WordPress. Berbeda dari REST API, GraphQL memungkinkan Anda menentukan dengan tepat data apa yang ingin diambil dalam satu query, menghilangkan masalah over-fetching dan under-fetching.

Untuk tutorial ini, kita akan menggunakan keduanya - dimulai dengan REST API yang lebih sederhana, lalu eksplorasi WPGraphQL untuk kebutuhan yang lebih kompleks.

Langkah 1: Persiapan WordPress sebagai Backend Headless

Pertama, pastikan instalasi WordPress Anda sudah siap berfungsi sebagai headless backend.

Instalasi WordPress

Jika belum punya instalasi WordPress, setup terlebih dahulu di hosting Anda. Gunakan Softaculous di cPanel untuk instalasi cepat. Setelah WordPress aktif, akses dashboard admin di namadomain.com/wp-admin.

Pastikan Permalink diatur ke format Post name: buka Settings > Permalinks, pilih Post name, klik Save Changes. Ini penting agar WordPress REST API bisa berfungsi dengan benar.

Konfigurasi CORS

Karena frontend dan backend akan berjalan di domain berbeda, Anda perlu mengonfigurasi CORS (Cross-Origin Resource Sharing) agar frontend bisa mengakses API WordPress. Tambahkan kode berikut ke file functions.php tema aktif Anda, atau lebih baik buat plugin kecil untuk ini:

// Tambahkan ke functions.php atau plugin kustom
function add_cors_headers() {
    $allowed_origins = array(
        'https://namadomain-frontend.com',
        'http://localhost:3000', // untuk development
    );

    $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';

    if (in_array($origin, $allowed_origins)) {
        header("Access-Control-Allow-Origin: " . $origin);
    }

    header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
    header("Access-Control-Allow-Headers: Authorization, Content-Type");

    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
        exit(0);
    }
}
add_action('init', 'add_cors_headers');
Baca Juga: Headless CMS Indonesia Terbaik 2026: Panduan Memilih dan Menggunakan

Langkah 2: Install dan Konfigurasi WPGraphQL

Untuk kemampuan GraphQL di WordPress, install plugin WPGraphQL:

  1. Di dashboard WordPress, buka Plugins > Add New.
  2. Cari WPGraphQL (oleh Jason Bahl).
  3. Klik Install Now lalu Activate.

Setelah aktif, endpoint GraphQL tersedia di namadomain.com/graphql. Buka GraphQL > Settings di menu admin untuk mengonfigurasi. Aktifkan opsi Enable Public Introspection selama development agar bisa mengeksplorasi schema via GraphiQL IDE.

Akses namadomain.com/graphql di browser untuk membuka GraphiQL IDE - antarmuka interaktif untuk menulis dan mengetes query GraphQL secara real-time.

Langkah 3: Eksplorasi WordPress REST API

Sebelum membangun frontend, pahami terlebih dahulu data yang tersedia via API. Buka browser atau Postman/Insomnia, lalu akses endpoint berikut (ganti dengan domain WordPress Anda):

# Daftar 10 post terbaru
GET https://namadomain.com/wp-json/wp/v2/posts?per_page=10

# Post dengan featured image dan author (embedded)
GET https://namadomain.com/wp-json/wp/v2/posts?_embed

# Post berdasarkan slug
GET https://namadomain.com/wp-json/wp/v2/posts?slug=judul-artikel

# Daftar kategori
GET https://namadomain.com/wp-json/wp/v2/categories

# Post berdasarkan kategori ID
GET https://namadomain.com/wp-json/wp/v2/posts?categories=5

Perhatikan struktur JSON yang dikembalikan. Setiap post memiliki field seperti id, title.rendered, content.rendered, excerpt.rendered, slug, date, _embedded (berisi featured image dan author jika menggunakan parameter _embed).

cara membuat headless wordpress
Ilustrasi cara membuat headless wordpress

Langkah 4: Membangun Frontend Next.js

Saatnya membangun frontend yang mengonsumsi WordPress REST API. Kita akan menggunakan Next.js 14+ dengan App Router.

Membuat Proyek Next.js

npx create-next-app@latest my-headless-wp --typescript --tailwind --app
cd my-headless-wp

Buat file .env.local di root proyek:

WORDPRESS_API_URL=https://namadomain.com/wp-json/wp/v2
NEXT_PUBLIC_SITE_URL=https://namadomain-frontend.com

Membuat Utilitas API WordPress

Buat file lib/wordpress.ts:

const WP_API_URL = process.env.WORDPRESS_API_URL;

export interface WPPost {
  id: number;
  slug: string;
  title: { rendered: string };
  content: { rendered: string };
  excerpt: { rendered: string };
  date: string;
  _embedded?: {
    'wp:featuredmedia'?: Array<{ source_url: string; alt_text: string }>;
    author?: Array<{ name: string; avatar_urls: Record }>;
  };
}

export async function getPosts(page = 1, perPage = 10): Promise {
  const res = await fetch(
    `${WP_API_URL}/posts?_embed&page=${page}&per_page=${perPage}`,
    { next: { revalidate: 300 } }
  );
  if (!res.ok) throw new Error('Gagal mengambil posts');
  return res.json();
}

export async function getPostBySlug(slug: string): Promise {
  const res = await fetch(
    `${WP_API_URL}/posts?slug=${slug}&_embed`,
    { next: { revalidate: 300 } }
  );
  if (!res.ok) return null;
  const posts: WPPost[] = await res.json();
  return posts[0] || null;
}

export async function getAllPostSlugs(): Promise {
  const res = await fetch(
    `${WP_API_URL}/posts?per_page=100&_fields=slug`,
    { next: { revalidate: 3600 } }
  );
  if (!res.ok) return [];
  const posts = await res.json();
  return posts.map((p: { slug: string }) => p.slug);
}

Halaman Daftar Artikel Blog

Buat file app/blog/page.tsx:

import { getPosts } from '@/lib/wordpress';
import Link from 'next/link';

export const revalidate = 300; // ISR setiap 5 menit

export default async function BlogPage() {
  const posts = await getPosts();

  return (
    <main className="max-w-4xl mx-auto px-4 py-12">
      <h1 className="text-4xl font-bold mb-10">Blog</h1>
      <div className="grid gap-8">
        {posts.map((post) => (
          <article key={post.id} className="border-b pb-8">
            <h2 className="text-2xl font-semibold mb-2">
              <Link
                href={`/blog/${post.slug}`}
                className="hover:text-blue-600 transition-colors"
                dangerouslySetInnerHTML={{ __html: post.title.rendered }}
              />
            </h2>
            <p
              className="text-gray-600"
              dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }}
            />
            <Link
              href={`/blog/${post.slug}`}
              className="mt-3 inline-block text-blue-600 font-medium hover:underline"
            >
              Baca selengkapnya →
            </Link>
          </article>
        ))}
      </div>
    </main>
  );
}

Halaman Detail Artikel dengan generateStaticParams

Buat file app/blog/[slug]/page.tsx:

import { getPostBySlug, getAllPostSlugs } from '@/lib/wordpress';
import { notFound } from 'next/navigation';
import type { Metadata } from 'next';

export async function generateStaticParams() {
  const slugs = await getAllPostSlugs();
  return slugs.map((slug) => ({ slug }));
}

export async function generateMetadata({
  params,
}: {
  params: { slug: string };
}): Promise<Metadata> {
  const post = await getPostBySlug(params.slug);
  if (!post) return {};
  return {
    title: post.title.rendered,
    description: post.excerpt.rendered.replace(/<[^>]+>/g, '').slice(0, 160),
  };
}

export default async function PostPage({
  params,
}: {
  params: { slug: string };
}) {
  const post = await getPostBySlug(params.slug);
  if (!post) notFound();

  return (
    <article className="max-w-3xl mx-auto px-4 py-12">
      <h1
        className="text-4xl font-bold mb-6"
        dangerouslySetInnerHTML={{ __html: post.title.rendered }}
      />
      <div
        className="prose prose-lg max-w-none"
        dangerouslySetInnerHTML={{ __html: post.content.rendered }}
      />
    </article>
  );
}

Langkah 5: Menggunakan WPGraphQL sebagai Alternatif REST API

Untuk query yang lebih efisien, berikut cara menggunakan WPGraphQL dari Next.js. Buat file lib/wpgraphql.ts:

const WP_GRAPHQL_URL = process.env.WORDPRESS_API_URL?.replace('/wp-json/wp/v2', '/graphql')
  || 'https://namadomain.com/graphql';

async function fetchGraphQL<T>(query: string, variables = {}): Promise<T> {
  const res = await fetch(WP_GRAPHQL_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, variables }),
    next: { revalidate: 300 },
  });
  const { data, errors } = await res.json();
  if (errors) throw new Error(errors[0].message);
  return data;
}

export async function getPostsGQL() {
  const query = `
    query GetPosts {
      posts(first: 10) {
        nodes {
          id
          slug
          title
          excerpt
          date
          featuredImage {
            node {
              sourceUrl
              altText
            }
          }
          author {
            node { name }
          }
          categories {
            nodes { name slug }
          }
        }
      }
    }
  `;
  const data = await fetchGraphQL<{ posts: { nodes: any[] } }>(query);
  return data.posts.nodes;
}

Langkah 6: On-Demand Revalidation dengan WordPress Webhook

Salah satu tantangan headless WordPress adalah memastikan frontend diperbarui segera setelah konten berubah di WordPress. Solusinya adalah on-demand revalidation: WordPress mengirim webhook ke Next.js setiap kali post dipublikasikan atau diperbarui.

Membuat Route Handler di Next.js

Buat file app/api/revalidate/route.ts:

import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

const SECRET = process.env.REVALIDATE_SECRET;

export async function POST(request: NextRequest) {
  const { secret, slug } = await request.json();

  if (secret !== SECRET) {
    return NextResponse.json({ error: 'Invalid token' }, { status: 401 });
  }

  if (slug) {
    revalidatePath(`/blog/${slug}`);
  }
  revalidatePath('/blog');

  return NextResponse.json({ revalidated: true, slug });
}

Membuat Plugin WordPress untuk Webhook

Buat file plugin sederhana di WordPress (wp-content/plugins/headless-revalidate/headless-revalidate.php):

<?php
/**
 * Plugin Name: Headless Revalidate
 * Description: Kirim webhook ke Next.js saat post dipublikasikan
 */

function trigger_revalidation($post_id) {
    if (wp_is_post_revision($post_id)) return;

    $post = get_post($post_id);
    if ($post->post_status !== 'publish') return;

    $frontend_url = 'https://namadomain-frontend.com/api/revalidate';
    $secret = 'secret-token-anda'; // Sesuaikan

    wp_remote_post($frontend_url, array(
        'body' => json_encode(array(
            'secret' => $secret,
            'slug' => $post->post_name,
        )),
        'headers' => array('Content-Type' => 'application/json'),
        'blocking' => false,
    ));
}
add_action('save_post', 'trigger_revalidation');
Baca Juga: Cara Membuat Website dengan Strapi: Headless CMS Open Source | Cara Membuat Website dengan WordPress: Panduan Lengkap

Best Practices Headless WordPress

Agar implementasi headless WordPress Anda berjalan optimal, terapkan praktik-praktik terbaik berikut:

  • Gunakan Application Passwords untuk autentikasi: Untuk endpoint yang memerlukan autentikasi (seperti preview post draft), gunakan WordPress Application Passwords (bawaan sejak WP 5.6) daripada username/password biasa.
  • Cache API responses di frontend: Manfaatkan Next.js Data Cache dengan opsi revalidate yang tepat untuk mengurangi request berulang ke WordPress.
  • Lindungi wp-admin: Batasi akses ke direktori /wp-admin menggunakan IP whitelist di .htaccess atau konfigurasi Nginx untuk meningkatkan keamanan.
  • Gunakan plugin SEO untuk meta data API: Plugin seperti Yoast SEO atau Rank Math mengekspos meta data SEO (title, description, Open Graph) melalui REST API, memudahkan Anda mengimplementasikan SEO di frontend.
  • Optimalkan ukuran response API: Gunakan parameter _fields untuk membatasi field yang dikembalikan: /wp-json/wp/v2/posts?_fields=id,slug,title,excerpt.
  • Set up CDN untuk media: Gunakan CDN (seperti Cloudflare) di depan domain WordPress untuk mempercepat pengiriman media/gambar ke seluruh Indonesia.

FAQ: Pertanyaan Umum Cara Membuat Headless WordPress

Apa perbedaan headless WordPress dengan WordPress biasa?

WordPress biasa (monolitik) menggunakan tema PHP untuk sekaligus mengolah data dan merender tampilan HTML. Headless WordPress hanya berfungsi sebagai backend/CMS - konten dikelola melalui dashboard WordPress, tapi ditampilkan melalui frontend terpisah (seperti Next.js) yang mengambil data via REST API atau GraphQL. Hasilnya: performa lebih baik, keamanan lebih tinggi, dan fleksibilitas teknologi frontend lebih besar.

Apakah semua plugin WordPress tetap berfungsi di mode headless?

Tidak semua. Plugin yang berhubungan dengan rendering frontend (tema, page builder seperti Elementor/Divi, atau plugin yang output-nya berupa HTML) tidak relevan di mode headless karena rendering dilakukan di frontend terpisah. Plugin backend seperti Yoast SEO, ACF (Advanced Custom Fields), WooCommerce, dan plugin keamanan tetap berfungsi karena bekerja di level data dan logika bisnis, bukan tampilan.

Apakah headless WordPress lebih sulit dari WordPress biasa?

Ya, kompleksitas teknis lebih tinggi. Anda perlu memahami konsep API, cara kerja Next.js atau framework frontend lainnya, deployment dua aplikasi terpisah (WordPress backend + frontend), dan strategi caching/revalidation. Namun untuk developer berpengalaman, effort ini sebanding dengan manfaat performa dan fleksibilitas yang didapat.

Bagaimana cara menangani preview post draft di headless WordPress?

Untuk preview post yang belum dipublikasikan, gunakan WordPress Preview dengan Next.js Draft Mode. Aktifkan WordPress Application Passwords, konfigurasi Next.js Draft Mode API route, dan tambahkan link preview di WordPress yang mengarah ke frontend dengan token draft mode. Plugin WP Headless Preview atau kode kustom bisa membantu mengimplementasikan alur ini.

Apakah WooCommerce bisa digunakan secara headless?

Ya. WooCommerce menyediakan REST API lengkap untuk produk, keranjang, checkout, dan order. Plugin WooCommerce GraphQL (via WPGraphQL WooCommerce add-on) menambahkan dukungan GraphQL. Banyak developer membangun toko online headless dengan WooCommerce sebagai backend dan Next.js sebagai frontend untuk performa checkout yang jauh lebih cepat.

Hosting apa yang direkomendasikan untuk headless WordPress?

Anda memerlukan dua hosting: satu untuk WordPress backend (shared hosting cPanel sudah cukup untuk traffic menengah) dan satu untuk frontend Next.js (Vercel, Netlify, atau VPS). Untuk WordPress backend, prioritaskan hosting dengan server Indonesia agar latensi API ke pengunjung lokal rendah. Hosting WordPress HostingEkspres dengan server Jakarta dan uptime 99.9% adalah pilihan tepat untuk backend headless WordPress Anda.

Bagaimana SEO headless WordPress dibandingkan WordPress biasa?

Dengan implementasi yang benar, SEO headless WordPress bisa lebih baik dari WordPress monolitik. Kuncinya adalah memastikan frontend Next.js menggunakan SSR atau SSG (bukan Client-Side Rendering murni), mengimplementasikan metadata SEO dari Yoast/Rank Math di halaman frontend, dan memastikan Googlebot bisa meng-crawl konten yang di-render. Core Web Vitals biasanya lebih baik di headless karena frontend yang lebih ringan dan cepat.

Kesimpulan: Headless WordPress untuk Web Modern Indonesia

Cara membuat headless WordPress membuka potensi yang jauh lebih besar dari WordPress monolitik: performa superior, keamanan lebih baik, dan kebebasan memilih teknologi frontend terbaik. Dengan WordPress sebagai backend yang sudah matang dan Next.js sebagai frontend modern, Anda mendapatkan kombinasi yang sulit dikalahkan.

Memang, pendekatan ini membutuhkan pengetahuan teknis yang lebih dalam dibanding WordPress biasa. Namun untuk project web yang serius - terutama yang membutuhkan performa tinggi, traffic besar, atau distribusi konten multi-channel - investasi waktu untuk mempelajari headless WordPress sangat sepadan.

Butuh hosting WordPress yang andal sebagai backend headless Anda? WordPress Hosting HostingEkspres dengan server Jakarta, cPanel, SSL gratis, dan uptime 99.9% adalah fondasi sempurna untuk arsitektur headless WordPress Anda. Tersedia mulai Rp 15.000/bulan.

Bangun Backend Headless WordPress Anda

Hosting WordPress Indonesia dengan server Jakarta, SSL gratis, cPanel lengkap, dan support 24/7. Mulai Rp 15.000/bulan.

Mulai WordPress Hosting

Butuh Hosting untuk Website Anda?

Dapatkan hosting cepat, aman, dan terpercaya dengan harga terjangkau. Gratis domain, SSL, dan support 24/7.

Jangan Ketinggalan Promo!

Subscribe newsletter kami dan dapatkan diskon hingga 50% untuk pembelian pertama kamu.

Gratis, tanpa spam. Bisa unsubscribe kapan saja.