#atom

Headless TypeScript CMS with built-in admin panel and developer flexibility

Core Idea: Payload CMS is a headless, self-hosted content management system built with TypeScript that provides a powerful admin interface while allowing developers to maintain complete control over the content structure, APIs, and presentation layer.

Key Elements

Key Features

Concepts

Technical Specifications

Use Cases

Implementation Steps

// 1. Collection Definition
// collections/Products.ts
import { CollectionConfig } from 'payload/types';

const Products: CollectionConfig = {
  slug: 'products',
  admin: {
    useAsTitle: 'title',
  },
  access: {
    read: () => true,
    create: ({ req }) => req.user?.role === 'admin',
    update: ({ req }) => req.user?.role === 'admin',
    delete: ({ req }) => req.user?.role === 'admin',
  },
  fields: [
    {
      name: 'title',
      type: 'text',
      required: true,
    },
    {
      name: 'price',
      type: 'number',
      required: true,
      min: 0,
    },
    {
      name: 'description',
      type: 'richText',
    },
    {
      name: 'category',
      type: 'relationship',
      relationTo: 'categories',
      hasMany: false,
    },
    {
      name: 'images',
      type: 'array',
      fields: [
        {
          name: 'image',
          type: 'upload',
          relationTo: 'media',
          required: true,
        },
        {
          name: 'altText',
          type: 'text',
        }
      ]
    }
  ],
};

export default Products;

// 2. Payload Configuration
// payload.config.ts
import { buildConfig } from 'payload/config';
import Products from './collections/Products';
import Categories from './collections/Categories';
import Media from './collections/Media';
import Users from './collections/Users';

export default buildConfig({
  serverURL: process.env.SERVER_URL,
  admin: {
    user: Users.slug,
  },
  collections: [
    Products,
    Categories,
    Media,
    Users,
  ],
});

Code Examples

Direct API Access in Server Component:

// app/products/page.tsx
import { getPayload } from '@/lib/payload';

export default async function ProductsPage() {
  const payload = await getPayload();
  
  const { docs: products } = await payload.find({
    collection: 'products',
    limit: 10,
    sort: '-createdAt',
  });
  
  return (
    <div>
      <h1>Products</h1>
      <div className="product-grid">
        {products.map(product => (
          <ProductCard key={product.id} product={product} />
        ))}
      </div>
    </div>
  );
}

Common Pitfalls

Additional Connections

References

  1. Payload CMS Documentation - https://payloadcms.com/docs
  2. "Building with Payload and Next.js" - Payload CMS Blog
  3. GitHub Repository - https://github.com/payloadcms/payload

#cms #typescript #headless #api #content-management #node-js


Sources: