How to Set Up Payload CMS with Next.js: A Complete Guide

Set Up Payload CMS with Next.js: A Complete Integration Guide

Payload CMS has emerged as a powerful, code-first headless CMS that integrates seamlessly with Next.js. This comprehensive guide will walk you through setting up Payload CMS with Next.js to create a modern, scalable web application.

1. Prerequisites

Before we begin, ensure you have:

  • Node.js 18+ installed
  • Basic knowledge of React and Next.js
  • A MongoDB database (local or cloud)

2. Initialize Your Next.js Project

Start by creating a new Next.js application:

npx create-next-app@latest my-payload-app
cd my-payload-app

3. Install Payload CMS

Install Payload and its dependencies:

npm install payload @payloadcms/bundler-webpack @payloadcms/db-mongodb @payloadcms/richtext-slate

4. Configure Payload

Create a payload.config.ts file in your project root:

import { buildConfig } from 'payload/config';
import { mongooseAdapter } from '@payloadcms/db-mongodb';
import { webpackBundler } from '@payloadcms/bundler-webpack';
import { slateEditor } from '@payloadcms/richtext-slate';

export default buildConfig({
  admin: {
    user: 'users',
    bundler: webpackBundler(),
  },
  editor: slateEditor({}),
  collections: [
    {
      slug: 'users',
      auth: true,
      fields: [],
    },
    {
      slug: 'posts',
      fields: [
        {
          name: 'title',
          type: 'text',
          required: true,
        },
        {
          name: 'content',
          type: 'richText',
        },
      ],
    },
  ],
  typescript: {
    outputFile: path.resolve(__dirname, 'payload-types.ts'),
  },
  graphQL: {
    schemaOutputFile: path.resolve(__dirname, 'generated-schema.graphql'),
  },
  db: mongooseAdapter({
    url: process.env.DATABASE_URI,
  }),
});

5. Set Up Environment Variables

Create a .env.local file:

DATABASE_URI=mongodb://localhost:27017/payload-cms
PAYLOAD_SECRET=your-secret-key

6. Create API Routes

Create pages/api/[...payload].ts (or app/api/[...payload]/route.ts for App Router):

import { NextApiRequest, NextApiResponse } from 'next';
import payload from 'payload';

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  await payload.init({
    secret: process.env.PAYLOAD_SECRET,
    mongoURL: process.env.DATABASE_URI,
    express: app,
    onInit: () => {
      payload.logger.info('Payload Admin initialized');
    },
  });

  return payload.handler(req, res);
};

export default handler;

7. Integrate with Next.js Pages

Fetch data from Payload in your Next.js components:

import { GetStaticProps } from 'next';
import payload from 'payload';

export const getStaticProps: GetStaticProps = async () => {
  const posts = await payload.find({
    collection: 'posts',
  });

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

8. Build Scripts

Update your package.json scripts:

{
  "scripts": {
    "dev": "cross-env PAYLOAD_CONFIG_PATH=payload.config.ts next dev",
    "build": "cross-env PAYLOAD_CONFIG_PATH=payload.config.ts next build",
    "start": "cross-env PAYLOAD_CONFIG_PATH=payload.config.ts next start"
  }
}

9. Best Practices

  • Type Safety: Use Payload’s generated TypeScript types
  • Authentication: Implement proper user roles and permissions
  • Caching: Use Next.js ISR for optimal performance
  • Security: Validate all inputs and use environment variables

10. Deployment Considerations

When deploying to Vercel or similar platforms:

  • Ensure MongoDB connection is properly configured
  • Set all environment variables in your deployment platform
  • Consider using MongoDB Atlas for production

Key Takeaway: Payload CMS with Next.js provides a powerful, developer-friendly stack for building modern web applications. The code-first approach gives you complete control while maintaining the benefits of a headless CMS.

Hashtags: #PayloadCMS #NextJS #HeadlessCMS #WebDevelopment #React #TypeScript #MongoDB

Resources: