Using Headless WordPress with Next.js is a popular approach for combining WordPress’s powerful content management system (CMS) with Next.js’s performance and scalability. In this architecture, WordPress serves purely as a content backend, while Next.js handles the frontend, rendering pages using data fetched from the WordPress API.

Here’s a step-by-step guide to setting up Headless WordPress with Next.js:

1. Set Up WordPress as a Headless CMS

You’ll need to set up a WordPress site that acts as the content provider. WordPress comes with a built-in REST API that can be used to fetch content like posts, pages, categories, and media.

Steps:

  • Install WordPress on your server or use a platform like WordPress.com or Local by Flywheel.
  • Enable the REST API: WordPress has a REST API by default, so you don’t need any extra plugins. You can access the API endpoints like this:
    • Posts: https://your-wordpress-site.com/wp-json/wp/v2/posts
    • Pages: https://your-wordpress-site.com/wp-json/wp/v2/pages

Optionally, you can install plugins like:

  • WPGraphQL: A popular plugin to enable GraphQL in WordPress, providing more control over how data is queried.
bash
# Install WPGraphQL plugin

WPGraphQL

2. Set Up Next.js

Next, set up your Next.js project, which will act as the frontend.

bash
npx create-next-app headless-wp-next
cd headless-wp-next

3. Fetch Data from WordPress

You can fetch data from the WordPress REST API or GraphQL in Next.js using getStaticProps or getServerSideProps.

Using REST API

You can use getStaticProps to fetch WordPress posts and pages during build time.

js
// pages/index.js
export async function getStaticProps() {
const res = await fetch('https://your-wordpress-site.com/wp-json/wp/v2/posts');
const posts = await res.json();

return {
props: {
posts,
},
};
}

export default function Home({ posts }) {
return (
<div>
<h1>WordPress Posts</h1>
{posts.map((post) => (
<div key={post.id}>
<h2>{post.title.rendered}</h2>
<div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
</div>
))}
</div>

);
}

Using WPGraphQL

If you’re using WPGraphQL, you can fetch data from the GraphQL endpoint.

js
export async function getStaticProps() {
const res = await fetch('https://your-wordpress-site.com/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `
{
posts {
nodes {
title
content
}
}
}
`
,
}),
});

const { data } = await res.json();

return {
props: {
posts: data.posts.nodes,
},
};
}

4. Fetching Single Post/Page

For individual posts or pages, use dynamic routes in Next.js. You can use the getStaticPaths method to generate the paths at build time and getStaticProps to fetch the individual post data.

js
// pages/posts/[slug].js
export async function getStaticPaths() {
const res = await fetch('https://your-wordpress-site.com/wp-json/wp/v2/posts');
const posts = await res.json();

const paths = posts.map((post) => ({
params: { slug: post.slug },
}));

return { paths, fallback: false };
}

export async function getStaticProps({ params }) {
const res = await fetch(`https://your-wordpress-site.com/wp-json/wp/v2/posts?slug=${params.slug}`);
const post = await res.json();

return {
props: {
post: post[0], // API returns an array
},
};
}

export default function Post({ post }) {
return (
<div>
<h1>{post.title.rendered}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content.rendered }} />
</div>

);
}

5. Add Tailwind CSS for Styling (Optional)

For easy styling, you can add Tailwind CSS to your Next.js project.

  • Install Tailwind CSS:
bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
  • Configure tailwind.config.js and add Tailwind’s base styles to globals.css.
css
@tailwind base;
@tailwind components;
@tailwind utilities;

6. Deploy WordPress and Next.js

  • WordPress Deployment: You can deploy your WordPress site on any hosting provider like DigitalOcean, Kinsta, or Flywheel.
  • Next.js Deployment: You can deploy the Next.js frontend on platforms like Vercel, Netlify, or AWS.

For example, deploying to Vercel:

bash
npx vercel

7. Bonus: Search Engine Optimization (SEO)

Since Next.js allows you to generate static pages, you can improve SEO by adding metadata for each page using the next/head component:

js
import Head from 'next/head';

export default function Post({ post }) {
return (
<>
<Head>
<title>{post.title.rendered} | My Blog</title>
<meta name="description" content={post.excerpt.rendered} />
</Head>
<div>
<h1>{post.title.rendered}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content.rendered }} />
</div>
</>

);
}

8. Bonus: Authentication and Protected Content

To handle user authentication (if needed), you can integrate with plugins like JWT Authentication for WP REST API or WordPress OAuth Server.

  • For example, you can store the token in localStorage or a cookie and pass it with API requests to fetch protected content.

Conclusion

By using Headless WordPress with Next.js, you can decouple the CMS from the frontend, giving you flexibility, performance, and modern development workflows. The REST API or WPGraphQL makes it easy to fetch data from WordPress, while Next.js handles SEO, static site generation, and dynamic routing efficiently.

Sign In

Sign Up