Payload comes with a built-in Plugins infrastructure that allows developers to build their own modular and easily reusable sets of functionality.
Writing plugins is no more complex than writing regular JavaScript. If you know how spread syntax works and are up to speed with Payload concepts, writing a plugin will be a breeze.
Example use cases:
upload
-enabled collections with a third-party file host like S3 or CloudinaryThe base Payload config allows for a plugins
property which takes an array
of Plugin
s.
import { buildConfig } from 'payload/config';// note: these plugins are not real (yet?)import addLastModified from 'payload-add-last-modified';import passwordProtect from 'payload-password-protect';const config = buildConfig({collections: [{slug: 'pages',fields: [{name: 'title',type: 'text',required: true,},{name: 'content',type: 'richText',required: true,}]}],plugins: [// Many plugins require options to be passed.// In the following example, we call the function// and pass it options accordinglypasswordProtect(['pages']),// This plugin takes no options and just// needs to be passed directlyaddLastModified,// ..// To understand how to use the plugins you're interested in,// consult their corresponding documentation]});export default config;
Payload Plugins are executed after the incoming config is validated, but before it is sanitized and had default options merged in.
After all plugins are executed, the full config with all plugins will be sanitized.
Here is an example for how to automatically add a lastModifiedBy
field to all Payload collections using a Plugin written in TypeScript.
import { Config } from 'payload/config';import { CollectionConfig } from 'payload/dist/collections/config/types';const addLastModified = (incomingConfig: Config): Config => {// Find all incoming auth-enabled collections// so we can create a lastModifiedBy relationship field// to all auth collectionsconst authEnabledCollections = incomingConfig.collections.filter(collection => Boolean(collection.auth));// Spread the existing configconst config: Config = {...incomingConfig,collections: incomingConfig.collections.map((collection) => {// Spread each item that we are modifying,// and add our new field - complete with// hooks and proper admin UI configreturn {...collection,fields: [...collection.fields,{name: 'lastModifiedBy',type: 'relationship',relationTo: authEnabledCollections.map(({ slug }) => slug),hooks: {beforeChange: [({ req }) => ({value: req?.user?.id,relationTo: req?.user?.collection,}),]},admin: {position: 'sidebar',readOnly: true,},},],};}),};return config;};export default addLastModified;
This page will be updated with more examples in the future, and we will be maintaining a list of both official and community Payload plugins on our website very soon.
In the meantime, if you have built a plugin, or if you would like one to be built by the core Payload team, open a Feature Request in our GitHub Discussions board. We would be happy to review your code and maybe feature you and your plugin on our website.