Description
next-wp is a Next.js application for Headless WordPress. Includes functions for fetching posts, categories, tags, pages, and featured media.
npx boilerapp nextjs-wordpress-headless-cmsDocumentación
Next WP
A modern headless WordPress starter built with Next.js 16, React 19, and TypeScript.
Table of Contents
- Quick Start
- Prerequisites
- Environment Variables
- Features
- Project Structure
- Deployment
- WordPress API Functions
- Cache Revalidation
- Customization
- Troubleshooting
- 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/
├── 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
└── CLAUDE.md # AI assistant guidelines
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
- Click the Deploy on Railway button above
- Wait for all 3 services to deploy (MySQL, WordPress, Next.js)
- Note the WordPress and Next.js public URLs from the Railway dashboard
Post-Deployment Setup
1. Complete WordPress Installation
- Visit your WordPress URL (e.g.,
https://wordpress-xxx.up.railway.app) - Complete the installation wizard:
- Site Title
- Admin Username
- Admin Password
- Admin Email
- Click "Install WordPress"
2. Configure the Revalidation Plugin
The next-revalidate plugin is pre-installed and activated.
- Go to WordPress Admin → Settings → Next.js Revalidation
- Enter your Next.js URL (e.g.,
https://next-wp-xxx.up.railway.app) - Enter the Webhook Secret:
- In Railway, go to your Next.js service → Variables
- Copy the
WORDPRESS_WEBHOOK_SECRETvalue - Paste it in the plugin settings
- Click Save
3. Test the Setup
- Create a test post in WordPress and publish it
- Visit your Next.js site - the post should appear
- Edit the post in WordPress
- 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:
- In Railway, click on the Next.js service
- Go to Settings → Source → Upstream Repo
- Click "Eject"
- Select your GitHub account/organization
- 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
- Click the Deploy with Vercel button above
- Fill in environment variables:
WORDPRESS_URL- Your existing WordPress site URLWORDPRESS_HOSTNAME- WordPress domain (for images)WORDPRESS_WEBHOOK_SECRET- Generate a secure random string
- Deploy and wait for build to complete
- Install the revalidation plugin on your WordPress site
- 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
getAllPosts(filters?) // Get all posts (max 100)
getPostsPaginated(page, perPage, filters?) // Paginated posts
getPostBySlug(slug) // Single post by slug
getPostById(id) // Single post by ID
Taxonomies
getAllCategories() // All categories
getCategoryBySlug(slug) // Category by slug
getAllTags() // All tags
getTagBySlug(slug) // Tag by slug
getPostsByCategory(id) // Posts in category
getPostsByTag(id) // Posts with tag
Authors & Pages
getAllAuthors() // All authors
getAuthorBySlug(slug) // Author by slug
getPostsByAuthor(id) // Posts by author
getAllPages() // All pages
getPageBySlug(slug) // Page by slug
Example Usage
import { getPostsPaginated } from "@/lib/wordpress";
const { data: posts, headers } = await getPostsPaginated(1, 9, {
category: "news\
Prix
Gratuit