Creating a Modern Headless CMS App with Payload CMS, MongoDB, and Next.js
Jayaprakash Attupurath
Senior Consultant | SAP S/4HANA MM | AI / ML / Big Data Specialist | Expert Technical Lead | Certified ScrumMaster? | MTech (CS) in ML & Big Data | Masters in Computer Applications | Master of Business Administration
A headless application is a backend system that provides content and data via APIs, without a built-in frontend or graphical user interface (GUI). This "headless" architecture decouples the backend (where content is created and managed) from the frontend (where content is displayed), enabling greater flexibility in how and where the content is presented.
In a headless setup:
Key Characteristics of a Headless Application
Advantages of Headless Applications
In this article, we’ll walk through the process of building a modern headless CMS-driven application using Payload CMS (https://payloadcms.com/) as our backend, MongoDB as the database, and Next.js for the frontend. This setup offers flexibility, scalability, and a seamless content management experience, making it ideal for web applications that require a dynamic content structure.
Let’s dive into the steps to set up and integrate Payload CMS with Next.js and use APIs for data handling.
Prerequisites
Step 1: Setting Up Payload CMS
First, we’ll set up Payload CMS as our backend. Payload CMS uses MongoDB to store content data, so ensure MongoDB is running locally or available through a connection string.
Create a new directory:
mkdir payload-cms-app && cd payload-cms-app
Initialize a new Payload CMS project: Install the Payload CMS starter template.
npx create-payload-app
Choose a template (like “blank” or “blog”) as per your project needs. This command will create a new Payload CMS project with a pre-configured setup.
Install dependencies: Navigate into the new project directory and install dependencies.
cd payload-cms-app
npm install
Configure MongoDB: Open the .env file and add your MongoDB connection URI.
MONGODB_URI=mongodb://localhost:27017/payload-cms-app
Run Payload CMS: Start the CMS server to verify everything is set up.
npm run dev
The CMS should be accessible at https://localhost:3000/admin.
Add the Blog item to the menu on Header section
Utilize the other pages and options in the admin panel. These provide a straightforward content management process.
Step 2: Define Content Structure in Payload CMS
Payload CMS uses collections to define different types of content. In this guide, we’ll set up a Posts collection.
Create a New Collection: Open payload.config.js and add a new collection.
const Posts = {
slug: 'posts',
fields: [
{
name: 'title',
type: 'text',
required: true,
},
{
name: 'content',
type: 'richText',
},
{
name: 'publishedDate',
type: 'date',
},
],
};
module.exports = {
collections: {
Posts,
},
};
Restart Payload: After editing the config file, restart Payload CMS:
npm run dev
Test Content Creation: Go to the CMS admin panel, navigate to Posts, and add a sample post to verify that everything is working.
领英推荐
Step 3: Set Up the Next.js Project
Now that our backend is ready, let’s set up the frontend using Next.js.
Initialize a Next.js Project: In a separate directory, create a new Next.js application.
npx create-next-app nextjs-payload-app
Install Axios (for API requests):
npm install axios
Configure .env.local for Next.js: In the root of the Next.js project, create a .env.local file to store the Payload CMS API URL.
NEXT_PUBLIC_CMS_URL=https://localhost:3000
Step 4: Fetching Content from Payload CMS in Next.js
We’ll now create a service in Next.js to fetch posts from Payload CMS.
Create an API Service: In the nextjs-payload-app directory, create a folder named services and a file called payloadAPI.js.
import axios from 'axios';
const api = axios.create({
baseURL: process.env.NEXT_PUBLIC_CMS_URL,
});
export const fetchPosts = async () => {
const response = await api.get('/api/posts?limit=10');
return response.data;
};
Display Posts in a Page: Open pages/index.js and use fetchPosts to retrieve and display the posts.
import { fetchPosts } from '../services/payloadAPI';
import { useEffect, useState } from 'react';
export default function Home() {
const [posts, setPosts] = useState([]);
useEffect(() => {
const getPosts = async () => {
const data = await fetchPosts();
setPosts(data.docs);
};
getPosts();
}, []);
return (
<div>
<h1>Latest Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
<p>{post.publishedDate}</p>
</li>
))}
</ul>
</div>
);
}
This code will render a list of posts fetched from Payload CMS.
Step 5: Integrate Dynamic Routing in Next.js
To enable individual post pages, let’s set up dynamic routing in Next.js.
Create a Dynamic Route: Inside the pages folder, create a [slug].js file.
Fetch Post Data Based on Slug: Update [slug].js to fetch and display data for a single post.
import { fetchPostBySlug } from '../services/payloadAPI';
export async function getServerSideProps({ params }) {
const post = await fetchPostBySlug(params.slug);
return {
props: { post },
};
}
export default function PostPage({ post }) {
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
<p>{post.publishedDate}</p>
</div>
);
}
Update payloadAPI.js with fetchPostBySlug Function: Add a new function to payloadAPI.js to fetch a single post by its slug.
export const fetchPostBySlug = async (slug) => {
const response = await api.get(`/api/posts?where[slug][equals]=${slug}`);
return response.data.docs[0];
};
Step 6: Deploying the Application
Deploy Payload CMS: Deploy Payload CMS to a server or cloud provider and MongoDB to a managed service like MongoDB Atlas.
Deploy Next.js: Deploy the Next.js frontend to Vercel or any preferred hosting provider. Set the environment variable NEXT_PUBLIC_CMS_URL in the deployment settings to the deployed Payload CMS URL.
MongoDB
We can use any tools like MongoDB compass (https://www.mongodb.com/products/tools/compass) to connect and manage database of the application.
REST API Testing on Postman
For a complete REST API reference, visit: https://payloadcms.com/docs/rest-api/overview
Conclusion:
By integrating Payload CMS, MongoDB, and Next.js, you have built a flexible, performant, and modern headless CMS application that can easily scale. Payload CMS powers the backend and content management, while Next.js manages the frontend and routing.
#HeadlessCMS
#PayloadCMS
#NextJS
#MongoDB
#WebDevelopment
#FullStack
#JavaScript
#APIIntegration
#CMSDevelopment
#FrontendDevelopment
#BackendDevelopment
#ModernWeb
#DecoupledArchitecture
#HeadlessArchitecture
#WebAppDevelopment
#CodingTips
#TechStack
#FullStackDevelopment
#APIs
#FrontendFramework