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: