Skip to content
Learni
View all tutorials
CMS Headless

Comment configurer Payload CMS expert en 2026

Introduction

Payload CMS est un CMS headless moderne construit sur Node.js et TypeScript. Il offre un panneau d'administration généré automatiquement tout en permettant une personnalisation profonde via du code. Ce tutoriel expert couvre l'installation, la configuration avancée des collections, les hooks de cycle de vie, le contrôle d'accès granulaire et l'intégration avec Next.js. Vous apprendrez à structurer un projet maintenable, à sécuriser les données et à optimiser les performances pour un environnement de production. Chaque étape inclut du code complet et fonctionnel que vous pouvez copier directement.

Prérequis

  • Node.js 20+ et TypeScript 5.4+
  • Connaissances solides en Next.js App Router
  • Base de données PostgreSQL ou MongoDB
  • Compte Vercel ou serveur VPS pour le déploiement
  • Familiarité avec les concepts de hooks et middleware

Initialisation du projet

terminal
npx create-payload-app@latest my-cms --template blank-typescript
cd my-cms
npm install

Cette commande génère un projet Payload prêt pour TypeScript avec la structure minimale. Le template blank-typescript inclut déjà les dépendances essentielles comme payload et les types.

Configuration principale

payload.config.ts
import { buildConfig } from 'payload/config'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { slateEditor } from '@payloadcms/richtext-slate'
import { Users } from './collections/Users'
import { Posts } from './collections/Posts'

export default buildConfig({
  serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL || 'http://localhost:3000',
  admin: { user: Users.slug },
  collections: [Users, Posts],
  editor: slateEditor({}),
  db: mongooseAdapter({ url: process.env.DATABASE_URI || '' }),
  typescript: { outputFile: './payload-types.ts' },
})

Le fichier payload.config.ts centralise toute la configuration. On y déclare les collections, l'éditeur riche et l'adaptateur de base de données. Cette structure permet un typage complet via payload-types.ts généré automatiquement.

Collection Posts avancée

collections/Posts.ts
import { CollectionConfig } from 'payload/types'
export const Posts: CollectionConfig = {
  slug: 'posts',
  admin: { useAsTitle: 'title' },
  access: { read: () => true, create: ({ req }) => !!req.user },
  fields: [
    { name: 'title', type: 'text', required: true },
    { name: 'content', type: 'richText', required: true },
    { name: 'author', type: 'relationship', relationTo: 'users', required: true },
    { name: 'publishedAt', type: 'date' }
  ],
  hooks: {
    beforeChange: [({ data, operation }) => {
      if (operation === 'create') data.publishedAt = new Date()
      return data
    }]
  }
}

Cette collection définit un modèle complet avec relations, contrôle d'accès et hook beforeChange. Le hook injecte automatiquement la date de publication lors de la création.

Hook afterChange avancé

collections/Posts.ts
hooks: {
  afterChange: [async ({ doc, operation, req }) => {
    if (operation === 'update' && doc.publishedAt) {
      await req.payload.create({
        collection: 'revisions',
        data: { post: doc.id, snapshot: doc }
      })
    }
    return doc
  }]
}

Le hook afterChange permet de créer automatiquement des révisions à chaque mise à jour. Il s'exécute après la sauvegarde et a accès à l'instance payload complète.

Contrôle d'accès granulaire

access/isAdminOrSelf.ts
import { Access } from 'payload/config'
export const isAdminOrSelf: Access = ({ req: { user } }) => {
  if (!user) return false
  if (user.role === 'admin') return true
  return { id: { equals: user.id } }
}

Cette fonction d'accès réutilisable vérifie le rôle ou l'identité de l'utilisateur. Elle retourne soit true, false ou une contrainte MongoDB pour filtrer les documents.

Bonnes pratiques

  • Toujours typer les hooks avec les types générés par Payload
  • Séparer les règles d'accès dans des fichiers dédiés pour la réutilisabilité
  • Utiliser les hooks beforeValidate pour la validation métier complexe
  • Versionner les collections critiques avec un champ revisionNumber
  • Configurer les CORS et les headers de sécurité dès le développement

Erreurs courantes à éviter

  • Oublier de régénérer les types après modification des collections
  • Utiliser des hooks async sans await sur les opérations payload
  • Définir des access rules contradictoires entre admin et API
  • Négliger la configuration des médias et du stockage S3 en production

Pour aller plus loin

Approfondissez l'écosystème Payload avec nos formations Learni dédiées aux CMS headless et à l'architecture TypeScript avancée.