Creating a Modern Headless CMS App with Payload CMS, MongoDB, and Next.js

Creating a Modern Headless CMS App with Payload CMS, MongoDB, and Next.js

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:

  1. Backend (or "headless CMS") focuses solely on content management and data storage, providing APIs (usually REST or GraphQL) for content delivery.
  2. Frontend applications or websites use these APIs to fetch data and render it in various formats or platforms, such as web browsers, mobile apps, smart TVs, or IoT devices.

Key Characteristics of a Headless Application

  • API-Driven: The backend communicates with clients via APIs, making it platform-agnostic and flexible.
  • Frontend-Agnostic: Since there is no built-in frontend, any technology or framework can be used on the client side.
  • Decoupled Architecture: The separation of frontend and backend allows for independent updates, scaling, and flexibility in design.

Advantages of Headless Applications

  • Flexibility in Frontend Choice: Developers can use any frontend technology, such as React, Next.js, Vue, or even mobile frameworks.
  • Omnichannel Publishing: The same content can be used across multiple platforms (website, mobile app, etc.) by accessing the same API.
  • Scalability: A headless backend can scale independently, supporting multiple frontend applications or high traffic across platforms.

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.


(Admin Login page)


(Dashboard Page)


(Pages listing screen)
(Creating a page)


(Select Content Layout screen)



(Post listing screen)
(Post creation screen)
(Categories screen)


(Add Header Menu item)


(Create Blog and posts)


(Select Archive option from the layout for the posts)
(Select Collection, Posts and Blog from the lists)

Add the Blog item to the menu on Header section


(Front end - Home page)


(Page details screen)

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.


(DB Collections screen)
(Pages Collections screen)

REST API Testing on Postman

(Post data screen)

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




要查看或添加评论,请登录

Jayaprakash Attupurath的更多文章

社区洞察

其他会员也浏览了