π It's headless WordPress! - https://nextjswp.com
This repo is a bare bones Next.js app which fetches data from WordPress and styles it with Tailwind. That's it.
Please consider it a starting point for your next headless WordPress site.
- Next.js 13 with App Router and Tailwind CSS
- WordPress data via GraphQL
- Support for:
- Custom Post Types
- Custom Fields
- Comments
- Yoast SEO
- TypeScript, ESLint, Prettier, and Stylelint
- Plus it's really fast!
git clone git@github.com:gregrickaby/nextjs-wordpress.gitnpm icp .env.example .env.localCustomize the URLs in .env.local to match your WordPress site:
# WordPress GraphQL API URL.
NEXT_PUBLIC_WORDPRESS_GRAPHQL_URL="https://your-wordpress-site.com/graphql"
# WordPress REST API URL.
NEXT_PUBLIC_WORDPRESS_REST_URL="https://your-wordpress-site.com/wp-json/wp/v2/"Update the URL in next.config.js to match your WordPress site:
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'wordpress.nextjswp.com' // <-- Change to your WordPress site
},
{
protocol: 'https',
hostname: '**.gravatar.com'
}
]
}
}
module.exports = nextConfignpm run devOnce the dev servers have started, you can view the following: http://localhost:3000
You'll need either a local or public WordPress site with the following plugins:
- WPGraphQL
- WPGraphQL for Advanced Custom Fields
- WPGraphQL Yoast SEO
- Advanced Custom Fields
- Next.js WordPress Theme
- Next.js WordPress Plugin
I've decided to simplify things based on the Next.js 13 App Router. You can still view the old repo.
GraphQL is efficient because we can query multiple endpoints in a single request. If we were to use the WordPress REST-API, we would need to make multiple round trips to each respective endpoint.
We can build our queries in GraphiQL (or your favorite REST client) and let JSON.stringify() format it. Because this is all standard JavaScript, we can even pass variables to our queries-- no need for a 3rd party package!
Here is a query to fetch a single post (based on the slug), the featured image, author meta, categories, tags, SEO, and post comments:
import {Post} from '@/lib/types'
/**
* Fetch a single post by slug.
*/
export async function getPostBySlug(slug: string) {
// Define our query.
const query = `
query GetPost($slug: ID!) {
post(id: $slug, idType: SLUG) {
databaseId
content(format: RENDERED)
title(format: RENDERED)
featuredImage {
node {
altText
mediaDetails {
sizes(include: MEDIUM) {
height
width
sourceUrl
}
}
}
}
author {
node {
gravatarUrl
name
}
}
date
tags {
nodes {
databaseId
name
}
}
categories {
nodes {
databaseId
name
}
}
seo {
metaDesc
title
}
comments(first: 10, where: {order: ASC}) {
nodes {
content(format: RENDERED)
databaseId
date
status
author {
node {
email
gravatarUrl
name
}
}
}
}
}
}
`
// Define our variables.
const variables = {
slug: slug
}
// Fetch the data using a reusable fetch function.
const response = await fetchGraphQL(query, variables)
// Return the post.
return response.data.post as Post
}This repo does not use a 3rd party GraphQL package, because Next.js automatically memoizes the fetch() requests in our custom fetch function. This means that if we fetch the same data twice, Next.js will only make one request to WordPress.
If you prefer use a 3rd party GraphQL package, simply swap out the custom
fetchGraphQL()function.
Contributions are welcome! Please see the contributing guidelines for more information.