150 lines
5.3 KiB
Plaintext
150 lines
5.3 KiB
Plaintext
---
|
|
title: Plugins
|
|
label: Overview
|
|
order: 10
|
|
desc: Plugins provide a great way to modularize Payload functionalities into easy-to-use enhancements and extensions of your Payload apps.
|
|
keywords: plugins, config, configuration, extensions, custom, documentation, Content Management System, cms, headless, javascript, node, react, express
|
|
---
|
|
|
|
Payload comes with a built-in Plugins infrastructure that allows developers to build their own modular and easily reusable sets of functionality.
|
|
|
|
<Banner type="success">
|
|
Because we rely on a simple config-based structure, Payload plugins simply take in a user's
|
|
existing config and return a modified config with new fields, hooks, collections, admin views, or
|
|
anything else you can think of.
|
|
</Banner>
|
|
|
|
Writing plugins is no more complex than writing regular JavaScript. If you know how [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) works and are up to speed with Payload concepts, writing a plugin will be a breeze.
|
|
|
|
**Example use cases:**
|
|
|
|
- Automatically sync data from a specific collection to HubSpot or a similar CRM when data is added or changes
|
|
- Add password-protection functionality to certain documents
|
|
- Add a full e-commerce backend to any Payload app
|
|
- Add custom reporting views to Payload's admin panel
|
|
- Encrypt specific collections' data
|
|
- Add a full form builder implementation
|
|
- Integrate all `upload`-enabled collections with a third-party file host like S3 or Cloudinary
|
|
- Add custom endpoints or GraphQL queries / mutations with any type of custom functionality that you can think of
|
|
|
|
## How to install plugins
|
|
|
|
The base Payload config allows for a `plugins` property which takes an `array` of [`Plugins`](https://github.com/payloadcms/payload/blob/main/packages/payload/src/config/types.ts).
|
|
|
|
```js
|
|
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'
|
|
import { mongooseAdapter } from '@payloadcms/db-mongodb'
|
|
import { postgresAdapter } from '@payloadcms/db-postgres'
|
|
|
|
import { viteBundler } from '@payloadcms/bundler-vite'
|
|
import { webpackBundler } from '@payloadcms/bundler-webpack'
|
|
|
|
|
|
const config = buildConfig({
|
|
bundler: webpackBundler() // or viteBundler(),
|
|
collections: [
|
|
{
|
|
slug: 'pages',
|
|
fields: [
|
|
{
|
|
name: 'title',
|
|
type: 'text',
|
|
required: true,
|
|
},
|
|
{
|
|
name: 'content',
|
|
type: 'richText',
|
|
required: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
db: mongooseAdapter({}) // or postgresAdapter({})
|
|
plugins: [
|
|
// Many plugins require options to be passed.
|
|
// In the following example, we call the function
|
|
// and pass it options accordingly
|
|
passwordProtect(['pages']),
|
|
|
|
// This plugin takes no options and just
|
|
// needs to be passed directly
|
|
addLastModified,
|
|
|
|
// ..
|
|
// To understand how to use the plugins you're interested in,
|
|
// consult their corresponding documentation
|
|
],
|
|
})
|
|
|
|
export default config
|
|
```
|
|
|
|
### When Plugins are initialized
|
|
|
|
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.
|
|
|
|
## Simple example
|
|
|
|
Here is an example for how to automatically add a `lastModifiedBy` field to all Payload collections using a Plugin written in TypeScript.
|
|
|
|
```ts
|
|
import { Config, Plugin } from 'payload/config'
|
|
|
|
const addLastModified: Plugin = (incomingConfig: Config): Config => {
|
|
// Find all incoming auth-enabled collections
|
|
// so we can create a lastModifiedBy relationship field
|
|
// to all auth collections
|
|
const authEnabledCollections = incomingConfig.collections.filter((collection) =>
|
|
Boolean(collection.auth),
|
|
)
|
|
|
|
// Spread the existing config
|
|
const 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 config
|
|
return {
|
|
...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
|
|
```
|
|
|
|
## Available Plugins
|
|
|
|
You can discover existing plugins by browsing the `payload-plugin` topic on [GitHub](https://github.com/topics/payload-plugin).
|
|
|
|
For maintainers building plugins for others to use, please add the topic to help others find it. If you would like one to be built by the core Payload team, [open a Feature Request](https://github.com/payloadcms/payload/discussions) in our GitHub Discussions board. We would be happy to review your code and maybe feature you and your plugin where appropriate.
|