VercelLogotypeVercelLogotype
LoginSign Up
Back to Templates

Next.js Starter for WordPress Headless CMS

next-wp is a Next.js application for Headless WordPress. Includes functions for fetching posts, categories, tags, pages, and featured media.

DeployView Demo
nextjs-headless-wordpress

Next WP

A modern headless WordPress starter built with Next.js 16, React 19, and TypeScript.

Live Demo | Video Tutorial | Headless Theme (761)

Need a WooCommerce version? Try next-woo

Table of Contents

  • Quick Start
  • Prerequisites
  • Environment Variables
  • Features
  • Project Structure
  • Deployment
    • Railway (Recommended)
    • Vercel
    • Local Development
  • WordPress API Functions
  • Cache Revalidation
  • Customization
  • Troubleshooting
  • Testing
  • Scripts
  • Contributing
  • License
  • Credits

Quick Start

# Clone the repository
git clone https://github.com/9d8dev/next-wp.git
cd next-wp
# Install dependencies
pnpm install
# Set up environment variables
cp .env.example .env.local
# Edit .env.local with your WordPress URL and credentials
# Start development server
pnpm dev

Your site is now running at http://localhost:3000.

Prerequisites

  • Node.js 18.17 or later
  • pnpm 8.0 or later (recommended) or npm/yarn
  • WordPress site with REST API enabled (default in WordPress 4.7+)

Environment Variables

Create a .env.local file in the root directory:

WORDPRESS_URL="https://your-wordpress-site.com" # Full WordPress URL
WORDPRESS_HOSTNAME="your-wordpress-site.com" # Domain for image optimization
WORDPRESS_WEBHOOK_SECRET="your-secret-key-here" # Secret for cache revalidation

Features

  • Type-safe WordPress API - Full TypeScript support with comprehensive type definitions
  • Server-side pagination - Efficient handling of large content libraries
  • Automatic cache revalidation - WordPress plugin for instant updates
  • Dynamic routes - Posts, pages, authors, categories, and tags
  • Search & filtering - Real-time search with debouncing
  • Dynamic sitemap - Auto-generated XML sitemap
  • OG image generation - Dynamic social media cards
  • Dark mode - Built-in theme switching
  • shadcn/ui components - Beautiful, accessible UI components
  • Responsive design - Mobile-first with Tailwind CSS v4

Project Structure

next-wp/
├── __tests__/ # Vitest test suite
│ ├── api/ # API route tests
│ └── lib/ # Library tests
├── app/ # Next.js App Router
│ ├── api/
│ │ ├── og/ # OG image generation
│ │ └── revalidate/ # Cache revalidation webhook
│ ├── pages/[slug]/ # Dynamic WordPress pages
│ ├── posts/
│ │ ├── [slug]/ # Individual post pages
│ │ ├── authors/ # Author archive
│ │ ├── categories/ # Category archive
│ │ └── tags/ # Tag archive
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Homepage
│ └── sitemap.ts # Dynamic sitemap
├── components/
│ ├── posts/ # Post-related components
│ │ ├── post-card.tsx # Post card component
│ │ ├── filter.tsx # Filter controls
│ │ └── search-input.tsx # Search component
│ ├── nav/ # Navigation components
│ ├── theme/ # Theme toggle
│ └── ui/ # shadcn/ui components
├── lib/
│ ├── wordpress.ts # WordPress API functions
│ └── wordpress.d.ts # TypeScript definitions
├── plugin/ # WordPress revalidation plugin
├── menu.config.ts # Navigation configuration
├── site.config.ts # Site metadata
└── vitest.config.ts # Test configuration

Deployment

Railway (Recommended)

Railway deploys the complete stack with one click: MySQL + WordPress + Next.js.

What's Included

The Railway template uses a custom WordPress Docker image (ghcr.io/9d8dev/next-wp-wordpress) with:

  • next-revalidate plugin - Pre-installed and auto-activated for cache revalidation
  • nextjs-headless theme - Redirects WordPress frontend to your Next.js site
  • WP-CLI - Automated WordPress setup
  • MySQL 8.0 - Database with persistent volume
  • Next.js - Your frontend application
┌─────────┐ ┌───────────┐ ┌─────────┐
│ MySQL │────▶│ WordPress │◀────│ Next.js │
│ DB │ │ (CMS) │ │(Frontend)│
└─────────┘ └───────────┘ └─────────┘
Deployment
  1. Click the Deploy on Railway button above
  2. Wait for all 3 services to deploy (MySQL, WordPress, Next.js)
  3. Note the WordPress and Next.js public URLs from the Railway dashboard
Post-Deployment Setup

1. Complete WordPress Installation

  1. Visit your WordPress URL (e.g., https://wordpress-xxx.up.railway.app)
  2. Complete the installation wizard:
    • Site Title
    • Admin Username
    • Admin Password
    • Admin Email
  3. Click "Install WordPress"

2. Configure the Revalidation Plugin

The next-revalidate plugin is pre-installed and activated.

  1. Go to WordPress Admin → Settings → Next.js Revalidation
  2. Enter your Next.js URL (e.g., https://next-wp-xxx.up.railway.app)
  3. Enter the Webhook Secret:
    • In Railway, go to your Next.js service → Variables
    • Copy the WORDPRESS_WEBHOOK_SECRET value
    • Paste it in the plugin settings
  4. Click Save

3. Test the Setup

  1. Create a test post in WordPress and publish it
  2. Visit your Next.js site - the post should appear
  3. Edit the post in WordPress
  4. Refresh the Next.js site - changes should appear (revalidation working)
Customizing the Next.js Code

By default, the template deploys from the 9d8dev/next-wp repository. To customize:

  1. In Railway, click on the Next.js service
  2. Go to Settings → Source → Upstream Repo
  3. Click "Eject"
  4. Select your GitHub account/organization
  5. Click "Eject service"

Railway creates a copy of the repository in your GitHub. You can then:

  • Clone the repo locally
  • Make customizations (styling, components, pages)
  • Push changes → Railway auto-deploys

Vercel

  1. Click the Deploy with Vercel button above
  2. Fill in environment variables:
    • WORDPRESS_URL - Your existing WordPress site URL
    • WORDPRESS_HOSTNAME - WordPress domain (for images)
    • WORDPRESS_WEBHOOK_SECRET - Generate a secure random string
  3. Deploy and wait for build to complete
  4. Install the revalidation plugin on your WordPress site
  5. Configure the plugin with your Vercel deployment URL

Local Development

# Install dependencies
pnpm install
# Copy environment template
cp .env.example .env.local
# Configure your WordPress connection in .env.local
# Then start the dev server
pnpm dev

Required: Your WordPress site must have the REST API enabled (default since WP 4.7).

WordPress API Functions

All WordPress interactions are centralized in lib/wordpress.ts:

Posts

getRecentPosts(filters?) // Recent posts (max 100)
getPostsPaginated(page, perPage, filters?) // Paginated posts with headers
getPostBySlug(slug) // Single post by slug (with _embed)
getPostById(id) // Single post by ID
getAllPostSlugs() // All slugs (for static generation)
getAllPostsForSitemap() // All slugs + modified dates

Taxonomies

getAllCategories() // All categories
getCategoryById(id) // Category by ID
getCategoryBySlug(slug) // Category by slug
getAllTags() // All tags
getTagById(id) // Tag by ID
getTagBySlug(slug) // Tag by slug
getPostsByCategory(id) // Posts in category
getPostsByTag(id) // Posts with tag
getTagsByPost(postId) // Tags on a post

Authors & Pages

getAllAuthors() // All authors
getAuthorById(id) // Author by ID
getAuthorBySlug(slug) // Author by slug
getPostsByAuthor(id) // Posts by author
getAllPages() // All pages
getPageById(id) // Page by ID
getPageBySlug(slug) // Page by slug

Paginated Queries

getPostsByCategoryPaginated(categoryId, page, perPage)
getPostsByTagPaginated(tagId, page, perPage)
getPostsByAuthorPaginated(authorId, page, perPage)

Search

searchCategories(query) // Search categories
searchTags(query) // Search tags
searchAuthors(query) // Search authors

Example Usage

import { getPostsPaginated } from "@/lib/wordpress";
const { data: posts, headers } = await getPostsPaginated(1, 9, {
category: "news",
search: "nextjs"
});
console.log(`Found ${headers.total} posts across ${headers.totalPages} pages`);

Cache Revalidation

The starter uses Next.js cache tags for efficient revalidation:

  1. Install the plugin - Download next-revalidate.zip and upload to WordPress
  2. Configure - Go to Settings > Next.js Revalidation
  3. Set URL - Enter your Next.js site URL
  4. Set secret - Use the same WORDPRESS_WEBHOOK_SECRET value

When content changes in WordPress, only affected pages are revalidated.

Note: If using the Railway template, the plugin is pre-installed automatically.

Customization

Site Configuration

Edit site.config.ts for site metadata:

export const siteConfig = {
site_name: "Your Site",
site_domain: "yourdomain.com",
site_description: "Your site description"
};

Navigation

Edit menu.config.ts for navigation links:

export const mainMenu = {
home: "/",
blog: "/posts",
// Add more links...
};
export const contentMenu = {
categories: "/posts/categories",
tags: "/posts/tags",
authors: "/posts/authors",
};

Theming

This project uses shadcn/ui with Tailwind CSS. Customize colors in your CSS or update the shadcn theme.

Troubleshooting

REST API not accessible

  • Ensure your WordPress site is publicly accessible
  • Check that permalinks are set (Settings > Permalinks)
  • Verify REST API at your-site.com/wp-json/wp/v2/posts

Images not loading

  • Add your WordPress domain to WORDPRESS_HOSTNAME
  • Check next.config.ts has the correct remotePatterns

Revalidation not working

  • Verify WORDPRESS_WEBHOOK_SECRET matches in both WordPress and Next.js
  • Check the plugin is activated in WordPress
  • Test the webhook endpoint at /api/revalidate

CORS errors

  • Install a CORS plugin on WordPress, or
  • Configure your server to allow requests from your Next.js domain

Testing

The project uses Vitest for unit testing.

pnpm test # Run all tests
pnpm test:watch # Run in watch mode

Tests cover the core modules:

ModuleWhat's tested
lib/utilscn() class merging with Tailwind deduplication
lib/metadatastripHtml, truncateHtml, OG/Twitter metadata generation
lib/wordpressAPI fetch layer, pagination, error handling, graceful fallbacks
api/revalidateWebhook secret validation, content type routing, cache revalidation

Scripts

pnpm dev # Start development server
pnpm build # Build for production
pnpm start # Start production server
pnpm lint # Run ESLint
pnpm test # Run tests

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see LICENSE for details.

Credits

Built with Next.js, Tailwind CSS, shadcn/ui, and brijr/craft.

Created by Bridger Tower and Cameron Youngblood at 9d8.

GitHub Repo9d8dev/next-wp
Use Cases
CMS
Stack
Next.jsTailwind
CMS
WordPress

Related Templates

Get Started

  • Templates
  • Supported frameworks
  • Marketplace
  • Domains

Build

  • Next.js on Vercel
  • Turborepo
  • v0

Scale

  • Content delivery network
  • Fluid compute
  • CI/CD
  • Observability
  • AI GatewayNew
  • Vercel AgentNew

Secure

  • Platform security
  • Web Application Firewall
  • Bot management
  • BotID
  • SandboxNew

Resources

  • Pricing
  • Customers
  • Enterprise
  • Articles
  • Startups
  • Solution partners

Learn

  • Docs
  • Blog
  • Changelog
  • Knowledge Base
  • Academy
  • Community

Frameworks

  • Next.js
  • Nuxt
  • Svelte
  • Nitro
  • Turbo

SDKs

  • AI SDK
  • Workflow SDKNew
  • Flags SDK
  • Chat SDK
  • Streamdown AINew

Use Cases

  • Composable commerce
  • Multi-tenant platforms
  • Web apps
  • Marketing sites
  • Platform engineers
  • Design engineers

Company

  • About
  • Careers
  • Help
  • Press
  • Legal
  • Privacy Policy

Community

  • Open source program
  • Events
  • Shipped on Vercel
  • GitHub
  • LinkedIn
  • X
  • YouTube

Loading status…

Select a display theme:
    • AI Cloud
      • v0

        Build applications with AI

      • AI SDK

        The AI Toolkit for TypeScript

      • AI Gateway

        One endpoint, all your models

      • Vercel Agent

        An agent that knows your stack

      • Sandbox

        AI workflows in live environments

    • Core Platform
      • CI/CD

        Helping teams ship 6× faster

      • Content Delivery

        Fast, scalable, and reliable

      • Fluid Compute

        Servers, in serverless form

      • Observability

        Trace every step

    • Security
      • Bot Management

        Scalable bot protection

      • BotID

        Invisible CAPTCHA

      • Platform Security

        DDoS Protection, Firewall

      • Web Application Firewall

        Granular, custom protection

    • Company
      • Customers

        Trusted by the best teams

      • Blog

        The latest posts and changes

      • Changelog

        See what shipped

      • Press

        Read the latest news

      • Events

        Join us at an event

    • Learn
      • Docs

        Vercel documentation

      • Academy

        Linear courses to level up

      • Knowledge Base

        Find help quickly

      • Community

        Join the conversation

    • Open Source
      • Next.js

        The native Next.js platform

      • Nuxt

        The progressive web framework

      • Svelte

        The web’s efficient UI framework

      • Turborepo

        Speed with Enterprise scale

    • Use Cases
      • AI Apps

        Deploy at the speed of AI

      • Composable Commerce

        Power storefronts that convert

      • Marketing Sites

        Launch campaigns fast

      • Multi-tenant Platforms

        Scale apps with one codebase

      • Web Apps

        Ship features, not infrastructure

    • Tools
      • Marketplace

        Extend and automate workflows

      • Templates

        Jumpstart app development

      • Partner Finder

        Get help from solution partners

    • Users
      • Platform Engineers

        Automate away repetition

      • Design Engineers

        Deploy for every idea

  • Enterprise
  • Pricing
Log InContact
Sign Up
Sign Up
Back to Templates
DeployView Demo

Contentstack Commerce

Learn to use Contentstack SDK to create apps with Next.js and Vercel.
Contentstack Commerce

Next.js Blog with Draft Mode

Static blog with Preview Mode, built with Next.js and Contentful.
Next.js Blog with Draft Mode

ISR Blog with Next.js and WordPress

An Incremental Static Regeneration Blog Example Using Next.js and WordPress
ISR Blog with Next.js and WordPress
v0

Build applications with AI

AI SDK

The AI Toolkit for TypeScript

AI Gateway

One endpoint, all your models

Vercel Agent

An agent that knows your stack

Sandbox

AI workflows in live environments

CI/CD

Helping teams ship 6× faster

Content Delivery

Fast, scalable, and reliable

Fluid Compute

Servers, in serverless form

Observability

Trace every step

Bot Management

Scalable bot protection

BotID

Invisible CAPTCHA

Platform Security

DDoS Protection, Firewall

Web Application Firewall

Granular, custom protection

Customers

Trusted by the best teams

Blog

The latest posts and changes

Changelog

See what shipped

Press

Read the latest news

Events

Join us at an event

Docs

Vercel documentation

Academy

Linear courses to level up

Knowledge Base

Find help quickly

Community

Join the conversation

Next.js

The native Next.js platform

Nuxt

The progressive web framework

Svelte

The web’s efficient UI framework

Turborepo

Speed with Enterprise scale

AI Apps

Deploy at the speed of AI

Composable Commerce

Power storefronts that convert

Marketing Sites

Launch campaigns fast

Multi-tenant Platforms

Scale apps with one codebase

Web Apps

Ship features, not infrastructure

Marketplace

Extend and automate workflows

Templates

Jumpstart app development

Partner Finder

Get help from solution partners

Platform Engineers

Automate away repetition

Design Engineers

Deploy for every idea