Payload CMS Explained: A Complete Guide to Headless CMS Development

Payload CMS Explained: A Complete Guide to Headless CMS Development

author

By Dharmesh Ghoghari Published in Payload CMS

Payload CMS Explained: A Complete Guide to Headless CMS Development

Over the past few years, Content Management Systems (CMS) have come a long way, making lives of developers and businesses relatively easier in terms of helping them manage content. Payload CMS is an example of a modern, developer-friendly CMS. Payload CMS is a headless CMS, which means we decoupled the back-end and front-end, allowing the users to manage content using widely used programming languages like Node.js, MongoDB, PostgreSQL, and SQLite databases

This guide will explore Payload CMS in great detail, including:

Why Use Payload Headless CMS? – Main benefits and functions.

Payload headless CMS – Installation and Initial configuration Settings and Customizations – Steps to customize 

Payload headless CMS according to your project requirement. By the time you get to the end of this article, you will have learned what a Headless CMS is and be prepared to start creating projects based on it.

Why Choose Payload CMS?

one feature that sets Payload headless CMS apart from the pack is its developer-first focus. Traditional CMSs involve complex integrations, while Payload CMS is built from the ground up around modern apps, allowing developers to spend less time worrying about the API and more time building out the loved ones. Here are the top reasons why developers love it:

Headless and API-First

Payload CMS is a headless CMS, meaning it decouples the backend from the frontend. This makes it very adaptable, allowing developers to build frontend apps in any frontend framework, such as React, Vue, or Angular. CMS also offers a GraphQL and REST API by default, and you can retrieve content easily.

For instance, fetching blog posts through REST API will look like:

GET /api/posts

This architecture allows developers to utilize Payload headless CMS in mobile apps, Web apps, web applications, and even IoT devices without backend restrictions.

Built on Node. js and Express

Payload headless CMS is architected with Node. js and Express, which makes it light, fast and highly customizable. It’s written in JavaScript, so developers who know React, Next. js, or Vue. js will even find it to be simple to use in their project.

Secure and Scalable

Payload headless CMS is secure by design. It offers role-based access control (RBAC), authentication, and strong user management functionality. You can create your access controls and permissions for secure data protection.

To do this, we configure access control to limit certain users, it would look like this:

access: {
read: ({ req }) => req. user && req. user. role === 'admin',
},

This ensures that only admin users can access specific data, keeping your application secure.

Getting Started with Payload Headless CMS

1. Installation and Setup

To start using Payload CMS, you need to have Node.js installed. Follow these simple steps:

Step 1: Install Payload CMS

npx create-payload-app my-project
cd my-project
npm install

Step 2: Start the Development Server

npm run dev

Once the server is running, open http://localhost:3000/admin in your browser to access the admin panel.

2. Creating a Custom Collection

Collections in Payload headless CMS are like database tables, where content is stored. Let’s create a blog post collection:

Step 1: Install Payload CMS

const Posts = {
    slug: 'posts',
    fields: [
        {
            name: 'title',
            type: 'text',
            required: true,
        },
        {
            name: 'content',
            type: 'richText',
            required: true,
        },
        {
            name: 'author',
            type: 'relationship',
            relationTo: 'users',
        }
    ]
};

export default Posts;

Once you add this collection, Payload CMS will automatically generate an API endpoint to create, read, update, and delete blog posts.

Customization and Extensibility

1. Extending the Admin Panel

Payload CMS allows you to customize the admin dashboard to suit your needs. You can modify fields, add custom UI elements, or even create new dashboard widgets.

For example, to add a custom dashboard widget, modify the admin configuration:

Step 1: Install Payload CMS

admin: {
  components: {
    Dashboard: () => <h2>Welcome to My Custom Dashboard</h2>
  }
}

This simple customization enhances the user experience for content managers and editors.

2. Integrating with Frontend Frameworks

Since Payload CMS is headless, integrating with React, Next.js, or Vue.js is seamless. Here’s an example of fetching posts in a Next.js application:

Step 1: Install Payload CMS

import { useEffect, useState } from 'react';
 
export default function Blog() {
  const [posts, setPosts] = useState([]);
 
  useEffect(() => {
    fetch('/api/posts')
      .then(res => res.json())
      .then(data => setPosts(data.docs));
  }, []);
 
  return (
    <div>
      <h1>Blog Posts</h1>
      {posts.map(post => (
        <div key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  );
}

This example demonstrates how easy it is to fetch and display content from Payload CMS in a frontend application.

Developer Guide Payload Headless CMS

Payload CMS is a modern headless CMS for developers. It’s powerful, has robust APIs and a highly customisable admin panel. But new users can struggle to set up, configure and extend it. This guide answers the most common developer questions with clear answers, step by step solutions and code snippets.

1. How do I use Payload CMS Blocks in Next.js?

Solution

Payload headless CMS allows developers to create flexible content structures using blocks. To render these blocks dynamically in a Next.js frontend:

  • Fetch the Data: Use getServerSideProps or getStaticProps to fetch the content from Payload CMS.
  • Map Blocks to Components: Define React components corresponding to each block type.
  • Render Blocks Dynamically: Use a switch statement or a mapping function to display blocks based on their type.

Code Example

// pages/index.js
import React from 'react';
import HeroBlock from '../components/HeroBlock';
import TextBlock from '../components/TextBlock';
import { fetchPayloadData } from '../lib/payloadAPI';
 
const BlockRenderer = ({ blocks }) => {
  return blocks.map((block, index) => {
    switch (block.blockType) {
      case 'hero':
        return <HeroBlock key={index} data={block} />;
      case 'text':
        return <TextBlock key={index} data={block} />;
      default:
        return null;
    }
  });
};
 
export async function getStaticProps() {
  const pageData = await fetchPayloadData('pages', 'home');
  return { props: { pageData } };
}
 
export default function Home({ pageData }) {
  return <BlockRenderer blocks={pageData.blocks} />;
}

2. What’s the best folder structure for Payload CMS and Next.js in one repo?

Solution

A well-structured repository improves maintainability. Follow this pattern:

A well-structured repository improves maintainability. Follow this pattern:
/project-root
  /backend  # Payload CMS
    /collections
    /config
    /payload.config.js
  /frontend  # Next.js frontend
    /components
    /pages
    /lib
  /shared    # Shared utilities
  .env
package.json

README.md

  • Keep Payload headless CMS (backend) and Next.js (frontend) separate.
  • Store shared utilities in the shared folder for reusability.
  • Use .env files for configuration.

3. How do I build a multi language website with a block builder in Payload CMS?

Solution

  • Enable Localization in Payload CMS: Modify payload.config.js to support multiple languages.
  • Use Language-Based Fields: Add a localized property to fields.
  • Switch Languages in Next.js: Pass the locale dynamically to fetch the correct content.

Code Example

// payload.config.js
collections: [
  {
    slug: 'pages',
    fields: [
      {
        name: 'title',
        type: 'text',
        localized: true, // Enables localization
      },
      {
        name: 'blocks',
        type: 'array',
        localized: true,
        fields: [
          { name: 'blockType', type: 'text' },
          { name: 'content', type: 'richText' },
        ],
      },
    ],
  },
]

4. How do I handle nested page routing in Payload CMS with Next.js?

Solution

  • Use a slug Field in the Collection: Store hierarchical slugs (/about/team).
  • Fetch Data Based on Slugs: Query Payload CMS using the full slug.
  • Handle Nested Routing in Next.js: Use dynamic catch-all routes ([…slug].js).

Code Example

// pages/[[...slug]].js
export async function getStaticProps({ params }) {
  const slug = params.slug ? params.slug.join('/') : 'home';
  const pageData = await fetchPayloadData('pages', slug);
  return { props: { pageData } };
}

5. How do I create media folders in Payload CMS like the Payload Landing Page?

Solution

By default, Payload CMS lacks a UI for media folders. However, you can:

  • Add a folder field to media collections.
  • Implement a custom UI extension to group files visually.

Code Example

collections: [
  {
    slug: 'media',
    upload: true,
    fields: [
      {
        name: 'folder',
        type: 'text',
      },
    ],
  },
]

6. Is Payload headless CMS for developers who are not familiar with Next.js and how does it compare to Strapi?

Answer

Yes! Payload CMS is:

  • More developer-focused (built with TypeScript, fully extensible API).
  • More customizable (flexible database support, UI components).
  • Less opinionated than Strapi, making it more powerful for advanced setups.

However, Strapi might be a better choice for developers looking for a plug-and-play UI with less configuration.

7. How do I integrate headless e-commerce with Payload CMS for multiple storefronts?

Solution

  • Use Payload CMS for Product & Order Management.
  • Integrate Shopify, BigCommerce, or a Custom Checkout.
  • Expose APIs to Multiple Frontends.

Code Example

collections: [
  {
    slug: 'products',
    fields: [
      { name: 'title', type: 'text' },
      { name: 'price', type: 'number' },
      { name: 'storefronts', type: 'array', fields: [
        { name: 'domain', type: 'text' },
      ] },
    ],
  },
]

Conclusion

Payload CMS is a powerful, flexible and developer-friendly CMS for modern applications. Whether you’re building a blog, an eCommerce site or a large enterprise application, Payload headless CMS has got the scalability and customisation you need.

Payload CMS is a mighty tool. This guide has covered the essentials.

Ready to try Payload CMS? Start your project today by hiring a Payload CMS Developer and set up your first project. Play with it, customize the admin panel and integrate it with your favorite frontend framework to build next-level applications!