feat: adds meta descriptions to docs

This commit is contained in:
Jessica Boezwinkle
2021-02-03 16:55:22 -05:00
parent 3bd0de0a0b
commit da61feb73b
52 changed files with 1350 additions and 1129 deletions

View File

@@ -2,7 +2,7 @@
title: Swap in your own React components title: Swap in your own React components
label: Custom Components label: Custom Components
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: Fully customize your Admin Panel by swapping in your own React components. Add fields, remove views, update routes and change functions to sculpt your perfect Dashboard.
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -11,31 +11,40 @@ While designing the Payload Admin panel, we determined it should be as minimal a
To swap in your own React component, first, consult the list of available component overrides below. Determine the scope that corresponds to what you are trying to accomplish, and then author your React component accordingly. To swap in your own React component, first, consult the list of available component overrides below. Determine the scope that corresponds to what you are trying to accomplish, and then author your React component accordingly.
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br/> <strong>Tip:</strong>
Custom components will automatically be provided with all props that the default component would accept. <br />
Custom components will automatically be provided with all props that the
default component would accept.
</Banner> </Banner>
### Base Component Overrides ### Base Component Overrides
You can override a set of admin panel-wide components by providing a component to your base Payload config's `admin.components` property. The following options are available: You can override a set of admin panel-wide components by providing a component to your base Payload config's `admin.components` property. The following options are available:
| Path | Description | | Path | Description |
| --------------------- | -------------| | --------------------- | -------------------------------------------------------------------------------------------------- |
| **`Nav`** | Contains the sidebar and mobile Nav in its entirety. | | **`Nav`** | Contains the sidebar and mobile Nav in its entirety. |
| **`views.Account`** | The Account view is used to show the currently logged in user's Account page. | | **`views.Account`** | The Account view is used to show the currently logged in user's Account page. |
| **`views.Dashboard`** | The main landing page of the Admin panel. | | **`views.Dashboard`** | The main landing page of the Admin panel. |
| **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. | | **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. |
| **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. | | **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. |
#### Full example: #### Full example:
`payload.config.js` `payload.config.js`
```js ```js
import { buildConfig } from 'payload/config'; import { buildConfig } from "payload/config";
import { MyCustomNav, MyCustomLogo, MyCustomIcon, MyCustomAccount, MyCustomDashboard } from './customComponents.js'; import {
MyCustomNav,
MyCustomLogo,
MyCustomIcon,
MyCustomAccount,
MyCustomDashboard,
} from "./customComponents.js";
export default buildConfig({ export default buildConfig({
serverURL: 'http://localhost:3000', serverURL: "http://localhost:3000",
admin: { admin: {
components: { components: {
Nav: MyCustomNav, Nav: MyCustomNav,
@@ -46,63 +55,62 @@ export default buildConfig({
views: { views: {
Account: MyCustomAccount, Account: MyCustomAccount,
Dashboard: MyCustomDashboard, Dashboard: MyCustomDashboard,
} },
} },
} },
}) });
``` ```
*For more examples regarding how to customize components, look at the [demo app](https://github.com/payloadcms/payload/tree/master/demo).* _For more examples regarding how to customize components, look at the [demo app](https://github.com/payloadcms/payload/tree/master/demo)._
### Collections ### Collections
You can override components on a Collection-by-Collection basis via each Collection's `admin` property. You can override components on a Collection-by-Collection basis via each Collection's `admin` property.
| Path | Description | | Path | Description |
| ---------------- | -------------| | ---------------- | ------------------------------------------------------------------------------------------------ |
| **`views.Edit`** | Used while a document within this Collection is being edited. | | **`views.Edit`** | Used while a document within this Collection is being edited. |
| **`views.List`** | The `List` view is used to render a paginated, filterable table of Documents in this Collection. | | **`views.List`** | The `List` view is used to render a paginated, filterable table of Documents in this Collection. |
### Globals ### Globals
As with Collections, You can override components on a global-by-global basis via their `admin` property. As with Collections, You can override components on a global-by-global basis via their `admin` property.
| Path | Description | | Path | Description |
| ---------------- | -------------| | ---------------- | --------------------------------------- |
| **`views.Edit`** | Used while this Global is being edited. | | **`views.Edit`** | Used while this Global is being edited. |
### Fields ### Fields
All Payload fields support the ability to swap in your own React components. So, for example, instead of rendering a default Text input, you might need to render a color picker that provides the editor with a custom color picker interface to restrict the data entered to colors only. All Payload fields support the ability to swap in your own React components. So, for example, instead of rendering a default Text input, you might need to render a color picker that provides the editor with a custom color picker interface to restrict the data entered to colors only.
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br/> <strong>Tip:</strong>
Don't see a built-in field type that you need? Build it! Using a combination of custom validation and custom components, you can override the entirety of how a component functions within the admin panel and effectively create your own field type. <br />
Don't see a built-in field type that you need? Build it! Using a combination
of custom validation and custom components, you can override the entirety of
how a component functions within the admin panel and effectively create your
own field type.
</Banner> </Banner>
**Fields support the following custom components:** **Fields support the following custom components:**
| Component | Description | | Component | Description |
| --------------- | -------------| | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
| **`Filter`** | Override the text input that is presented in the `List` view when a user is filtering documents by the customized field. | | **`Filter`** | Override the text input that is presented in the `List` view when a user is filtering documents by the customized field. |
| **`Cell`** | Used in the `List` view's table to represent a table-based preview of the data stored in the field. | | **`Cell`** | Used in the `List` view's table to represent a table-based preview of the data stored in the field. |
| **`Field`** | Swap out the field itself within all `Edit` views. | | **`Field`** | Swap out the field itself within all `Edit` views. |
#### Sending and receiving values from the form #### Sending and receiving values from the form
When swapping out the `Field` component, you'll be responsible for sending and receiving the field's `value` from the form itself. To do so, import the `useFieldType` hook as follows: When swapping out the `Field` component, you'll be responsible for sending and receiving the field's `value` from the form itself. To do so, import the `useFieldType` hook as follows:
```js ```js
import { useFieldType } from 'payload/components/forms'; import { useFieldType } from "payload/components/forms";
const CustomTextField = ({ path }) => { const CustomTextField = ({ path }) => {
const { value, setValue } = useFieldType({ path }); const { value, setValue } = useFieldType({ path });
return ( return <input onChange={(e) => setValue(e.target.value)} value={value} />;
<input };
onChange={(e) => setValue(e.target.value)}
value={value}
/>
)
}
``` ```

View File

@@ -2,7 +2,7 @@
title: Customizing CSS & SCSS title: Customizing CSS & SCSS
label: Customizing CSS label: Customizing CSS
order: 30 order: 30
desc: Payload is a headless CMS and application framework. desc: Customize your Payload admin panel further by adding your own CSS or SCSS style sheet to the configuration, powerful theme and design options are waiting for you.
keywords: admin, css, scss, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: admin, css, scss, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---

View File

@@ -2,7 +2,7 @@
title: The Admin Panel title: The Admin Panel
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Manage your data and customize the Admin Panel by swapping in your own React components. Create, modify or remove views, fields, styles and much more.
keywords: admin, components, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: admin, components, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -11,48 +11,52 @@ Payload dynamically generates a beautiful, fully functional React admin panel to
The Payload Admin panel is built with Webpack, code-split, highly performant (even with 100+ fields), and written fully in TypeScript. The Payload Admin panel is built with Webpack, code-split, highly performant (even with 100+ fields), and written fully in TypeScript.
<Banner type="success"> <Banner type="success">
The Admin panel is meant to be simple enough to give you a starting point but not bring too much complexity, so that you can easily customize it to suit the needs of your application and your editors. The Admin panel is meant to be simple enough to give you a starting point but
not bring too much complexity, so that you can easily customize it to suit the
needs of your application and your editors.
</Banner> </Banner>
![Payload's Admin panel built in React](https://payloadcms.com/images/admin.jpg) ![Payload's Admin panel built in React](https://payloadcms.com/images/admin.jpg)
*Screenshot of the Admin panel while editing a document from an example `AllFields` collection* _Screenshot of the Admin panel while editing a document from an example `AllFields` collection_
## Admin Options ## Admin Options
All options for the Admin panel are defined in your base Payload config file. All options for the Admin panel are defined in your base Payload config file.
| Option | Description | | Option | Description |
| -------------------- | -------------| | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `user` | The `slug` of a Collection that you want be used to log in to the Admin dashboard. [More](/docs/admin/overview#the-admin-user-collection) | | `user` | The `slug` of a Collection that you want be used to log in to the Admin dashboard. [More](/docs/admin/overview#the-admin-user-collection) |
| `meta` | Base meta data to use for the Admin panel. Included properties are `titleSuffix`, `ogImage`, and `favicon`. | | `meta` | Base meta data to use for the Admin panel. Included properties are `titleSuffix`, `ogImage`, and `favicon`. |
| `disable` | If set to `true`, the entire Admin panel will be disabled. | | `disable` | If set to `true`, the entire Admin panel will be disabled. |
| `indexHTML` | Optionally replace the entirety of the `index.html` file used by the Admin panel. Reference the [base index.html file](https://github.com/payloadcms/payload/blob/master/src/admin/index.html) to ensure your replacement has the appropriate HTML elements. | | `indexHTML` | Optionally replace the entirety of the `index.html` file used by the Admin panel. Reference the [base index.html file](https://github.com/payloadcms/payload/blob/master/src/admin/index.html) to ensure your replacement has the appropriate HTML elements. |
| `css` | Absolute path to a stylesheet that you can use to override / customize the Admin panel styling. [More](/docs/admin/customizing-css). | | `css` | Absolute path to a stylesheet that you can use to override / customize the Admin panel styling. [More](/docs/admin/customizing-css). |
| `scss` | Absolute path to a Sass variables / mixins stylesheet meant to override Payload styles to make for an easy re-skinning of the Admin panel. [More](/docs/admin/customizing-css#overriding-scss-variables). | | `scss` | Absolute path to a Sass variables / mixins stylesheet meant to override Payload styles to make for an easy re-skinning of the Admin panel. [More](/docs/admin/customizing-css#overriding-scss-variables). |
| `components` | Component overrides that affect the entirety of the Admin panel. [More](/docs/admin/components) | | `components` | Component overrides that affect the entirety of the Admin panel. [More](/docs/admin/components) |
| `webpack` | Customize the Webpack config that's used to generate the Admin panel. [More](/docs/admin/webpack) | | `webpack` | Customize the Webpack config that's used to generate the Admin panel. [More](/docs/admin/webpack) |
### The Admin User Collection ### The Admin User Collection
<Banner type="warning"> <Banner type="warning">
<strong>Important:</strong><br /> <strong>Important:</strong>
The Payload Admin panel can only be used by one Collection that supports <a href="/docs/authentication/">Authentication</a>. <br />
The Payload Admin panel can only be used by one Collection that supports{" "}
<a href="/docs/authentication/">Authentication</a>.
</Banner> </Banner>
To specify which Collection to use to log in to the Admin panel, pass the `admin` options a `user` key equal to the slug of the Collection that you'd like to use. To specify which Collection to use to log in to the Admin panel, pass the `admin` options a `user` key equal to the slug of the Collection that you'd like to use.
`payload.config.js`: `payload.config.js`:
```js ```js
import { buildConfig } from 'payload/config'; import { buildConfig } from "payload/config";
const config = buildConfig({ const config = buildConfig({
serverURL: 'http://localhost:3000', serverURL: "http://localhost:3000",
admin: { admin: {
user: 'admins', // highlight-line user: "admins", // highlight-line
}, },
}) });
``` ```
By default, if you have not specified a Collection, Payload will automatically provide you with a `User` Collection which will be used to access the Admin panel. You can customize or override the fields and settings of the default `User` Collection by passing your own collection using `users` as its `slug` to Payload. When this is done, Payload will use your provided `User` Collection instead of its default version. By default, if you have not specified a Collection, Payload will automatically provide you with a `User` Collection which will be used to access the Admin panel. You can customize or override the fields and settings of the default `User` Collection by passing your own collection using `users` as its `slug` to Payload. When this is done, Payload will use your provided `User` Collection instead of its default version.

View File

@@ -2,7 +2,7 @@
title: Webpack title: Webpack
label: Webpack label: Webpack
order: 40 order: 40
desc: Payload is a headless CMS and application framework. desc: The Payload admin panel uses Webpack 5 and supports many common functionalities such as SCSS and Typescript out of the box to give you more freedom.
keywords: admin, webpack, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: admin, webpack, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---

View File

@@ -2,7 +2,7 @@
title: Collection Access Control title: Collection Access Control
label: Collections label: Collections
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: With Collection-level Access Control you can define which users can create, read, update or delete Collections.
keywords: collections, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: collections, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -10,23 +10,24 @@ You can define Collection-level Access Control within each Collection's `access`
## Available Controls ## Available Controls
| Function | Allows/Denies Access | | Function | Allows/Denies Access |
| ------------------------ | -------------------- | | ----------------------- | -------------------------------------------- |
| **[`create`](#create)** | Used in the `create` operation | | **[`create`](#create)** | Used in the `create` operation |
| **[`read`](#read)** | Used in the `find` and `findByID` operations | | **[`read`](#read)** | Used in the `find` and `findByID` operations |
| **[`update`](#update)** | Used in the `update` operation | | **[`update`](#update)** | Used in the `update` operation |
| **[`delete`](#delete)** | Used in the `delete` operation | | **[`delete`](#delete)** | Used in the `delete` operation |
#### Auth-enabled Controls #### Auth-enabled Controls
If a Collection supports [`Authentication`](/docs/authentication/overview), the following Access Controls become available: If a Collection supports [`Authentication`](/docs/authentication/overview), the following Access Controls become available:
| Function | Allows/Denies Access | | Function | Allows/Denies Access |
| ----------------------- | -------------------- | | ----------------------- | -------------------------------------------------------------- |
| **[`admin`](#admin)** | Used to restrict access to the Payload Admin panel | | **[`admin`](#admin)** | Used to restrict access to the Payload Admin panel |
| **[`unlock`](#unlock)** | Used to restrict which users can access the `unlock` operation | | **[`unlock`](#unlock)** | Used to restrict which users can access the `unlock` operation |
**Example Collection config:** **Example Collection config:**
```js ```js
export default { export default {
slug: "posts", slug: "posts",
@@ -48,8 +49,8 @@ Returns a boolean which allows/denies access to the `create` request.
**Available argument properties :** **Available argument properties :**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |
### Read ### Read
@@ -58,9 +59,9 @@ Read access functions can return a boolean result or optionally return a [query
**Available argument properties :** **Available argument properties :**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | ------------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`id`** | `id` of document requested, if within `findByID`. Otherwise, `id` is undefined. | | **`id`** | `id` of document requested, if within `findByID`. Otherwise, `id` is undefined. |
### Update ### Update
@@ -69,10 +70,10 @@ Update access functions can return a boolean result or optionally return a [quer
**Available argument properties :** **Available argument properties :**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`id`** | `id` of document requested to update | | **`id`** | `id` of document requested to update |
### Delete ### Delete
@@ -80,10 +81,10 @@ Similarly to the Update function, returns a boolean or a [query constraint](/doc
**Available argument properties :** **Available argument properties :**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | --------------------------------------------------------------------------------------------------- |
| **`req`** | The Express `request` object with additional `user` property, which is the currently logged in user | | **`req`** | The Express `request` object with additional `user` property, which is the currently logged in user |
| **`id`** | `id` of document requested to delete | | **`id`** | `id` of document requested to delete |
### Admin ### Admin
@@ -91,8 +92,8 @@ If the Collection is [used to access the Payload Admin panel](/docs/admin/overvi
**Available argument properties :** **Available argument properties :**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |
### Unlock ### Unlock
@@ -101,6 +102,6 @@ Determines which users can [unlock](/docs/authentication/operations#unlock) othe
**Available argument properties :** **Available argument properties :**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |

View File

@@ -2,7 +2,7 @@
title: Field-level Access Control title: Field-level Access Control
label: Fields label: Fields
order: 30 order: 30
desc: Payload is a headless CMS and application framework. desc: Field-level Access Control is specified within a field's config, and allows you to define which users can create, read or update Fields.
keywords: fields, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: fields, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -10,13 +10,14 @@ Field Access Control is specified with functions inside a field's config. All fi
## Available Controls ## Available Controls
| Function | Purpose | | Function | Purpose |
| ------------------------ | ------- | | ----------------------- | -------------------------------------------------------------------------------- |
| **[`create`](#create)** | Allows or denies the ability to set a field's value when creating a new document | | **[`create`](#create)** | Allows or denies the ability to set a field's value when creating a new document |
| **[`read`](#read)** | Allows or denies the ability to read a field's value | | **[`read`](#read)** | Allows or denies the ability to read a field's value |
| **[`update`](#update)** | Allows or denies the ability to update a field's value | | **[`update`](#update)** | Allows or denies the ability to update a field's value |
**Example Collection config:** **Example Collection config:**
```js ```js
export default { export default {
slug: 'posts', slug: 'posts',
@@ -43,8 +44,8 @@ Returns a boolean which allows or denies the ability to set a field's value when
**Available argument properties:** **Available argument properties:**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |
### Read ### Read
@@ -53,10 +54,10 @@ Returns a boolean which allows or denies the ability to read a field's value. If
**Available argument properties:** **Available argument properties:**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`id`** | `id` of the document being read | | **`id`** | `id` of the document being read |
### Update ### Update
@@ -64,7 +65,7 @@ Returns a boolean which allows or denies the ability to update a field's value.
**Available argument properties:** **Available argument properties:**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`id`** | `id` of the document being updated | | **`id`** | `id` of the document being updated |

View File

@@ -2,22 +2,23 @@
title: Globals Access Control title: Globals Access Control
label: Globals label: Globals
order: 40 order: 40
desc: Payload is a headless CMS and application framework. desc: Global-level Access Control is specified within each Global's `access` property and allows you to define which users can read or update Globals.
keywords: globals, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: globals, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
You can define Global-level Access Control within each Global's `access` property. All Access Control functions accept one `args` argument. You can define Global-level Access Control within each Global's `access` property. All Access Control functions accept one `args` argument.
**Available argument properties: \*\*Available argument properties:
## Available Controls ## Available Controls
| Function | Allows/Denies Access | | Function | Allows/Denies Access |
| ------------------------ | -------------------- | | ----------------------- | -------------------------------------- |
| **[`read`](#read)** | Used in the `findOne` Global operation | | **[`read`](#read)** | Used in the `findOne` Global operation |
| **[`update`](#update)** | Used in the `update` Global operation | | **[`update`](#update)** | Used in the `update` Global operation |
**Example Global config:** **Example Global config:**
```js ```js
export default { export default {
slug: "header", slug: "header",
@@ -36,8 +37,8 @@ Returns a boolean result to allow or deny a user's ability to read the Global.
**Available argument properties:** **Available argument properties:**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |
### Update ### Update
@@ -46,6 +47,6 @@ Returns a boolean result to allow or deny a user's ability to update the Global.
**Available argument properties:** **Available argument properties:**
| Option | Description | | Option | Description |
| --------- | ----------- | | --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` | | **`req`** | The Express `request` object containing the currently authenticated `user` |

View File

@@ -2,7 +2,7 @@
title: Access Control title: Access Control
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Payload makes it simple to define and manage access control. By declaring roles, you can set permissions and restrict what your users can interact with.
keywords: overview, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: overview, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -28,12 +28,15 @@ const defaultPayloadAccess = ({ req: { user } }) => {
// Return `true` if a user is found // Return `true` if a user is found
// and `false` if it is undefined or null // and `false` if it is undefined or null
return Boolean(user); return Boolean(user);
} };
``` ```
<Banner type="success"> <Banner type="success">
<strong>Note:</strong><br/> <strong>Note:</strong>
In the Local API, all Access Control functions are skipped by default, allowing your server to do whatever it needs. But, you can opt back in by setting the option <strong>overrideAccess</strong> to <strong>true</strong>. <br />
In the Local API, all Access Control functions are skipped by default,
allowing your server to do whatever it needs. But, you can opt back in by
setting the option <strong>overrideAccess</strong> to <strong>true</strong>.
</Banner> </Banner>
### Access Control Types ### Access Control Types

View File

@@ -2,7 +2,7 @@
title: Authentication Config title: Authentication Config
label: Config label: Config
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: Enable and customize options in the Authentication config for features including Forgot Password, Login Attempts, API key usage and more.
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -12,16 +12,16 @@ To enable Authentication on a collection, define an `auth` property and set it t
## Options ## Options
| Option | Description | | Option | Description |
| ---------------------- | -------------| | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`useAPIKey`** | Payload Authentication provides for API keys to be set on each user within an Authentication-enabled Collection. [More](/docs/authentication/config#api-keys) | | **`useAPIKey`** | Payload Authentication provides for API keys to be set on each user within an Authentication-enabled Collection. [More](/docs/authentication/config#api-keys) |
| **`tokenExpiration`** | How long (in seconds) to keep the user logged in. JWTs and HTTP-only cookies will both expire at the same time. | | **`tokenExpiration`** | How long (in seconds) to keep the user logged in. JWTs and HTTP-only cookies will both expire at the same time. |
| **`maxLoginAttempts`** | Only allow a user to attempt logging in X amount of times. Automatically locks out a user from authenticating if this limit is passed. Set to `0` to disable. | | **`maxLoginAttempts`** | Only allow a user to attempt logging in X amount of times. Automatically locks out a user from authenticating if this limit is passed. Set to `0` to disable. |
| **`lockTime`** | Set the time that a user should be locked out if they fail authentication more times than `maxLoginAttempts` allows for. | | **`lockTime`** | Set the time that a user should be locked out if they fail authentication more times than `maxLoginAttempts` allows for. |
| **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the express `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. | | **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the express `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. |
| **`cookies`** | Set cookie options, including `secure`, `sameSite`, and `domain`. For advanced users. | | **`cookies`** | Set cookie options, including `secure`, `sameSite`, and `domain`. For advanced users. |
| **`forgotPassword`** | Customize the way that the `forgotPassword` operation functions. [More](/docs/authentication/config#forgot-password) | | **`forgotPassword`** | Customize the way that the `forgotPassword` operation functions. [More](/docs/authentication/config#forgot-password) |
| **`verify`** | Set to `true` or pass an object with verification options to require users to verify by email before they are allowed to log into your app. [More](/docs/authentication/config#email-verification) | | **`verify`** | Set to `true` or pass an object with verification options to require users to verify by email before they are allowed to log into your app. [More](/docs/authentication/config#email-verification) |
### API keys ### API keys
@@ -37,7 +37,8 @@ Technically, both of these options will work for third-party integrations but th
To enable API keys on a collection, set the `useAPIKey` auth option to `true`. From there, a new interface will appear in the Admin panel for each document within the collection that allows you to generate an API key for each user in the Collection. To enable API keys on a collection, set the `useAPIKey` auth option to `true`. From there, a new interface will appear in the Admin panel for each document within the collection that allows you to generate an API key for each user in the Collection.
<Banner type="success"> <Banner type="success">
User API keys are encrypted within the database, meaning that if your database is compromised, your API keys will not be. User API keys are encrypted within the database, meaning that if your database
is compromised, your API keys will not be.
</Banner> </Banner>
##### Authenticating via API Key ##### Authenticating via API Key
@@ -45,8 +46,9 @@ To enable API keys on a collection, set the `useAPIKey` auth option to `true`. F
To utilize your API key while interacting with the REST or GraphQL API, add the `Authorization` header. To utilize your API key while interacting with the REST or GraphQL API, add the `Authorization` header.
**For example, using Fetch:** **For example, using Fetch:**
```js ```js
const response = await fetch('http://localhost:3000/api/pages', { const response = await fetch("http://localhost:3000/api/pages", {
headers: { headers: {
Authorization: `${collection.labels.singular} API-Key ${YOUR_API_KEY}`, Authorization: `${collection.labels.singular} API-Key ${YOUR_API_KEY}`,
}, },
@@ -62,8 +64,13 @@ You can customize how the Forgot Password workflow operates with the following o
Function that accepts one argument, containing `{ req, token, user }`, that allows for overriding the HTML within emails that are sent to users attempting to reset their password. The function should return a string that supports HTML, which can be a full HTML email. Function that accepts one argument, containing `{ req, token, user }`, that allows for overriding the HTML within emails that are sent to users attempting to reset their password. The function should return a string that supports HTML, which can be a full HTML email.
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br /> <strong>Tip:</strong>
HTML templating can be used to create custom email templates, inline CSS automatically, and more. You can make a reusable function that standardizes all email sent from Payload, which makes sending custom emails more DRY. Payload doesn't ship with an HTML templating engine, so you are free to choose your own. <br />
HTML templating can be used to create custom email templates, inline CSS
automatically, and more. You can make a reusable function that standardizes
all email sent from Payload, which makes sending custom emails more DRY.
Payload doesn't ship with an HTML templating engine, so you are free to choose
your own.
</Banner> </Banner>
Example: Example:
@@ -99,8 +106,13 @@ Example:
``` ```
<Banner type="warning"> <Banner type="warning">
<strong>Important:</strong><br /> <strong>Important:</strong>
If you specify a different URL to send your users to for resetting their password, such as a page on the frontend of your app or similar, you need to handle making the call to the Payload REST or GraphQL reset-password operation yourself on your frontend, using the token that was provided for you. Above, it was passed via query parameter. <br />
If you specify a different URL to send your users to for resetting their
password, such as a page on the frontend of your app or similar, you need to
handle making the call to the Payload REST or GraphQL reset-password operation
yourself on your frontend, using the token that was provided for you. Above,
it was passed via query parameter.
</Banner> </Banner>
**`generateEmailSubject`** **`generateEmailSubject`**
@@ -153,8 +165,13 @@ Example:
``` ```
<Banner type="warning"> <Banner type="warning">
<strong>Important:</strong><br /> <strong>Important:</strong>
If you specify a different URL to send your users to for email verification, such as a page on the frontend of your app or similar, you need to handle making the call to the Payload REST or GraphQL verification operation yourself on your frontend, using the token that was provided for you. Above, it was passed via query parameter. <br />
If you specify a different URL to send your users to for email verification,
such as a page on the frontend of your app or similar, you need to handle
making the call to the Payload REST or GraphQL verification operation yourself
on your frontend, using the token that was provided for you. Above, it was
passed via query parameter.
</Banner> </Banner>
**`generateEmailSubject`** **`generateEmailSubject`**

View File

@@ -2,7 +2,7 @@
title: Authentication Operations title: Authentication Operations
label: Operations label: Operations
order: 30 order: 30
desc: Payload is a headless CMS and application framework. desc: Enabling Authentication automatically makes key operations available such as Login, Logout, Verify, Unlock, Reset Password and more.
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -17,6 +17,7 @@ The Access operation returns what a logged in user can and can't do with the col
`GET http://localhost:3000/api/access` `GET http://localhost:3000/api/access`
Example response: Example response:
```js ```js
{ {
canAccessAdmin: true, canAccessAdmin: true,
@@ -76,6 +77,7 @@ Returns either a logged in user with token or null when there is no logged in us
`GET http://localhost:3000/api/[collection-slug]/me` `GET http://localhost:3000/api/[collection-slug]/me`
Example response: Example response:
```js ```js
{ {
user: { // The JWT "payload" ;) from the logged in user user: { // The JWT "payload" ;) from the logged in user
@@ -107,17 +109,18 @@ query {
Accepts an `email` and `password`. On success, it will return the logged in user as well as a token that can be used to authenticate. In the GraphQL and REST APIs, this operation also automatically sets an HTTP-only cookie including the user's token. If you pass an Express `res` to the Local API operation, Payload will set a cookie there as well. Accepts an `email` and `password`. On success, it will return the logged in user as well as a token that can be used to authenticate. In the GraphQL and REST APIs, this operation also automatically sets an HTTP-only cookie including the user's token. If you pass an Express `res` to the Local API operation, Payload will set a cookie there as well.
**Example REST API login**: **Example REST API login**:
```js ```js
const res = await fetch('http://localhost:3000/api/[collection-slug]/login', { const res = await fetch("http://localhost:3000/api/[collection-slug]/login", {
method: 'POST', method: "POST",
headers: { headers: {
'Content-Type': 'application/json', "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
email: 'dev@payloadcms.com', email: "dev@payloadcms.com",
password: 'this-is-not-our-password...or-is-it?', password: "this-is-not-our-password...or-is-it?",
}) }),
}) });
const json = await res.json(); const json = await res.json();
@@ -154,12 +157,12 @@ mutation {
```js ```js
const result = await payload.login({ const result = await payload.login({
collection: '[collection-slug]', collection: "[collection-slug]",
data: { data: {
email: 'dev@payloadcms.com', email: "dev@payloadcms.com",
password: 'get-out', password: "get-out",
}, },
}) });
``` ```
### Logout ### Logout
@@ -167,13 +170,14 @@ const result = await payload.login({
As Payload sets HTTP-only cookies, logging out cannot be done by just removing a cookie in JavaScript, as HTTP-only cookies are inaccessible by JS within the browser. So, Payload exposes a `logout` operation to delete the token in a safe way. As Payload sets HTTP-only cookies, logging out cannot be done by just removing a cookie in JavaScript, as HTTP-only cookies are inaccessible by JS within the browser. So, Payload exposes a `logout` operation to delete the token in a safe way.
**Example REST API logout**: **Example REST API logout**:
```js ```js
const res = await fetch('http://localhost:3000/api/[collection-slug]/logout', { const res = await fetch("http://localhost:3000/api/[collection-slug]/logout", {
method: 'POST', method: "POST",
headers: { headers: {
'Content-Type': 'application/json', "Content-Type": "application/json",
}, },
}) });
``` ```
**Example GraphQL Mutation**: **Example GraphQL Mutation**:
@@ -193,13 +197,14 @@ This operation requires a non-expired token to send back a new one. If the user'
If successful, this operation will automatically renew the user's HTTP-only cookie and will send back the updated token in JSON. If successful, this operation will automatically renew the user's HTTP-only cookie and will send back the updated token in JSON.
**Example REST API token refresh**: **Example REST API token refresh**:
```js ```js
const res = await fetch('http://localhost:3000/api/[collection-slug]/refresh', { const res = await fetch("http://localhost:3000/api/[collection-slug]/refresh", {
method: 'POST', method: "POST",
headers: { headers: {
'Content-Type': 'application/json', "Content-Type": "application/json",
}, },
}) });
const json = await res.json(); const json = await res.json();
@@ -232,7 +237,10 @@ mutation {
``` ```
<Banner type="success"> <Banner type="success">
The Refresh operation will automatically find the user's token in either a JWT header or the HTTP-only cookie. But, you can specify the token you're looking to refresh by providing the REST API with a `token` within the JSON body of the request, or by providing the GraphQL resolver a `token` arg. The Refresh operation will automatically find the user's token in either a JWT
header or the HTTP-only cookie. But, you can specify the token you're looking
to refresh by providing the REST API with a `token` within the JSON body of
the request, or by providing the GraphQL resolver a `token` arg.
</Banner> </Banner>
### Verify by Email ### Verify by Email
@@ -240,13 +248,17 @@ mutation {
If your collection supports email verification, the Verify operation will be exposed which accepts a verification token and sets the user's `_verified` property to `true`, thereby allowing the user to authenticate with the Payload API. If your collection supports email verification, the Verify operation will be exposed which accepts a verification token and sets the user's `_verified` property to `true`, thereby allowing the user to authenticate with the Payload API.
**Example REST API user verification**: **Example REST API user verification**:
```js ```js
const res = await fetch(`http://localhost:3000/api/[collection-slug]/verify/${TOKEN_HERE}`, { const res = await fetch(
method: 'POST', `http://localhost:3000/api/[collection-slug]/verify/${TOKEN_HERE}`,
headers: { {
'Content-Type': 'application/json', method: "POST",
}, headers: {
}) "Content-Type": "application/json",
},
}
);
``` ```
**Example GraphQL Mutation**: **Example GraphQL Mutation**:
@@ -261,9 +273,9 @@ mutation {
```js ```js
const result = await payload.verifyEmail({ const result = await payload.verifyEmail({
collection: '[collection-slug]', collection: "[collection-slug]",
token: 'TOKEN_HERE', token: "TOKEN_HERE",
}) });
``` ```
### Unlock ### Unlock
@@ -273,13 +285,14 @@ If a user locks themselves out and you wish to deliberately unlock them, you can
To restrict who is allowed to unlock users, you can utilize the [`unlock`](/docs/access-control/overview#unlock) access control function. To restrict who is allowed to unlock users, you can utilize the [`unlock`](/docs/access-control/overview#unlock) access control function.
**Example REST API unlock**: **Example REST API unlock**:
```js ```js
const res = await fetch(`http://localhost:3000/api/[collection-slug]/unlock`, { const res = await fetch(`http://localhost:3000/api/[collection-slug]/unlock`, {
method: 'POST', method: "POST",
headers: { headers: {
'Content-Type': 'application/json', "Content-Type": "application/json",
}, },
}) });
``` ```
**Example GraphQL Mutation**: **Example GraphQL Mutation**:
@@ -294,8 +307,8 @@ mutation {
```js ```js
const result = await payload.unlock({ const result = await payload.unlock({
collection: '[collection-slug]', collection: "[collection-slug]",
}) });
``` ```
### Forgot Password ### Forgot Password
@@ -307,16 +320,20 @@ The link to reset the user's password contains a token which is what allows the
By default, the Forgot Password operations send users to the Payload Admin panel to reset their password, but you can customize the generated email to send users to the frontend of your app instead by [overriding the email HTML](/docs/authentication/config#forgot-password). By default, the Forgot Password operations send users to the Payload Admin panel to reset their password, but you can customize the generated email to send users to the frontend of your app instead by [overriding the email HTML](/docs/authentication/config#forgot-password).
**Example REST API Forgot Password**: **Example REST API Forgot Password**:
```js ```js
const res = await fetch(`http://localhost:3000/api/[collection-slug]/forgot-password`, { const res = await fetch(
method: 'POST', `http://localhost:3000/api/[collection-slug]/forgot-password`,
headers: { {
'Content-Type': 'application/json', method: "POST",
}, headers: {
body: JSON.stringify({ "Content-Type": "application/json",
email: 'dev@payloadcms.com', },
}), body: JSON.stringify({
}) email: "dev@payloadcms.com",
}),
}
);
``` ```
**Example GraphQL Mutation**: **Example GraphQL Mutation**:
@@ -331,17 +348,23 @@ mutation {
```js ```js
const token = await payload.forgotPassword({ const token = await payload.forgotPassword({
collection: '[collection-slug]', collection: "[collection-slug]",
data: { data: {
email: 'dev@payloadcms.com', email: "dev@payloadcms.com",
}, },
disableEmail: false // you can disable the auto-generation of email via local API disableEmail: false, // you can disable the auto-generation of email via local API
}) });
``` ```
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br/> <strong>Tip:</strong>
You can stop the reset-password email from being sent via using the local API. This is helpful if you need to create user accounts programmatically, but not set their password for them. This effectively generates a reset password token which you can then use to send to a page you create, allowing a user to "complete" their account by setting their password. In the background, you'd use the token to "reset" their password. <br />
You can stop the reset-password email from being sent via using the local API.
This is helpful if you need to create user accounts programmatically, but not
set their password for them. This effectively generates a reset password token
which you can then use to send to a page you create, allowing a user to
"complete" their account by setting their password. In the background, you'd
use the token to "reset" their password.
</Banner> </Banner>
### Reset Password ### Reset Password
@@ -349,6 +372,7 @@ const token = await payload.forgotPassword({
After a user has "forgotten" their password and a token is generated, that token can be used to send to the reset password operation along with a new password which will allow the user to reset their password securely. After a user has "forgotten" their password and a token is generated, that token can be used to send to the reset password operation along with a new password which will allow the user to reset their password securely.
**Example REST API Reset Password**: **Example REST API Reset Password**:
```js ```js
const res = await fetch(`http://localhost:3000/api/[collection-slug]/reset-password`, { const res = await fetch(`http://localhost:3000/api/[collection-slug]/reset-password`, {
method: 'POST', method: 'POST',

View File

@@ -2,18 +2,19 @@
title: Authentication Overview title: Authentication Overview
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Payload provides highly secure user Authentication out of the box, and you can fully customize, override, or remove the default Authentication support.
keywords: authentication, config, configuration, overview, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: authentication, config, configuration, overview, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner> <Banner>
Payload provides for highly secure and customizable user Authentication out of the box, which allows for users to identify themselves to Payload. Payload provides for highly secure and customizable user Authentication out of
the box, which allows for users to identify themselves to Payload.
</Banner> </Banner>
Authentication is used within the Payload Admin panel itself as well as throughout your app(s) themselves however you determine necessary. Authentication is used within the Payload Admin panel itself as well as throughout your app(s) themselves however you determine necessary.
![Authentication admin panel functionality](https://payloadcms.com/images/auth-admin.jpg) ![Authentication admin panel functionality](https://payloadcms.com/images/auth-admin.jpg)
*Admin panel screenshot depicting an Admins Collection with Auth enabled* _Admin panel screenshot depicting an Admins Collection with Auth enabled_
**Here are some common use cases of Authentication outside of Payload's dashboard itself:** **Here are some common use cases of Authentication outside of Payload's dashboard itself:**
@@ -77,8 +78,11 @@ Once enabled, each document that is created within the Collection can be thought
Successfully logging in returns a `JWT` (JSON web token) which is how a user will identify themselves to Payload. By providing this JWT via either an HTTP-only cookie or an `Authorization` header, Payload will automatically identify the user and add its user JWT data to the Express `req`, which is available throughout Payload including within access control, hooks, and more. Successfully logging in returns a `JWT` (JSON web token) which is how a user will identify themselves to Payload. By providing this JWT via either an HTTP-only cookie or an `Authorization` header, Payload will automatically identify the user and add its user JWT data to the Express `req`, which is available throughout Payload including within access control, hooks, and more.
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br/> <strong>Tip:</strong>
You can access the logged in user from access control functions and hooks via the Express <strong>req</strong>. The logged in user is automatically added as the <strong>user</strong> property. <br />
You can access the logged in user from access control functions and hooks via
the Express <strong>req</strong>. The logged in user is automatically added as
the <strong>user</strong> property.
</Banner> </Banner>
### HTTP-only cookies ### HTTP-only cookies
@@ -96,8 +100,8 @@ However, if you use `fetch` or similar APIs to retrieve Payload resources from i
Fetch example, including credentials: Fetch example, including credentials:
```js ```js
const response = await fetch('http://localhost:3000/api/pages', { const response = await fetch("http://localhost:3000/api/pages", {
credentials: 'include', credentials: "include",
}); });
const pages = await response.json(); const pages = await response.json();
@@ -106,8 +110,12 @@ const pages = await response.json();
For more about how to automatically include cookies in requests from your app to your Payload API, [click here](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Sending_a_request_with_credentials_included). For more about how to automatically include cookies in requests from your app to your Payload API, [click here](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Sending_a_request_with_credentials_included).
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br/> <strong>Tip:</strong>
To make sure you have a Payload cookie set properly in your browser after logging in, you can use Chrome's Developer Tools - Application - Cookies - [your-domain-here]. The Chrome Developer tools will still show HTTP-only cookies, even when JavaScript running on the page can't. <br />
To make sure you have a Payload cookie set properly in your browser after
logging in, you can use Chrome's Developer Tools - Application - Cookies -
[your-domain-here]. The Chrome Developer tools will still show HTTP-only
cookies, even when JavaScript running on the page can't.
</Banner> </Banner>
### CSRF Protection ### CSRF Protection
@@ -119,24 +127,29 @@ For example, let's say you have a very popular app running at coolsite.com. This
So, if a user of coolsite.com is logged in and just browsing around on the internet, they might stumble onto a page with bad intentions. That bad page might automatically make requests to all sorts of sites to see if they can find one that they can log into - and coolsite.com might be on their list. If your user was logged in while they visited that evil site, the attacker could do whatever they wanted as if they were your coolsite.com user by just sending requests to the coolsite API (which would automatically include the auth cookie). They could send themselves a bunch of money from your user's account, change the user's password, etc. This is what a CSRF attack is. So, if a user of coolsite.com is logged in and just browsing around on the internet, they might stumble onto a page with bad intentions. That bad page might automatically make requests to all sorts of sites to see if they can find one that they can log into - and coolsite.com might be on their list. If your user was logged in while they visited that evil site, the attacker could do whatever they wanted as if they were your coolsite.com user by just sending requests to the coolsite API (which would automatically include the auth cookie). They could send themselves a bunch of money from your user's account, change the user's password, etc. This is what a CSRF attack is.
<Banner type="warning"> <Banner type="warning">
<strong>To protect against CSRF attacks, Payload only accepts cookie-based authentication from domains that you explicitly whitelist.</strong> <strong>
To protect against CSRF attacks, Payload only accepts cookie-based
authentication from domains that you explicitly whitelist.
</strong>
</Banner> </Banner>
To define domains that should allow users to identify themselves via the Payload HTTP-only cookie, use the `csrf` option on the base Payload config to whitelist domains that you trust. To define domains that should allow users to identify themselves via the Payload HTTP-only cookie, use the `csrf` option on the base Payload config to whitelist domains that you trust.
`payload.config.js`: `payload.config.js`:
```js ```js
import { buildConfig } from 'payload/config'; import { buildConfig } from "payload/config";
const config = buildConfig({ const config = buildConfig({
serverURL: 'http://localhost:3000', serverURL: "http://localhost:3000",
collections: [ collections: [
// collections here // collections here
], ],
// highlight-start // highlight-start
csrf: [ // whitelist of domains to allow cookie auth from csrf: [
'https://your-frontend-app.com', // whitelist of domains to allow cookie auth from
'https://your-other-frontend-app.com', "https://your-frontend-app.com",
"https://your-other-frontend-app.com",
], ],
// highlight-end // highlight-end
}); });
@@ -149,12 +162,13 @@ export default config;
In addition to authenticating via an HTTP-only cookie, you can also identify users via the `Authorization` header on an HTTP request. In addition to authenticating via an HTTP-only cookie, you can also identify users via the `Authorization` header on an HTTP request.
Example: Example:
```js ```js
const request = await fetch('http://localhost:3000', { const request = await fetch("http://localhost:3000", {
headers: { headers: {
Authorization: `JWT ${token}` Authorization: `JWT ${token}`,
} },
}) });
``` ```
You can retrieve a user's token via the response to `login`, `refresh`, and `me` auth operations. You can retrieve a user's token via the response to `login`, `refresh`, and `me` auth operations.

View File

@@ -2,28 +2,30 @@
title: Using the Payload Auth Middleware title: Using the Payload Auth Middleware
label: Using the Middleware label: Using the Middleware
order: 40 order: 40
desc: Payload is a headless CMS and application framework. desc: Make full use of Payload's built-in authentication with your own custom Express endpoints by adding Payload's authentication middleware.
keywords: authentication, middleware, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: authentication, middleware, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
Because Payload uses your existing Express server, you are free to add whatever logic you need to your app through endpoints of your own. However, Payload does not add its middleware to your Express app itself—instead, ist scopes all of its middleware to Payload-specific routers. Because Payload uses your existing Express server, you are free to add whatever logic you need to your app through endpoints of your own. However, Payload does not add its middleware to your Express app itself—instead, it scopes all of its middleware to Payload-specific routers.
This approach has a ton of benefits - it's great for isolation of concerns and limiting scope, but it also means that your additional routes won't have access to Payload's user authentication. This approach has a ton of benefits - it's great for isolation of concerns and limiting scope, but it also means that your additional routes won't have access to Payload's user authentication.
<Banner type="success"> <Banner type="success">
You can make full use of Payload's built-in authentication within your own custom Express endpoints by adding Payload's authentication middleware. You can make full use of Payload's built-in authentication within your own
custom Express endpoints by adding Payload's authentication middleware.
</Banner> </Banner>
Example in `server.js`: Example in `server.js`:
```js ```js
import express from 'express'; import express from "express";
import payload from 'payload'; import payload from "payload";
const app = express(); const app = express();
payload.init({ payload.init({
secret: 'PAYLOAD_SECRET_KEY', secret: "PAYLOAD_SECRET_KEY",
mongoURL: 'mongodb://localhost/payload', mongoURL: "mongodb://localhost/payload",
express: app, express: app,
}); });
@@ -31,18 +33,17 @@ const router = express.Router();
router.use(payload.authenticate); // highlight-line router.use(payload.authenticate); // highlight-line
router.get('/', (req, res) => { router.get("/", (req, res) => {
if (req.user) { if (req.user) {
return res.send(`Authenticated successfully as ${req.user.email}.`); return res.send(`Authenticated successfully as ${req.user.email}.`);
} }
return res.send('Not authenticated'); return res.send("Not authenticated");
}); });
app.use('/some-route-here', router); app.use("/some-route-here", router);
app.listen(3000, async () => { app.listen(3000, async () => {
payload.logger.info(`listening on ${3000}...`); payload.logger.info(`listening on ${3000}...`);
}); });
``` ```

View File

@@ -2,7 +2,7 @@
title: Collection Configs title: Collection Configs
label: Collections label: Collections
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: Structure your Collections for your needs by defining fields, adding slugs and labels, establishing access control, tying in hooks, setting timestamps and more.
keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -12,43 +12,43 @@ It's often best practice to write your Collections in separate files and then im
## Options ## Options
| Option | Description | | Option | Description |
| ---------------- | -------------| | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`slug`** * | Unique, URL-friendly string that will act as an identifier for this Collection. | | **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
| **`fields`** * | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. | | **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. | | **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. |
| **`admin`** | Admin-specific configuration. See below for [more detail](/docs/collections#admin). | | **`admin`** | Admin-specific configuration. See below for [more detail](/docs/collections#admin). |
| **`hooks`** | Entry points to "tie in" to Collection actions at specific points. [More](/docs/hooks/overview#collection-hooks) | | **`hooks`** | Entry points to "tie in" to Collection actions at specific points. [More](/docs/hooks/overview#collection-hooks) |
| **`access`** | Provide access control functions to define exactly who should be able to do what with Documents in this Collection. [More](/docs/access-control/overview/#collections) | | **`access`** | Provide access control functions to define exactly who should be able to do what with Documents in this Collection. [More](/docs/access-control/overview/#collections) |
| **`auth`** | Specify options if you would like this Collection to feature authentication. For more, consult the [Authentication](/docs/authentication/config) documentation. | | **`auth`** | Specify options if you would like this Collection to feature authentication. For more, consult the [Authentication](/docs/authentication/config) documentation. |
| **`upload`** | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](/docs/uploads/overview) documentation. | | **`upload`** | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](/docs/uploads/overview) documentation. |
| **`timestamps`** | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. | | **`timestamps`** | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
#### Simple collection example #### Simple collection example
```js ```js
const Order = { const Order = {
slug: 'orders', slug: "orders",
labels: { labels: {
singular: 'Order', singular: "Order",
plural: 'Orders', plural: "Orders",
}, },
fields: [ fields: [
{ {
name: 'total', name: "total",
type: 'number', type: "number",
required: true, required: true,
}, },
{ {
name: 'placedBy', name: "placedBy",
type: 'relationship', type: "relationship",
relationTo: 'customers', relationTo: "customers",
required: true, required: true,
} },
] ],
} };
``` ```
#### More collection config examples #### More collection config examples
@@ -59,14 +59,14 @@ You can find an assortment of [example collection configs](https://github.com/pa
You can customize the way that the Admin panel behaves on a collection-by-collection basis by defining the `admin` property on a collection's config. You can customize the way that the Admin panel behaves on a collection-by-collection basis by defining the `admin` property on a collection's config.
| Option | Description | | Option | Description |
| ---------------------------- | -------------| | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin panel. If no field is defined, the ID of the document is used as the title. | | `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin panel. If no field is defined, the ID of the document is used as the title. |
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this collection's List view. | | `defaultColumns` | Array of field names that correspond to which columns to show by default in this collection's List view. |
| `disableDuplicate ` | Disables the "Duplicate" button while editing documents within this collection. | | `disableDuplicate ` | Disables the "Duplicate" button while editing documents within this collection. |
| `enableRichTextRelationship` | The [Rich Text](/docs/fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set this field to `true` to enable the collection to be selected within it. | | `enableRichTextRelationship` | The [Rich Text](/docs/fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set this field to `true` to enable the collection to be selected within it. |
| `preview` | Function to generate preview URLS within the Admin panel that can point to your app. [More](/docs/collections#preview). | | `preview` | Function to generate preview URLS within the Admin panel that can point to your app. [More](/docs/collections#preview). |
| `components` | Swap in your own React components to be used within this collection. [More](/docs/admin/components#collections) | | `components` | Swap in your own React components to be used within this collection. [More](/docs/admin/components#collections) |
### Preview ### Preview

View File

@@ -2,7 +2,7 @@
title: Express title: Express
label: Express label: Express
order: 60 order: 60
desc: Payload is a headless CMS and application framework. desc: Payload utilizes Express middleware packages, you can customize how they work by passing in configuration options.
keywords: config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---

View File

@@ -2,51 +2,51 @@
title: Global Configs title: Global Configs
label: Globals label: Globals
order: 30 order: 30
desc: Payload is a headless CMS and application framework. desc: Set up your Global config for your needs by defining fields, adding slugs and labels, establishing access control, tying in hooks and more.
keywords: globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
Global configs are in many ways similar to [Collections](/docs/configuration/collections). The big difference is that Collections will potentially contain *many* documents, while a Global is a "one-off". Globals are perfect for things like header nav, site-wide banner alerts, app-wide localized strings, and other "global" data that your site or app might rely on. Global configs are in many ways similar to [Collections](/docs/configuration/collections). The big difference is that Collections will potentially contain _many_ documents, while a Global is a "one-off". Globals are perfect for things like header nav, site-wide banner alerts, app-wide localized strings, and other "global" data that your site or app might rely on.
As with Collection configs, it's often best practice to write your Globals in separate files and then import them into the main Payload config. As with Collection configs, it's often best practice to write your Globals in separate files and then import them into the main Payload config.
## Options ## Options
| Option | Description | | Option | Description |
| ---------------- | -------------| | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`slug`** * | Unique, URL-friendly string that will act as an identifier for this Global. | | **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Global. |
| **`fields`** * | Array of field types that will determine the structure and functionality of the data stored within this Global. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. | | **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Global. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
| **`label`** | Singular label for use in identifying this Global throughout Payload. | | **`label`** | Singular label for use in identifying this Global throughout Payload. |
| **`admin`** | Admin-specific configuration. See below for [more detail](/docs/configuration/globals#admin-options). | | **`admin`** | Admin-specific configuration. See below for [more detail](/docs/configuration/globals#admin-options). |
| **`hooks`** | Entry points to "tie in" to collection actions at specific points. [More](/docs/hooks/overview#global-hooks) | | **`hooks`** | Entry points to "tie in" to collection actions at specific points. [More](/docs/hooks/overview#global-hooks) |
| **`access`** | Provide access control functions to define exactly who should be able to do what with this Global. [More](/docs/access-control/overview/#globals) | | **`access`** | Provide access control functions to define exactly who should be able to do what with this Global. [More](/docs/access-control/overview/#globals) |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
#### Simple Global example #### Simple Global example
```js ```js
const Nav = { const Nav = {
slug: 'nav', slug: "nav",
label: 'Nav', label: "Nav",
fields: [ fields: [
{ {
name: 'items', name: "items",
type: 'array', type: "array",
required: true, required: true,
maxRows: 8, maxRows: 8,
fields: [ fields: [
{ {
name: 'page', name: "page",
label: 'Page', label: "Page",
type: 'relationship', type: "relationship",
relationTo: 'pages', // "pages" is the slug of an existing collection relationTo: "pages", // "pages" is the slug of an existing collection
required: true, required: true,
} },
] ],
}, },
] ],
} };
``` ```
#### More Global config examples #### More Global config examples
@@ -57,9 +57,9 @@ You can find an assortment of [example Global configs](https://github.com/payloa
You can customize the way that the Admin panel behaves on a Global-by-Global basis by defining the `admin` property on a Global's config. You can customize the way that the Admin panel behaves on a Global-by-Global basis by defining the `admin` property on a Global's config.
| Option | Description | | Option | Description |
| ---------------------------- | -------------| | ------------ | ------------------------------------------------------------------------------------------------------- |
| `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) | | `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) |
### Access control ### Access control

View File

@@ -2,7 +2,7 @@
title: Localization title: Localization
label: Localization label: Localization
order: 50 order: 50
desc: Payload is a headless CMS and application framework. desc: Add and maintain as many locales as you need by adding Localization to your Payload config, set options for default locale, fallbacks, fields and more.
keywords: localization, internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: localization, internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -68,8 +68,13 @@ With the above configuration, the `title` field will now be saved in the databas
All field types with a `name` property support the `localized` property—even the more complex field types like `array`s and `block`s. All field types with a `name` property support the `localized` property—even the more complex field types like `array`s and `block`s.
<Banner> <Banner>
<strong>Note:</strong><br/> <strong>Note:</strong>
Enabling localization for field types that support nested fields will automatically create localized "sets" of all fields contained within the field. For example, if you have a page layout using a blocks field type, you have the choice of either localizing the full layout, by enabling localization on the top-level blocks field, or only certain fields within the layout. <br />
Enabling localization for field types that support nested fields will
automatically create localized "sets" of all fields contained within the
field. For example, if you have a page layout using a blocks field type, you
have the choice of either localizing the full layout, by enabling localization
on the top-level blocks field, or only certain fields within the layout.
</Banner> </Banner>
### Retrieving localized docs ### Retrieving localized docs
@@ -106,16 +111,19 @@ The `fallbackLocale` arg will accept valid locales as well as `none` to disable
```graphql ```graphql
query { query {
Posts(locale: de, fallbackLocale: none) { Posts(locale: de, fallbackLocale: none) {
docs { docs {
title title
} }
} }
} }
``` ```
<Banner> <Banner>
In GraphQL, specifying the locale at the top level of a query will automatically apply it throughout all nested relationship fields. You can override this behavior by re-specifying locale arguments in nested related document queries. In GraphQL, specifying the locale at the top level of a query will
automatically apply it throughout all nested relationship fields. You can
override this behavior by re-specifying locale arguments in nested related
document queries.
</Banner> </Banner>
##### Local API ##### Local API
@@ -126,8 +134,8 @@ You can specify `locale` as well as `fallbackLocale` within the Local API as wel
```js ```js
const posts = await payload.find({ const posts = await payload.find({
collection: 'posts', collection: "posts",
locale: 'es', locale: "es",
fallbackLocale: false, fallbackLocale: false,
}) });
``` ```

View File

@@ -2,16 +2,24 @@
title: The Payload Config title: The Payload Config
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: The Payload config is central to everything that Payload does, from adding custom React components, to modifying collections, controlling localization and much more.
keywords: overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
Payload is a *config-based*, code-first CMS and application framework. The Payload config is central to everything that Payload does. It scaffolds the data that Payload stores as well as maintains custom React components, hook logic, custom validations, and much more. The config itself and all of its dependencies are run through Babel, so you can take full advantage of newer JavaScript features and even directly import React components containing JSX. Payload is a _config-based_, code-first CMS and application framework. The Payload config is central to everything that Payload does. It scaffolds the data that Payload stores as well as maintains custom React components, hook logic, custom validations, and much more. The config itself and all of its dependencies are run through Babel, so you can take full advantage of newer JavaScript features and even directly import React components containing JSX.
<strong>Also, because the Payload source code is fully written in TypeScript, its configs are strongly typed—meaning that even if you aren't using TypeScript to build your project, your IDE (such as VSCode) may still provide helpful information like type-ahead suggestions while you write your config.</strong> <strong>
Also, because the Payload source code is fully written in TypeScript, its
configs are strongly typed—meaning that even if you aren't using TypeScript to
build your project, your IDE (such as VSCode) may still provide helpful
information like type-ahead suggestions while you write your config.
</strong>
<Banner type="warning"> <Banner type="warning">
<strong>Important:</strong><br />This file is included in the Payload admin bundle, so make sure you do not embed any sensitive information. <strong>Important:</strong>
<br />
This file is included in the Payload admin bundle, so make sure you do not
embed any sensitive information.
</Banner> </Banner>
## Options ## Options
@@ -40,54 +48,53 @@ Payload is a *config-based*, code-first CMS and application framework. The Paylo
#### Simple example #### Simple example
```js ```js
import { buildConfig } from 'payload/config'; import { buildConfig } from "payload/config";
const config = buildConfig({ const config = buildConfig({
serverURL: 'http://localhost:3000', serverURL: "http://localhost:3000",
collections: [ collections: [
{ {
slug: 'pages', slug: "pages",
fields: [ fields: [
{ {
name: 'title', name: "title",
label: 'Title', label: "Title",
type: 'text', type: "text",
required: true, required: true,
}, },
{ {
name: 'content', name: "content",
label: 'Content', label: "Content",
type: 'richText', type: "richText",
required: true, required: true,
} },
] ],
} },
], ],
globals: [ globals: [
{ {
slug: 'header', slug: "header",
label: 'Header', label: "Header",
fields: [ fields: [
{ {
name: 'nav', name: "nav",
label: 'Nav', label: "Nav",
type: 'array', type: "array",
fields: [ fields: [
{ {
name: 'page', name: "page",
label: 'Page', label: "Page",
type: 'relationship', type: "relationship",
relationTo: 'pages', relationTo: "pages",
}, },
] ],
} },
] ],
} },
] ],
}); });
export default config; export default config;
``` ```
#### Full example config #### Full example config
@@ -99,6 +106,7 @@ You can see a full [example config](https://github.com/payloadcms/payload/blob/m
We suggest using the `dotenv` package to handle environment variables alongside of Payload. All that's necessary to do is to require the package as high up in your application as possible (for example, at the top of your `server.js` file), and ensure that it can find an `.env` file that you create. We suggest using the `dotenv` package to handle environment variables alongside of Payload. All that's necessary to do is to require the package as high up in your application as possible (for example, at the top of your `server.js` file), and ensure that it can find an `.env` file that you create.
**Add this line to the top of your server:** **Add this line to the top of your server:**
``` ```
require('dotenv').config() require('dotenv').config()
// ... // ...
@@ -116,8 +124,13 @@ project-name
``` ```
<Banner type="warning"> <Banner type="warning">
<strong>Important:</strong><br /> <strong>Important:</strong>
If you use an environment variable to configure any properties that are required for the Admin panel to function (ex. serverURL or any routes), you need to make sure that your Admin panel code can access it. <a href="/docs/admin/webpack#admin-environment-vars">Click here</a> for more info. <br />
If you use an environment variable to configure any properties that are
required for the Admin panel to function (ex. serverURL or any routes), you
need to make sure that your Admin panel code can access it.{" "}
<a href="/docs/admin/webpack#admin-environment-vars">Click here</a> for more
info.
</Banner> </Banner>
### Customizing & overriding the config location ### Customizing & overriding the config location

View File

@@ -2,7 +2,7 @@
title: Email Functionality title: Email Functionality
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Payload uses NodeMailer to allow you to send emails smoothly from your app. Set up email functions such as password resets, order confirmations and more.
keywords: email, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: email, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -25,20 +25,21 @@ in the `email` property object of your payload init call. Payload will make use
The following options are configurable in the `email` property object as part of the options object when calling payload.init(). The following options are configurable in the `email` property object as part of the options object when calling payload.init().
| Option | Description | | Option | Description |
| ---------------------------- | -------------| | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`transport`** | The NodeMailer transport object for when you want to do it yourself, not needed when transportOptions is set | | **`transport`** | The NodeMailer transport object for when you want to do it yourself, not needed when transportOptions is set |
| **`transportOptions`** | An object that configures the transporter that Payload will create. For all the available options see the [NodeMailer documentation](https://nodemailer.com/smtp/) or see the examples below | | **`transportOptions`** | An object that configures the transporter that Payload will create. For all the available options see the [NodeMailer documentation](https://nodemailer.com/smtp/) or see the examples below |
| **`fromName`** * | The name part of the From field that will be seen on the delivered email | | **`fromName`** \* | The name part of the From field that will be seen on the delivered email |
| **`fromAddress`** * | The email address part of the From field that will be used when delivering email | | **`fromAddress`** \* | The email address part of the From field that will be used when delivering email |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Use SMTP ### Use SMTP
Simple Mail Transfer Protocol, also known as SMTP can be passed in using the `transportOptions` object on the `email` options. Simple Mail Transfer Protocol, also known as SMTP can be passed in using the `transportOptions` object on the `email` options.
**Example email part using SMTP:** **Example email part using SMTP:**
```js ```js
payload.init({ payload.init({
email: { email: {
@@ -62,7 +63,12 @@ payload.init({
``` ```
<Banner type="warning"> <Banner type="warning">
It is best practice to avoid saving credentials or API keys directly in your code, use <a href="/docs/configuration/overview#using-environment-variables-in-your-config">environment variables</a>. It is best practice to avoid saving credentials or API keys directly in your
code, use{" "}
<a href="/docs/configuration/overview#using-environment-variables-in-your-config">
environment variables
</a>
.
</Banner> </Banner>
### Use an email service ### Use an email service
@@ -70,25 +76,28 @@ payload.init({
Many third party mail providers are available and offer benefits beyond basic SMTP. As an example your payload init could look this if you wanted to use SendGrid.com though the same approach would work for any other [NodeMailer transports](https://nodemailer.com/transports/) shown here or provided by another third party. Many third party mail providers are available and offer benefits beyond basic SMTP. As an example your payload init could look this if you wanted to use SendGrid.com though the same approach would work for any other [NodeMailer transports](https://nodemailer.com/transports/) shown here or provided by another third party.
```js ```js
const nodemailerSendgrid = require('nodemailer-sendgrid'); const nodemailerSendgrid = require("nodemailer-sendgrid");
const payload = require('payload'); const payload = require("payload");
const sendGridAPIKey = process.env.SENDGRID_API_KEY; const sendGridAPIKey = process.env.SENDGRID_API_KEY;
payload.init({ payload.init({
...sendGridAPIKey ? { ...(sendGridAPIKey
email: { ? {
transportOptions: nodemailerSendgrid({ email: {
apiKey: sendGridAPIKey, transportOptions: nodemailerSendgrid({
}), apiKey: sendGridAPIKey,
fromName: 'Admin', }),
fromAddress: 'admin@example.com', fromName: "Admin",
}, fromAddress: "admin@example.com",
} : {}, },
}
: {}),
}); });
``` ```
### Use a custom NodeMailer transport ### Use a custom NodeMailer transport
To take full control of the mail transport you may wish to use `nodemailer.createTransport()` on your server and provide it to Payload init. To take full control of the mail transport you may wish to use `nodemailer.createTransport()` on your server and provide it to Payload init.
```js ```js
@@ -114,12 +123,15 @@ payload.init({
``` ```
### Sending Mail ### Sending Mail
With a working transport you can call it anywhere you have access to payload by calling `payload.sendEmail(message)`. The `message` will contain the `to`, `subject` and `email` or `text` for the email being sent. To see all available message configuration options see [NodeMailer](https://nodemailer.com/message). With a working transport you can call it anywhere you have access to payload by calling `payload.sendEmail(message)`. The `message` will contain the `to`, `subject` and `email` or `text` for the email being sent. To see all available message configuration options see [NodeMailer](https://nodemailer.com/message).
### Mock transport ### Mock transport
By default, Payload uses a mock implementation that only sends mail to the [ethereal](https://ethereal.email) capture service that will never reach a user's inbox. While in development you may wish to make use of the captured messages which is why the payload output during server output helpfully logs this out on the server console. By default, Payload uses a mock implementation that only sends mail to the [ethereal](https://ethereal.email) capture service that will never reach a user's inbox. While in development you may wish to make use of the captured messages which is why the payload output during server output helpfully logs this out on the server console.
**Console output when starting payload with a mock email instance** **Console output when starting payload with a mock email instance**
``` ```
[06:37:21] INFO (payload): Starting Payload... [06:37:21] INFO (payload): Starting Payload...
[06:37:22] INFO (payload): Payload Demo Initialized [06:37:22] INFO (payload): Payload Demo Initialized
@@ -134,7 +146,8 @@ By default, Payload uses a mock implementation that only sends mail to the [ethe
The mock email handler is used when payload is started with neither `transport` or `transportOptions` to know how to deliver email. The mock email handler is used when payload is started with neither `transport` or `transportOptions` to know how to deliver email.
<Banner type="warning"> <Banner type="warning">
The randomly generated email account username and password will be different each time the Payload server starts. The randomly generated email account username and password will be different
each time the Payload server starts.
</Banner> </Banner>
### Using multiple mail providers ### Using multiple mail providers

View File

@@ -2,12 +2,14 @@
title: Array Field title: Array Field
label: Array label: Array
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: Array fields are intended for sets of repeating fields, that you define. Learn how to use array fields, see examples and options.
keywords: array, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: array, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Array field type is used when you need to have a set of "repeating" fields. It stores an array of objects containing the fields that you define. Its uses can be simple or highly complex. The Array field type is used when you need to have a set of "repeating"
fields. It stores an array of objects containing the fields that you define.
Its uses can be simple or highly complex.
</Banner> </Banner>
**Example uses:** **Example uses:**
@@ -17,31 +19,32 @@ keywords: array, fields, config, configuration, documentation, Content Managemen
- Event agenda "timeslots" where you need to specify start & end time ([date field](/docs/fields/date)), label ([text field](/docs/fields/text)), and Learn More page [relationship](/docs/fields/relationship) - Event agenda "timeslots" where you need to specify start & end time ([date field](/docs/fields/date)), label ([text field](/docs/fields/text)), and Learn More page [relationship](/docs/fields/relationship)
![Array field in Payload admin panel](https://payloadcms.com/images/fields/array.jpg) ![Array field in Payload admin panel](https://payloadcms.com/images/fields/array.jpg)
*Admin panel screenshot of an Array field with a Row containing two text fields, a read-only text field and a checkbox* _Admin panel screenshot of an Array field with a Row containing two text fields, a read-only text field and a checkbox_
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a heading in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a heading in the Admin panel and to name the generated GraphQL type. |
| **`fields`** * | Array of field types to correspond to each row of the Array. | | **`fields`** \* | Array of field types to correspond to each row of the Array. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide an array of row data to be used for this field's default value. | | **`defaultValue`** | Provide an array of row data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Array will be kept, so there is no need to specify each nested field as `localized`. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Array will be kept, so there is no need to specify each nested field as `localized`. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`labels`** | Customize the row labels appearing in the Admin dashboard. | | **`labels`** | Customize the row labels appearing in the Admin dashboard. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. | | **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,12 +2,15 @@
title: Blocks Field title: Blocks Field
label: Blocks label: Blocks
order: 30 order: 30
desc: Payload is a headless CMS and application framework. desc: The Blocks field type is a great layout build and can be used to construct any flexible content model. Learn how to use Block fields, see examples and options.
keywords: blocks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: blocks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Blocks field type is <strong>incredibly powerful</strong> and can be used as a <em>layout builder</em> as well as to define any other flexible content model you can think of. It stores an array of objects, where each object must match the shape of one of your provided block configs. The Blocks field type is <strong>incredibly powerful</strong> and can be used
as a <em>layout builder</em> as well as to define any other flexible content
model you can think of. It stores an array of objects, where each object must
match the shape of one of your provided block configs.
</Banner> </Banner>
**Example uses:** **Example uses:**
@@ -17,45 +20,50 @@ keywords: blocks, fields, config, configuration, documentation, Content Manageme
- Virtual event agenda "timeslots" where a timeslot could either be a `Break`, a `Presentation`, or a `BreakoutSession`. - Virtual event agenda "timeslots" where a timeslot could either be a `Break`, a `Presentation`, or a `BreakoutSession`.
![Blocks field in Payload admin panel](https://payloadcms.com/images/fields/blocks.jpg) ![Blocks field in Payload admin panel](https://payloadcms.com/images/fields/blocks.jpg)
*Admin panel screenshot of a Blocks field type with Call to Action and Number block examples* _Admin panel screenshot of a Blocks field type with Call to Action and Number block examples_
### Field config ### Field config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | -------------- | ----------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a heading in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a heading in the Admin panel and to name the generated GraphQL type. |
| **`blocks`** * | Array of [block configs](/docs/fields/blocks#block-configs) to be made available to this field. | | **`blocks`** \* | Array of [block configs](/docs/fields/blocks#block-configs) to be made available to this field. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-level hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-level hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-level access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-level access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API response or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API response or the Admin panel. |
| **`defaultValue`** | Provide an array of block data to be used for this field's default value. | | **`defaultValue`** | Provide an array of block data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this field will be kept, so there is no need to specify each nested field as `localized`. || **`required`** | Require this field to have a value. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this field will be kept, so there is no need to specify each nested field as `localized`. | | **`required`** | Require this field to have a value. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. | | **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`labels`** | Customize the block row labels appearing in the Admin dashboard. | | **`labels`** | Customize the block row labels appearing in the Admin dashboard. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. | | **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Block configs ### Block configs
Blocks are defined as separate configs of their own. Blocks are defined as separate configs of their own.
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br /> <strong>Tip:</strong>
Best practice is to define each block config in its own file, and then import them into your Blocks field as necessary. This way each block config can be easily shared between fields. For instance, using the "layout builder" example, you might want to feature a few of the same blocks in a Post collection as well as a Page collection. Abstracting into their own files trivializes their reusability. <br />
Best practice is to define each block config in its own file, and then import
them into your Blocks field as necessary. This way each block config can be
easily shared between fields. For instance, using the "layout builder"
example, you might want to feature a few of the same blocks in a Post
collection as well as a Page collection. Abstracting into their own files
trivializes their reusability.
</Banner> </Banner>
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | -------------------------------------------------------------------------------------------------------------------- |
| **`slug`** * | Identifier for this block type. Will be saved on each block as the `blockType` property. | | **`slug`** \* | Identifier for this block type. Will be saved on each block as the `blockType` property. |
| **`fields`** * | Array of fields to be stored in this block. | | **`fields`** \* | Array of fields to be stored in this block. |
| **`labels`** | Customize the block labels that appear in the Admin dashboard. Also used to name corresponding GraphQL schema types. | | **`labels`** | Customize the block labels that appear in the Admin dashboard. Also used to name corresponding GraphQL schema types. |
| **`imageURL`** | Provide a custom image thumbnail to help editors identify this block in the Admin UI. | | **`imageURL`** | Provide a custom image thumbnail to help editors identify this block in the Admin UI. |
| **`imageAltText`** | Customize this block's image thumbnail alt text. | | **`imageAltText`** | Customize this block's image thumbnail alt text. |
#### Auto-generated data per block #### Auto-generated data per block
@@ -72,44 +80,46 @@ The Admin panel provides each block with a `blockName` field which optionally al
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
const QuoteBlock = { const QuoteBlock = {
slug: 'Quote', // required slug: "Quote", // required
imageURL: 'https://google.com/path/to/image.jpg', imageURL: "https://google.com/path/to/image.jpg",
imageAltText: 'A nice thumbnail image to show what this block looks like', imageAltText: "A nice thumbnail image to show what this block looks like",
fields: [ // required fields: [
// required
{ {
name: 'text', name: "text",
label: 'Quote Text', label: "Quote Text",
type: 'text', type: "text",
required: true, required: true,
}, },
{ {
name: 'text', name: "text",
label: 'Quotee', label: "Quotee",
type: 'text', type: "text",
}, },
] ],
}; };
const ExampleCollection = { const ExampleCollection = {
slug: 'example-collection', slug: "example-collection",
fields: [ fields: [
{ {
name: 'layout', // required name: "layout", // required
type: 'blocks', // required type: "blocks", // required
label: 'layout', label: "layout",
minRows: 1, minRows: 1,
maxRows: 20, maxRows: 20,
labels: { labels: {
singular: 'Layout', singular: "Layout",
plural: 'Layouts', plural: "Layouts",
}, },
blocks: [ // required blocks: [
QuoteBlock // required
] QuoteBlock,
} ],
] },
} ],
};
``` ```

View File

@@ -2,36 +2,35 @@
title: Checkbox Field title: Checkbox Field
label: Checkbox label: Checkbox
order: 40 order: 40
desc: Payload is a headless CMS and application framework. desc: Checkbox field types allow the developer to save a boolean value in the database. Learn how to use Checkbox fields, see examples and options.
keywords: checkbox, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: checkbox, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>The Checkbox field type saves a boolean in the database.</Banner>
The Checkbox field type saves a boolean in the database.
</Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. | | **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,37 +2,39 @@
title: Code Field title: Code Field
label: Code label: Code
order: 50 order: 50
desc: Payload is a headless CMS and application framework. desc: The Code field type will store any string in the Database. Learn how to use Code fields, see examples and options.
keywords: code, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: code, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Code field type saves a string in the database, but provides the Admin panel with a code editor styled interface. The Code field type saves a string in the database, but provides the Admin
panel with a code editor styled interface.
</Banner> </Banner>
This field uses `prismjs` for syntax highlighting and `react-simple-code-editor` for the editor itself. This field uses `prismjs` for syntax highlighting and `react-simple-code-editor` for the editor itself.
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. | | **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. | | **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. | | **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). | | **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Admin config ### Admin config
@@ -43,6 +45,7 @@ Currently, the `language` property only supports JavaScript syntax but more supp
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,34 +2,35 @@
title: Date Field title: Date Field
label: Date label: Date
order: 60 order: 60
desc: Payload is a headless CMS and application framework. desc: The Date field type stores a Date in the database. Learn how to use and customize the Date field, see examples and options.
keywords: date, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: date, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Date field type saves a Date in the database and provides the Admin panel with a customizable time picker interface. The Date field type saves a Date in the database and provides the Admin panel
with a customizable time picker interface.
</Banner> </Banner>
This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepicker) for the Admin panel component. This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepicker) for the Admin panel component.
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin). | | **`admin`** | Admin-specific configuration. See below for [more detail](#admin). |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Admin config ### Admin config
@@ -42,6 +43,7 @@ Common use cases for customizing the `date` property are to restrict your field
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,33 +2,33 @@
title: Email Field title: Email Field
label: Email label: Email
order: 70 order: 70
desc: Payload is a headless CMS and application framework. desc: The Email field enforces that the value provided is a valid email address. Learn how to use Email fields, see examples and options.
keywords: email, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: email, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Email field enforces that the value provided is a valid email address. The Email field enforces that the value provided is a valid email address.
</Banner> </Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. | | **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin). | | **`admin`** | Admin-specific configuration. See below for [more detail](#admin). |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Admin config ### Admin config
@@ -45,6 +45,7 @@ Set this property to a string that will be used for browser autocomplete.
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,36 +2,38 @@
title: Group Field title: Group Field
label: Group label: Group
order: 80 order: 80
desc: Payload is a headless CMS and application framework. desc: The Group field allows other fields to be nested under a common property. Learn how to use Group fields, see examples and options.
keywords: group, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: group, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Group field allows fields to be nested under a common property name. It also groups fields together visually in the Admin panel. The Group field allows fields to be nested under a common property name. It
also groups fields together visually in the Admin panel.
</Banner> </Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`fields`** * | Array of field types to nest within this Group. | | **`fields`** \* | Array of field types to nest within this Group. |
| **`label`** | Used as a heading in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a heading in the Admin panel and to name the generated GraphQL type. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide an object of data to be used for this field's default value. | | **`defaultValue`** | Provide an object of data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Group will be kept, so there is no need to specify each nested field as `localized`. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Group will be kept, so there is no need to specify each nested field as `localized`. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. | | **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,35 +2,36 @@
title: Number Field title: Number Field
label: Number label: Number
order: 90 order: 90
desc: Payload is a headless CMS and application framework. desc: Number fields store and validate numeric data. Learn how to use and format Number fields, see examples and Number field options.
keywords: number, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: number, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Number field stores and validates numeric entry and supports additional numerical validation and formatting features. The Number field stores and validates numeric entry and supports additional
numerical validation and formatting features.
</Banner> </Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`min`** | Minimum value accepted. Used in the default `validation` function. | | **`min`** | Minimum value accepted. Used in the default `validation` function. |
| **`max`** | Maximum value accepted. Used in the default `validation` function. | | **`max`** | Maximum value accepted. Used in the default `validation` function. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. | | **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin). | | **`admin`** | Admin-specific configuration. See below for [more detail](#admin). |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Admin config ### Admin config
@@ -51,6 +52,7 @@ Set this property to a string that will be used for browser autocomplete.
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,12 +2,14 @@
title: Fields Overview title: Fields Overview
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Fields are the building blocks of Payload, find out how to add or remove a field, change field type, add hooks, define access control and validation.
keywords: overview, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: overview, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner type="info"> <Banner type="info">
Fields are the building blocks of Payload. Collections and Globals both use Fields to define the shape of the data that they store. Payload offers a wide variety of field types - both simple and complex. Fields are the building blocks of Payload. Collections and Globals both use
Fields to define the shape of the data that they store. Payload offers a wide
variety of field types - both simple and complex.
</Banner> </Banner>
Fields are defined as an array on Collections and Globals via the `fields` key. They define the shape of the data that will be stored as well as automatically construct the corresponding Admin UI. Fields are defined as an array on Collections and Globals via the `fields` key. They define the shape of the data that will be stored as well as automatically construct the corresponding Admin UI.
@@ -15,22 +17,23 @@ Fields are defined as an array on Collections and Globals via the `fields` key.
The required `type` property on a field determines what values it can accept, how it is presented in the API, and how the field will be rendered in the admin interface. The required `type` property on a field determines what values it can accept, how it is presented in the API, and how the field will be rendered in the admin interface.
**Simple collection with two fields:** **Simple collection with two fields:**
```js ```js
const Pages = { const Pages = {
slug: 'pages', slug: "pages",
fields: [ fields: [
{ {
name: 'my-field', name: "my-field",
type: 'text', // highlight-line type: "text", // highlight-line
label: 'My Field', label: "My Field",
}, },
{ {
name: 'other-field', name: "other-field",
type: 'checkbox', // highlight-line type: "checkbox", // highlight-line
label: 'Other Field' label: "Other Field",
}, },
], ],
} };
``` ```
### Field types ### Field types
@@ -65,6 +68,7 @@ In addition to being able to define access control on a document-level, you can
You can provide your own validation function for all field types. It will be used on both the frontend and the backend, so it should not rely on any Node-specific packages. The validation function can be either synchronous or asynchronous and accepts the field's value and expects to return either `true` or a string error message to display in both API responses and within the Admin panel. You can provide your own validation function for all field types. It will be used on both the frontend and the backend, so it should not rely on any Node-specific packages. The validation function can be either synchronous or asynchronous and accepts the field's value and expects to return either `true` or a string error message to display in both API responses and within the Admin panel.
Example: Example:
```js ```js
{ {
slug: 'orders', slug: 'orders',
@@ -89,15 +93,15 @@ Example:
In addition to each field's base configuration, you can define specific traits and properties for fields that only have effect on how they are rendered in the Admin panel. The following properties are available for all fields within the `admin` property: In addition to each field's base configuration, you can define specific traits and properties for fields that only have effect on how they are rendered in the Admin panel. The following properties are available for all fields within the `admin` property:
| Option | Description | | Option | Description |
| ------------- | -------------| | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | You can programmatically show / hide fields based on what other fields are doing. [Click here](#conditional-logic) for more info. | | `condition` | You can programmatically show / hide fields based on what other fields are doing. [Click here](#conditional-logic) for more info. |
| `components` | All field components can be completely and easily swapped out for custom components that you define. [Click here](#custom-admin-components) for more info. | | `components` | All field components can be completely and easily swapped out for custom components that you define. [Click here](#custom-admin-components) for more info. |
| `position` | Specify if the field should be rendered in the sidebar by defining `position: 'sidebar'`. | | `position` | Specify if the field should be rendered in the sidebar by defining `position: 'sidebar'`. |
| `width` | Restrict the width of a field. you can pass any string-based value here, be it pixels, percentages, etc. This property is especially useful when fields are nested within a `Row` type where they can be organized horizontally. | | `width` | Restrict the width of a field. you can pass any string-based value here, be it pixels, percentages, etc. This property is especially useful when fields are nested within a `Row` type where they can be organized horizontally. |
| `readOnly` | Setting a field to `readOnly` has no effect on the API whatsoever but disables the admin component's editability to prevent editors from modifying the field's value. | | `readOnly` | Setting a field to `readOnly` has no effect on the API whatsoever but disables the admin component's editability to prevent editors from modifying the field's value. |
| `disabled` | If a field is `disabled`, it is completely omitted from the Admin panel. | | `disabled` | If a field is `disabled`, it is completely omitted from the Admin panel. |
| `hidden` | Setting a field's `hidden` property on its `admin` config will transform it into a `hidden` input type. Its value will still submit with the Admin panel's requests, but the field itself will not be visible to editors. | | `hidden` | Setting a field's `hidden` property on its `admin` config will transform it into a `hidden` input type. Its value will still submit with the Admin panel's requests, but the field itself will not be visible to editors. |
### Conditional logic ### Conditional logic
@@ -114,13 +118,13 @@ The `condition` function should return a boolean that will control if the field
{ {
fields: [ fields: [
{ {
name: 'enableGreeting', name: "enableGreeting",
type: 'checkbox', type: "checkbox",
defaultValue: false, defaultValue: false,
}, },
{ {
name: 'greeting', name: "greeting",
type: 'text', type: "text",
admin: { admin: {
// highlight-start // highlight-start
condition: (data, siblingData) => { condition: (data, siblingData) => {
@@ -129,11 +133,11 @@ The `condition` function should return a boolean that will control if the field
} else { } else {
return false; return false;
} }
} },
// highlight-end // highlight-end
} },
} },
] ];
} }
``` ```

View File

@@ -2,37 +2,44 @@
title: Radio Field title: Radio Field
label: Radio Group label: Radio Group
order: 100 order: 100
desc: Payload is a headless CMS and application framework. desc: The Radio field type allows for the selection of one value from a predefined set of possible values. Learn how to use Radio fields, see examples and options.
keywords: radio, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: radio, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Radio field type allows for the selection of one value from a predefined set of possible values and presents a radio group-style set of inputs to the Admin panel. The Radio field type allows for the selection of one value from a predefined
set of possible values and presents a radio group-style set of inputs to the
Admin panel.
</Banner> </Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`options`** * | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `option` string and a `value` string. | | **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `option` string and a `value` string. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin). | | **`admin`** | Admin-specific configuration. See below for [more detail](#admin). |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
<Banner type="warning"> <Banner type="warning">
<strong>Important:</strong><br/> <strong>Important:</strong>
Option values should be strings that do not contain hyphens or special characters due to GraphQL enumeration naming constraints. Underscores are allowed. If you determine you need your option values to be non-strings or contain special characters, they will be formatted accordingly before being used as a GraphQL enum. <br />
Option values should be strings that do not contain hyphens or special
characters due to GraphQL enumeration naming constraints. Underscores are
allowed. If you determine you need your option values to be non-strings or
contain special characters, they will be formatted accordingly before being
used as a GraphQL enum.
</Banner> </Banner>
### Admin config ### Admin config
@@ -46,6 +53,7 @@ The `layout` property allows for the radio group to be styled as a horizonally o
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,12 +2,13 @@
title: Relationship Field title: Relationship Field
label: Relationship label: Relationship
order: 110 order: 110
desc: Payload is a headless CMS and application framework. desc: The Relationship field provides the ability to relate documents together. Learn how to use Relationship fields, see examples and options.
keywords: relationship, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: relationship, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Relationship field is one of the most powerful fields Payload features. It provides for the ability to easily relate documents together. The Relationship field is one of the most powerful fields Payload features. It
provides for the ability to easily relate documents together.
</Banner> </Banner>
**Example uses:** **Example uses:**
@@ -18,34 +19,37 @@ keywords: relationship, fields, config, configuration, documentation, Content Ma
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`*relationTo`** * | Provide one or many collection `slug`s to be able to assign relationships to. | | **`*relationTo`** \* | Provide one or many collection `slug`s to be able to assign relationships to. |
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. | | **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. | | **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. | | **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br/> <strong>Tip:</strong>
The <a href="/docs/getting-started/concepts#depth">Depth</a> parameter can be used to automatically populate related documents that are returned by the API. <br />
The <a href="/docs/getting-started/concepts#depth">Depth</a> parameter can be
used to automatically populate related documents that are returned by the API.
</Banner> </Banner>
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,37 +2,46 @@
title: Rich Text Field title: Rich Text Field
label: Rich Text label: Rich Text
order: 120 order: 120
desc: Payload is a headless CMS and application framework. desc: The Rich Text field allows dynamic content to be written through the Admin Panel. Learn how to use Rich Text fields, see examples and options.
keywords: rich text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: rich text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Rich Text field is a powerful way to allow editors to write dynamic content. The content is saved as JSON in the database and can be converted into any format, including HTML, that you need. The Rich Text field is a powerful way to allow editors to write dynamic
content. The content is saved as JSON in the database and can be converted
into any format, including HTML, that you need.
</Banner> </Banner>
The Admin component is built on the powerful [`slatejs`](https://docs.slatejs.org/) editor and is meant to be as extensible and customizable as possible. The Admin component is built on the powerful [`slatejs`](https://docs.slatejs.org/) editor and is meant to be as extensible and customizable as possible.
<Banner type="success"> <Banner type="success">
<strong>Consistent with Payload's goal of making you learn as litle of Payload as possible, customizing and using the Rich Text Editor does not involve learning how to develop for a <em>Payload</em> rich text editor.</strong> Instead, you can invest your time and effort into learning Slate, an open-source tool that will allow you to apply your learnings elsewhere as well. <strong>
Consistent with Payload's goal of making you learn as litle of Payload as
possible, customizing and using the Rich Text Editor does not involve
learning how to develop for a <em>Payload</em> rich text editor.
</strong>{" "}
Instead, you can invest your time and effort into learning Slate, an
open-source tool that will allow you to apply your learnings elsewhere as
well.
</Banner> </Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). | | **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Admin config ### Admin config
@@ -76,8 +85,11 @@ The default `leaves` available in Payload are:
The built-in `relationship` element is a powerful way to reference other Documents directly within your Rich Text editor. The built-in `relationship` element is a powerful way to reference other Documents directly within your Rich Text editor.
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br/> <strong>Tip:</strong>
To enable collections to be selected within the Rich Text relationship, you need to enable the collection admin option of <strong>enableRichTextRelationship</strong>. <br />
To enable collections to be selected within the Rich Text relationship, you
need to enable the collection admin option of{" "}
<strong>enableRichTextRelationship</strong>.
</Banner> </Banner>
### Specifying which elements and leaves to allow ### Specifying which elements and leaves to allow
@@ -92,11 +104,11 @@ Once you're up to speed with the general concepts involved, you can pass in your
**Both custom elements and leaves are defined via the following config:** **Both custom elements and leaves are defined via the following config:**
| Property | Description | | Property | Description |
| ---------------- | ----------- | | --------------- | ---------------------------------------------------------- |
| **`name`** * | The name to be used as a `type` for this element. | | **`name`** \* | The name to be used as a `type` for this element. |
| **`Button`** * | A React component to be rendered in the Rich Text toolbar. | | **`Button`** \* | A React component to be rendered in the Rich Text toolbar. |
| **`plugins`** | An array of plugins to provide to the Rich Text editor. | | **`plugins`** | An array of plugins to provide to the Rich Text editor. |
Custom `Element`s also require the `Element` property set to a Reactt component to be rendered as the `Element` within the rich text editor itself. Custom `Element`s also require the `Element` property set to a Reactt component to be rendered as the `Element` within the rich text editor itself.
@@ -105,6 +117,7 @@ Custom `Leaf` objects follow a similar pattern but require you to define the `Le
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',
@@ -156,110 +169,68 @@ For more examples regarding how to define your own elements and leaves, check ou
As the Rich Text field saves its content in a JSON format, you'll need to render it as HTML yourself. Here is an example for how to generate JSX / HTML from Rich Text content: As the Rich Text field saves its content in a JSON format, you'll need to render it as HTML yourself. Here is an example for how to generate JSX / HTML from Rich Text content:
```js ```js
import React, { Fragment } from 'react'; import React, { Fragment } from "react";
import escapeHTML from 'escape-html'; import escapeHTML from "escape-html";
import { Text } from 'slate'; import { Text } from "slate";
const serialize = (children) => children.map((node, i) => { const serialize = (children) =>
if (Text.isText(node)) { children.map((node, i) => {
let text = <span dangerouslySetInnerHTML={{ __html: escapeHTML(node.text) }} />; if (Text.isText(node)) {
let text = (
if (node.bold) { <span dangerouslySetInnerHTML={{ __html: escapeHTML(node.text) }} />
text = (
<strong key={i}>
{text}
</strong>
); );
if (node.bold) {
text = <strong key={i}>{text}</strong>;
}
if (node.code) {
text = <code key={i}>{text}</code>;
}
if (node.italic) {
text = <em key={i}>{text}</em>;
}
// Handle other leaf types here...
return <Fragment key={i}>{text}</Fragment>;
} }
if (node.code) { if (!node) {
text = ( return null;
<code key={i}>
{text}
</code>
);
} }
if (node.italic) { switch (node.type) {
text = ( case "h1":
<em key={i}> return <h1 key={i}>{serialize(node.children)}</h1>;
{text} // Iterate through all headings here...
</em> case "h6":
); return <h6 key={i}>{serialize(node.children)}</h6>;
case "quote":
return <blockquote key={i}>{serialize(node.children)}</blockquote>;
case "ul":
return <ul key={i}>{serialize(node.children)}</ul>;
case "ol":
return <ol key={i}>{serialize(node.children)}</ol>;
case "li":
return <li key={i}>{serialize(node.children)}</li>;
case "link":
return (
<a href={escapeHTML(node.url)} key={i}>
{serialize(node.children)}
</a>
);
default:
return <p key={i}>{serialize(node.children)}</p>;
} }
});
// Handle other leaf types here...
return (
<Fragment key={i}>
{text}
</Fragment>
);
}
if (!node) {
return null;
}
switch (node.type) {
case 'h1':
return (
<h1 key={i}>
{serialize(node.children)}
</h1>
);
// Iterate through all headings here...
case 'h6':
return (
<h6 key={i}>
{serialize(node.children)}
</h6>
);
case 'quote':
return (
<blockquote key={i}>
{serialize(node.children)}
</blockquote>
);
case 'ul':
return (
<ul key={i}>
{serialize(node.children)}
</ul>
);
case 'ol':
return (
<ol key={i}>
{serialize(node.children)}
</ol>
);
case 'li':
return (
<li key={i}>
{serialize(node.children)}
</li>
);
case 'link':
return (
<a
href={escapeHTML(node.url)}
key={i}
>
{serialize(node.children)}
</a>
);
default:
return (
<p key={i}>
{serialize(node.children)}
</p>
);
}
});
``` ```
<Banner> <Banner>
<strong>Note:</strong><br/> <strong>Note:</strong>
The above example is for how to render to JSX, although for plain HTML the pattern is similar. Just remove the JSX and return HTML strings instead! <br />
The above example is for how to render to JSX, although for plain HTML the
pattern is similar. Just remove the JSX and return HTML strings instead!
</Banner> </Banner>

View File

@@ -2,26 +2,28 @@
title: Row Field title: Row Field
label: Row label: Row
order: 130 order: 130
desc: Payload is a headless CMS and application framework. desc: With the Row field you can arrange fields next to each other in the Admin Panel to help you customize your Dashboard.
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Row field is presentational-only and only affects the Admin panel. By using it, you can arrange fields next to each other horizontally. The Row field is presentational-only and only affects the Admin panel. By
using it, you can arrange fields next to each other horizontally.
</Banner> </Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | --------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **`fields`** * | Array of field types to nest within this Row. | | **`fields`** \* | Array of field types to nest within this Row. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. | | **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,44 +2,51 @@
title: Select Field title: Select Field
label: Select label: Select
order: 140 order: 140
desc: Payload is a headless CMS and application framework. desc: The Select field provides a dropdown-style interface for choosing options from a predefined list. Learn how to use Select fields, see examples and options.
keywords: select, multi-select, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: select, multi-select, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Select field provides a dropdown-style interface for choosing options from a predefined list as an enumeration. The Select field provides a dropdown-style interface for choosing options from
a predefined list as an enumeration.
</Banner> </Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`options`** * | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `option` string and a `value` string. | | **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `option` string and a `value` string. |
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many selections instead of only one. | | **`hasMany`** | Boolean when, if set to `true`, allows this field to have many selections instead of only one. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. | | **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. | | **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
<Banner type="warning"> <Banner type="warning">
<strong>Important:</strong><br/> <strong>Important:</strong>
Option values should be strings that do not contain hyphens or special characters due to GraphQL enumeration naming constraints. Underscores are allowed. If you determine you need your option values to be non-strings or contain special characters, they will be formatted accordingly before being used as a GraphQL enum. <br />
Option values should be strings that do not contain hyphens or special
characters due to GraphQL enumeration naming constraints. Underscores are
allowed. If you determine you need your option values to be non-strings or
contain special characters, they will be formatted accordingly before being
used as a GraphQL enum.
</Banner> </Banner>
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,35 +2,36 @@
title: Text Field title: Text Field
label: Text label: Text
order: 150 order: 150
desc: Payload is a headless CMS and application framework. desc: Text field types simply save a string to the database and provide the Admin panel with a text input. Learn how to use Text fields, see examples and options.
keywords: text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Text field type is one of the most commonly used fields. It saves a string to the database and provides the Admin panel with a simple text input. The Text field type is one of the most commonly used fields. It saves a string
to the database and provides the Admin panel with a simple text input.
</Banner> </Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. | | **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. | | **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. | | **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin). | | **`admin`** | Admin-specific configuration. See below for [more detail](#admin). |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Admin config ### Admin config
@@ -47,6 +48,7 @@ Set this property to a string that will be used for browser autocomplete.
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,35 +2,36 @@
title: Textarea Field title: Textarea Field
label: Textarea label: Textarea
order: 160 order: 160
desc: Payload is a headless CMS and application framework. desc: Textarea field types save a string to the database, similar to the Text field type but equipped for longer text. Learn how to use Textarea fields, see examples and options.
keywords: textarea, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: textarea, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Textarea field is almost identical to the Text field but it features a slightly larger input that is better suited to edit longer text. The Textarea field is almost identical to the Text field but it features a
slightly larger input that is better suited to edit longer text.
</Banner> </Banner>
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. | | **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. | | **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. | | **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin). | | **`admin`** | Admin-specific configuration. See below for [more detail](#admin). |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Admin config ### Admin config
@@ -47,6 +48,7 @@ Set this property to a string that will be used for browser autocomplete.
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,17 +2,22 @@
title: Upload Field title: Upload Field
label: Upload label: Upload
order: 170 order: 170
desc: Payload is a headless CMS and application framework. desc: Upload fields will allow a file to be uploaded, only from a collection supporting Uploads. Learn how to use Upload fields, see examples and options.
keywords: upload, images media, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: upload, images media, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner > <Banner>
The Upload field allows for the selection of a Document from a collection supporting Uploads, and formats the selection as a thumbnail in the Admin panel. The Upload field allows for the selection of a Document from a collection
supporting Uploads, and formats the selection as a thumbnail in the Admin
panel.
</Banner> </Banner>
<Banner type="warning"> <Banner type="warning">
<strong>Important:</strong><br/> <strong>Important:</strong>
To use this field, you need to have a Collection configured to allow Uploads. For more information, <a href="/docs/upload/config">click here</a> to read about how to enable Uploads on a collection by collection basis. <br />
To use this field, you need to have a Collection configured to allow Uploads.
For more information, <a href="/docs/upload/config">click here</a> to read
about how to enable Uploads on a collection by collection basis.
</Banner> </Banner>
**Example uses:** **Example uses:**
@@ -23,29 +28,30 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
### Config ### Config
| Option | Description | | Option | Description |
| ---------------- | ----------- | | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** * | To be used as the property name when stored and retrieved from the database. | | **`name`** \* | To be used as the property name when stored and retrieved from the database. |
| **`*relationTo`** * | Provide a single collection `slug` to allow this field to accept a relation to. <strong>Note: the related collection must be configured to support Uploads.</strong> | | **`*relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. <strong>Note: the related collection must be configured to support Uploads.</strong> |
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. | | **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. |
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. | | **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. | | **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) | | **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. | | **`index`** | Build a [MongoDB index](https://docs.mongodb.com/manual/indexes/) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. | | **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) | | **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) | | **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. | | **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
| **`defaultValue`** | Provide data to be used for this field's default value. | | **`defaultValue`** | Provide data to be used for this field's default value. |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. | | **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
| **`required`** | Require this field to have a value. | | **`required`** | Require this field to have a value. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. | | **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
*\* An asterisk denotes that a property is required.* _\* An asterisk denotes that a property is required._
### Example ### Example
`collections/ExampleCollection.js` `collections/ExampleCollection.js`
```js ```js
{ {
slug: 'example-collection', slug: 'example-collection',

View File

@@ -2,7 +2,7 @@
title: Payload Concepts title: Payload Concepts
label: Concepts label: Concepts
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: Payload is based around a small and intuitive set of concepts. Key concepts include collections, globals, fields and more.
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -11,7 +11,7 @@ Payload is based around a small and intuitive set of concepts. Before starting t
### Config ### Config
<Banner type="info"> <Banner type="info">
The Payload config is where you configure everything that Payload does. The Payload config is where you configure everything that Payload does.
</Banner> </Banner>
By default, the Payload config lives in the root folder of your code and is named `payload.config.js` (`payload.config.ts` if you're using TypeScript), but you can customize its name and where you store it. You can write full functions and even full React components right into your config. By default, the Payload config lives in the root folder of your code and is named `payload.config.js` (`payload.config.ts` if you're using TypeScript), but you can customize its name and where you store it. You can write full functions and even full React components right into your config.
@@ -19,7 +19,8 @@ By default, the Payload config lives in the root folder of your code and is name
### Collections ### Collections
<Banner type="info"> <Banner type="info">
A Collection represents a type of content that Payload will store and can contain many documents. A Collection represents a type of content that Payload will store and can
contain many documents.
</Banner> </Banner>
Collections define the shape of your data as well as all functionalities attached to that data. They will contain or many "documents", all corresponding with the same fields and functionalities that you define. Collections define the shape of your data as well as all functionalities attached to that data. They will contain or many "documents", all corresponding with the same fields and functionalities that you define.
@@ -29,7 +30,8 @@ They can represent anything you can store in a database - for example - pages, p
### Globals ### Globals
<Banner type="info"> <Banner type="info">
A Global is a "one-off" piece of content that is perfect for storing navigational structures, themes, top-level meta data, and more. A Global is a "one-off" piece of content that is perfect for storing
navigational structures, themes, top-level meta data, and more.
</Banner> </Banner>
Globals are in many ways similar to Collections, but there is only ever **one** instance of a Global, whereas Collections can contain many documents. Globals are in many ways similar to Collections, but there is only ever **one** instance of a Global, whereas Collections can contain many documents.
@@ -37,7 +39,8 @@ Globals are in many ways similar to Collections, but there is only ever **one**
### Fields ### Fields
<Banner type="info"> <Banner type="info">
Fields are the building blocks of Payload. Collections and Globals both use Fields to define the shape of the data that they store. Fields are the building blocks of Payload. Collections and Globals both use
Fields to define the shape of the data that they store.
</Banner> </Banner>
Payload comes with [many different field types](../fields/overview) that give you a ton of flexibility while designing your API. Each Field type has its own potential properties that allow you to customize how they work. Payload comes with [many different field types](../fields/overview) that give you a ton of flexibility while designing your API. Each Field type has its own potential properties that allow you to customize how they work.
@@ -45,7 +48,8 @@ Payload comes with [many different field types](../fields/overview) that give yo
### Hooks ### Hooks
<Banner type="info"> <Banner type="info">
Hooks are where you can "tie in" to existing Payload actions to perform your own additional logic or modify how Payload operates altogether. Hooks are where you can "tie in" to existing Payload actions to perform your
own additional logic or modify how Payload operates altogether.
</Banner> </Banner>
Hooks are an extremely powerful concept and are central to extending and customizing your app. Payload provides a wide variety of hooks which you can utilize. For example, imagine if you'd like to send an email every time a document is created in your Orders collection. To do so, you can add an `afterChange` hook function to your Orders collection that receives the Order data and allows you to send an email accordingly. Hooks are an extremely powerful concept and are central to extending and customizing your app. Payload provides a wide variety of hooks which you can utilize. For example, imagine if you'd like to send an email every time a document is created in your Orders collection. To do so, you can add an `afterChange` hook function to your Orders collection that receives the Order data and allows you to send an email accordingly.
@@ -55,7 +59,8 @@ There are many more potential reasons to use Hooks. For more, visit the [Hooks d
### Access Control ### Access Control
<Banner type="info"> <Banner type="info">
Access Control refers to Payload's system of defining who can do what to your API. Access Control refers to Payload's system of defining who can do what to your
API.
</Banner> </Banner>
Access Control is extremely powerful but easy and intuitive to manage. You can easily define your own full-blown RBAC (role-based access control) or any other access control pattern that your scenario requires. No conventions or structure is forced on you whatsoever. Access Control is extremely powerful but easy and intuitive to manage. You can easily define your own full-blown RBAC (role-based access control) or any other access control pattern that your scenario requires. No conventions or structure is forced on you whatsoever.
@@ -65,10 +70,11 @@ For more, visit the [Access Control documentation](/docs/access-control/overview
### Depth ### Depth
<Banner type="info"> <Banner type="info">
"Depth" gives you control over how many levels down related documents should be automatically populated when retrieved. "Depth" gives you control over how many levels down related documents should
be automatically populated when retrieved.
</Banner> </Banner>
You can specify population `depth` via query parameter in the REST API and by an option in the local API. *Depth has no effect in the GraphQL API, because there, depth is based on the shape of your queries.* You can specify population `depth` via query parameter in the REST API and by an option in the local API. _Depth has no effect in the GraphQL API, because there, depth is based on the shape of your queries._
**For example, let's look the following Collections:** `departments`, `users`, `posts` **For example, let's look the following Collections:** `departments`, `users`, `posts`

View File

@@ -2,7 +2,7 @@
title: Installation title: Installation
label: Installation label: Installation
order: 30 order: 30
desc: Payload is a headless CMS and application framework. desc: How do I install Payload CMS? To quickly get started with Payload, simply run npx create-payload-app. Read more for further instructions or to install from scratch.
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express
--- ---

View File

@@ -2,7 +2,7 @@
title: What is Payload? title: What is Payload?
label: What is Payload? label: What is Payload?
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: What is Payload? Payload is a next-gen headless CMS and application framework, equipped with dozens of features to provide a massive boost to your development process.
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express
--- ---

View File

@@ -2,7 +2,7 @@
title: Adding your own Queries and Mutations title: Adding your own Queries and Mutations
label: Custom Queries and Mutations label: Custom Queries and Mutations
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: Payload allows you to add your own GraphQL queries and mutations, simply set up GraphQL in your main Payload config by following these instructions.
keywords: graphql, resolvers, mutations, custom, queries, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: graphql, resolvers, mutations, custom, queries, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -10,10 +10,10 @@ You can add your own GraphQL queries and mutations to Payload, making use of all
To do so, add your queries and mutations to the main Payload config as follows: To do so, add your queries and mutations to the main Payload config as follows:
| Config Path | Description | | Config Path | Description |
| -------------------- | -------------| | ------------------- | --------------------------------------------------------------------------- |
| `graphQL.queries` | Function that returns an object containing keys to custom GraphQL queries | | `graphQL.queries` | Function that returns an object containing keys to custom GraphQL queries |
| `graphQL.mutations` | Function that returns an object containing keys to custom GraphQL mutations | | `graphQL.mutations` | Function that returns an object containing keys to custom GraphQL mutations |
The above properties each receive a function that is defined with the following arguments: The above properties each receive a function that is defined with the following arguments:
@@ -34,18 +34,18 @@ Both `graphQL.queries` and `graphQL.mutations` functions should return an object
`payload.config.js`: `payload.config.js`:
```js ```js
import { buildConfig } from 'payload/config'; import { buildConfig } from "payload/config";
import myCustomQueryResolver from './graphQL/resolvers/myCustomQueryResolver'; import myCustomQueryResolver from "./graphQL/resolvers/myCustomQueryResolver";
export default buildConfig({ export default buildConfig({
serverURL: 'http://localhost:3000', serverURL: "http://localhost:3000",
graphQL: { graphQL: {
// highlight-start // highlight-start
queries: (GraphQL, payload) => { queries: (GraphQL, payload) => {
return { return {
MyCustomQuery: { MyCustomQuery: {
type: new GraphQL.GraphQLObjectType({ type: new GraphQL.GraphQLObjectType({
name: 'MyCustomQuery', name: "MyCustomQuery",
fields: { fields: {
text: { text: {
type: GraphQL.GraphQLString, type: GraphQL.GraphQLString,
@@ -57,14 +57,14 @@ export default buildConfig({
args: { args: {
argNameHere: { argNameHere: {
type: new GraphQL.GraphQLNonNull(GraphQLString), type: new GraphQL.GraphQLNonNull(GraphQLString),
} },
}, },
resolve: myCustomQueryResolver, resolve: myCustomQueryResolver,
}) }),
} },
} };
} },
// highlight-end // highlight-end
} },
}) });
``` ```

View File

@@ -2,7 +2,7 @@
title: GraphQL Overview title: GraphQL Overview
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Payload ships with a fully featured and extensible GraphQL API, which can be used in addition to the REST and Local APIs to give you more flexibility.
keywords: graphql, resolvers, mutations, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: graphql, resolvers, mutations, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---

View File

@@ -2,7 +2,7 @@
title: Collection Hooks title: Collection Hooks
label: Collections label: Collections
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: You can add hooks to any Collection, several hook types are available including beforeChange, afterRead, afterDelete and more.
keywords: hooks, collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: hooks, collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -27,6 +27,7 @@ Additionally, `auth`-enabled collections feature the following hooks:
All collection Hook properties accept arrays of synchronous or asynchronous functions. Each Hook type receives specific arguments and has the ability to modify specific outputs. All collection Hook properties accept arrays of synchronous or asynchronous functions. Each Hook type receives specific arguments and has the ability to modify specific outputs.
`collections/example-hooks.js` `collections/example-hooks.js`
```js ```js
// Collection config // Collection config
module.exports = { module.exports = {
@@ -63,7 +64,7 @@ const beforeOperationHook = async ({
operation, // name of the operation operation, // name of the operation
}) => { }) => {
return args; // Return operation arguments as necessary return args; // Return operation arguments as necessary
} };
``` ```
### beforeValidate ### beforeValidate
@@ -78,7 +79,7 @@ const beforeValidateHook = async ({
originalDoc, // original document originalDoc, // original document
}) => { }) => {
return data; // Return data to either create or update a document with return data; // Return data to either create or update a document with
} };
``` ```
### beforeChange ### beforeChange
@@ -93,7 +94,7 @@ const beforeChangeHook = async ({
originalDoc, // original document originalDoc, // original document
}) => { }) => {
return data; // Return data to either create or update a document with return data; // Return data to either create or update a document with
} };
``` ```
### afterChange ### afterChange
@@ -107,7 +108,7 @@ const afterChangeHook = async ({
operation, // name of the operation ie. 'create', 'update' operation, // name of the operation ie. 'create', 'update'
}) => { }) => {
return data; return data;
} };
``` ```
### beforeRead ### beforeRead
@@ -121,7 +122,7 @@ const beforeReadHook = async ({
query, // JSON formatted query query, // JSON formatted query
}) => { }) => {
return doc; return doc;
} };
``` ```
### afterRead ### afterRead
@@ -135,7 +136,7 @@ const afterReadHook = async ({
query, // JSON formatted query query, // JSON formatted query
}) => { }) => {
return doc; return doc;
} };
``` ```
### beforeDelete ### beforeDelete
@@ -172,7 +173,7 @@ const afterLoginHook = async ({
token, // user token token, // user token
}) => { }) => {
return user; return user;
} };
``` ```
### afterForgotPassword ### afterForgotPassword
@@ -186,5 +187,5 @@ const afterLoginHook = async ({
token, // user token token, // user token
}) => { }) => {
return user; return user;
} };
``` ```

View File

@@ -2,7 +2,7 @@
title: Field Hooks title: Field Hooks
label: Fields label: Fields
order: 30 order: 30
desc: Payload is a headless CMS and application framework. desc: Hooks can be added to any fields, and optionally modify the return value of the field before the operation continues.
keywords: hooks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: hooks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -26,6 +26,7 @@ Field-level hooks offer incredible potential for encapsulating your logic. They
## Config ## Config
Example field configuration: Example field configuration:
```js ```js
{ {
name: 'name', name: 'name',
@@ -47,27 +48,33 @@ Example field configuration:
All field-level hooks are formatted to accept the same arguments, although some arguments may be `undefined` based on which field hook you are utilizing. All field-level hooks are formatted to accept the same arguments, although some arguments may be `undefined` based on which field hook you are utilizing.
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br /> <strong>Tip:</strong>
It's a good idea to conditionally scope your logic based on which operation is executing. <br />
It's a good idea to conditionally scope your logic based on which operation is
executing.
</Banner> </Banner>
#### Arguments #### Arguments
Field Hooks receive one `args` argument that contains the following properties: Field Hooks receive one `args` argument that contains the following properties:
| Option | Description | | Option | Description |
| ----------------- | -------------| | ----------------- | ------------------------------------------------------------------------------------------------ |
| **`value`** | The value of the field, before any updating. Will return `undefined` within `create` operations. | | **`value`** | The value of the field, before any updating. Will return `undefined` within `create` operations. |
| **`data`** | The data passed to update the field with in `create` and `update` operations. | | **`data`** | The data passed to update the field with in `create` and `update` operations. |
| **`originalDoc`** | The full original document in `update` or `read` operations. | | **`originalDoc`** | The full original document in `update` or `read` operations. |
| **`operation`** | A string relating to which operation the field type is currently executing within. | | **`operation`** | A string relating to which operation the field type is currently executing within. |
| **`req`** | The Express `request` object. It is mocked for Local API operations. | | **`req`** | The Express `request` object. It is mocked for Local API operations. |
#### Return value #### Return value
Field hooks **must** return the intended value for the field to be used in the operation. You can modify the return value of the field before the operation continues, or simply send the `value` that you receive through the hook's argument. If you return `undefined` within a `beforeChange` or `beforeValidate` hook, the property will be unset from its document. Field hooks **must** return the intended value for the field to be used in the operation. You can modify the return value of the field before the operation continues, or simply send the `value` that you receive through the hook's argument. If you return `undefined` within a `beforeChange` or `beforeValidate` hook, the property will be unset from its document.
<Banner type="warning"> <Banner type="warning">
<strong>Important</strong><br/> <strong>Important</strong>
Due to GraphQL's typed nature, you should never change the type of data that you return from a field, otherwise GraphQL will produce errors. If you need to change the shape or type of data, reconsider Field Hooks and instead evaluate if Collection / Global hooks might suit you better. <br />
Due to GraphQL's typed nature, you should never change the type of data that
you return from a field, otherwise GraphQL will produce errors. If you need to
change the shape or type of data, reconsider Field Hooks and instead evaluate
if Collection / Global hooks might suit you better.
</Banner> </Banner>

View File

@@ -2,7 +2,7 @@
title: Global Hooks title: Global Hooks
label: Globals label: Globals
order: 40 order: 40
desc: Payload is a headless CMS and application framework. desc: Hooks can be added to any Global and allow you to validate data, flatten locales, hide protected fields, remove fields and more.
keywords: hooks, globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: hooks, globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -19,6 +19,7 @@ Globals feature the ability to define the following hooks:
All Global Hook properties accept arrays of synchronous or asynchronous functions. Each Hook type receives specific arguments and has the ability to modify specific outputs. All Global Hook properties accept arrays of synchronous or asynchronous functions. Each Hook type receives specific arguments and has the ability to modify specific outputs.
`globals/example-hooks.js` `globals/example-hooks.js`
```js ```js
// Global config // Global config
module.exports = { module.exports = {
@@ -48,7 +49,7 @@ const beforeValidateHook = async ({
originalDoc, // original document originalDoc, // original document
}) => { }) => {
return data; // Return data to either create or update a document with return data; // Return data to either create or update a document with
} };
``` ```
### beforeChange ### beforeChange
@@ -63,7 +64,7 @@ const beforeChangeHook = async ({
originalDoc, // original document originalDoc, // original document
}) => { }) => {
return data; // Return data to either create or update a document with return data; // Return data to either create or update a document with
} };
``` ```
### afterChange ### afterChange
@@ -77,7 +78,7 @@ const afterChangeHook = async ({
operation, // name of the operation ie. 'create', 'update' operation, // name of the operation ie. 'create', 'update'
}) => { }) => {
return data; return data;
} };
``` ```
### beforeRead ### beforeRead

View File

@@ -2,12 +2,14 @@
title: Hooks Overview title: Hooks Overview
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Hooks allow you to add your own logic to Payload, including integrating with third-party APIs, adding auto-generated data, or modifing Payload's base functionality.
keywords: hooks, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: hooks, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner type="info"> <Banner type="info">
Hooks are powerful ways to tie into existing Payload actions in order to add your own logic like integrating with third-party APIs, adding auto-generated data, or modifing Payload's base functionality. Hooks are powerful ways to tie into existing Payload actions in order to add
your own logic like integrating with third-party APIs, adding auto-generated
data, or modifing Payload's base functionality.
</Banner> </Banner>
**With Hooks, you can transform Payload from a traditional CMS into a fully-fledged application framework.** **With Hooks, you can transform Payload from a traditional CMS into a fully-fledged application framework.**

View File

@@ -2,15 +2,21 @@
title: Local API title: Local API
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: The Payload Local API allows you to interact with your database and execute the same operations that are available through REST and GraphQL within Node, directly on your server.
keywords: local api, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: local api, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
The Payload Local API gives you the ability to execute the same operations that are available through REST and GraphQL within Node, directly on your server. Here, you don't need to deal with server latency or network speed whatsoever and can interact directly with your database. The Payload Local API gives you the ability to execute the same operations that are available through REST and GraphQL within Node, directly on your server. Here, you don't need to deal with server latency or network speed whatsoever and can interact directly with your database.
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br/> <strong>Tip:</strong>
The Local API is incredibly powerful when used with server-side rendering app frameworks like NextJS. With other headless CMS, you need to request your data from third-party servers which can add significant loading time to your server-rendered pages. With Payload, you don't have to leave your server to gather the data you need. It can be incredibly fast and is definitely a game changer. <br />
The Local API is incredibly powerful when used with server-side rendering app
frameworks like NextJS. With other headless CMS, you need to request your data
from third-party servers which can add significant loading time to your
server-rendered pages. With Payload, you don't have to leave your server to
gather the data you need. It can be incredibly fast and is definitely a game
changer.
</Banner> </Banner>
Here are some common examples of how you can use the Local API: Here are some common examples of how you can use the Local API:
@@ -28,14 +34,15 @@ You can gain access to the currently running `payload` object via two ways:
You can import or require `payload` into your own files after it's been initialized, but you need to make sure that your `import` / `require` statements come **after** you call `payload.init()`—otherwise Payload won't have been initialized yet. That might be obvious. To us, it's usually not. You can import or require `payload` into your own files after it's been initialized, but you need to make sure that your `import` / `require` statements come **after** you call `payload.init()`—otherwise Payload won't have been initialized yet. That might be obvious. To us, it's usually not.
Example: Example:
```js ```js
import payload from 'payload'; import payload from "payload";
const afterChangeHook = async () => { const afterChangeHook = async () => {
const posts = await payload.find({ const posts = await payload.find({
collection: 'posts', collection: "posts",
}); });
} };
``` ```
##### Accessing from the `req` ##### Accessing from the `req`
@@ -43,34 +50,38 @@ const afterChangeHook = async () => {
Payload is available anywhere you have access to the Express `req` - including within your access control and hook functions. Payload is available anywhere you have access to the Express `req` - including within your access control and hook functions.
Example: Example:
```js ```js
const afterChangeHook = async ({ req: { payload }}) => { const afterChangeHook = async ({ req: { payload } }) => {
const posts = await payload.find({ const posts = await payload.find({
collection: 'posts', collection: "posts",
}); });
} };
``` ```
### Local options available ### Local options available
You can specify more options within the Local API vs. REST or GraphQL due to the server-only context that they are executed in. You can specify more options within the Local API vs. REST or GraphQL due to the server-only context that they are executed in.
| Local Option | Description | | Local Option | Description |
| -------------------- | ------------ | | ------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `collection` | Required for Collection operations. Specifies the Collection slug to operate against. | | `collection` | Required for Collection operations. Specifies the Collection slug to operate against. |
| `data` | The data to use within the operation. Required for `create`, `update`. | | `data` | The data to use within the operation. Required for `create`, `update`. |
| `depth` | [Control auto-population](/docs/getting-started/concepts#depth) of nested relationship and upload fields. | | `depth` | [Control auto-population](/docs/getting-started/concepts#depth) of nested relationship and upload fields. |
| `locale` | Specify [locale](/docs/configuration/localization) for any returned documents. | | `locale` | Specify [locale](/docs/configuration/localization) for any returned documents. |
| `fallbackLocale` | Specify a [fallback locale](/docs/configuration/localization) to use for any returned documents. | | `fallbackLocale` | Specify a [fallback locale](/docs/configuration/localization) to use for any returned documents. |
| `overrideAccess` | Skip access control. By default, this property is set to false. | | `overrideAccess` | Skip access control. By default, this property is set to false. |
| `user` | If you re-enable access control, you can specify a user to use against the access control checks. | | `user` | If you re-enable access control, you can specify a user to use against the access control checks. |
| `showHiddenFields` | Opt-in to receiving hidden fields. By default, they are hidden from returned documents in accordance to your config. | | `showHiddenFields` | Opt-in to receiving hidden fields. By default, they are hidden from returned documents in accordance to your config. |
*There are more options available on an operation by operation basis outlined below.* _There are more options available on an operation by operation basis outlined below._
<Banner type="warning"> <Banner type="warning">
<strong>Note:</strong><br/> <strong>Note:</strong>
By default, all access control checks are disabled in the Local API, but you can re-enable them if you'd like, as well as pass a specific user to run the operation with. <br />
By default, all access control checks are disabled in the Local API, but you
can re-enable them if you'd like, as well as pass a specific user to run the
operation with.
</Banner> </Banner>
## Collections ## Collections
@@ -82,12 +93,13 @@ The following Collection operations are available through the Local API:
```js ```js
// The created Post document is returned // The created Post document is returned
const post = await payload.create({ const post = await payload.create({
collection: 'posts', // required collection: "posts", // required
data: { // required data: {
title: 'sure', // required
description: 'maybe', title: "sure",
description: "maybe",
}, },
locale: 'en', locale: "en",
fallbackLocale: false, fallbackLocale: false,
user: dummyUserDoc, user: dummyUserDoc,
overrideAccess: true, overrideAccess: true,
@@ -96,7 +108,7 @@ const post = await payload.create({
// If creating verification-enabled auth doc, // If creating verification-enabled auth doc,
// you can optionally disable the email that is auto-sent // you can optionally disable the email that is auto-sent
disableVerificationEmail: true, disableVerificationEmail: true,
}) });
``` ```
#### Find #### Find
@@ -124,15 +136,15 @@ const result = await payload.find({
```js ```js
// Result will be a Post document. // Result will be a Post document.
const result = await payload.findByID({ const result = await payload.findByID({
collection: 'posts', // required collection: "posts", // required
id: '507f1f77bcf86cd799439011', // required id: "507f1f77bcf86cd799439011", // required
depth: 2, depth: 2,
locale: 'en', locale: "en",
fallbackLocale: false, fallbackLocale: false,
user: dummyUser, user: dummyUser,
overrideAccess: false, overrideAccess: false,
showHiddenFields: true, showHiddenFields: true,
}) });
``` ```
#### Update #### Update
@@ -140,19 +152,20 @@ const result = await payload.findByID({
```js ```js
// Result will be the updated Post document. // Result will be the updated Post document.
const result = await payload.update({ const result = await payload.update({
collection: 'posts', // required collection: "posts", // required
id: '507f1f77bcf86cd799439011', // required id: "507f1f77bcf86cd799439011", // required
data: { // required data: {
title: 'sure', // required
description: 'maybe', title: "sure",
description: "maybe",
}, },
depth: 2, depth: 2,
locale: 'en', locale: "en",
fallbackLocale: false, fallbackLocale: false,
user: dummyUser, user: dummyUser,
overrideAccess: false, overrideAccess: false,
showHiddenFields: true, showHiddenFields: true,
}) });
``` ```
#### Delete #### Delete
@@ -160,15 +173,15 @@ const result = await payload.update({
```js ```js
// Result will be the now-deleted Post document. // Result will be the now-deleted Post document.
const result = await payload.delete({ const result = await payload.delete({
collection: 'posts', // required collection: "posts", // required
id: '507f1f77bcf86cd799439011', // required id: "507f1f77bcf86cd799439011", // required
depth: 2, depth: 2,
locale: 'en', locale: "en",
fallbackLocale: false, fallbackLocale: false,
user: dummyUser, user: dummyUser,
overrideAccess: false, overrideAccess: false,
showHiddenFields: true, showHiddenFields: true,
}) });
``` ```
## Auth Operations ## Auth Operations
@@ -186,19 +199,20 @@ If a collection has [`Authentication`](/docs/authentication/overview) enabled, a
// } // }
const result = await payload.login({ const result = await payload.login({
collection: 'users', // required collection: "users", // required
data: { // required data: {
email: 'dev@payloadcms.com', // required
password: 'rip', email: "dev@payloadcms.com",
password: "rip",
}, },
req: req, // pass an Express `req` which will be provided to all hooks req: req, // pass an Express `req` which will be provided to all hooks
res: res, // used to automatically set an HTTP-only auth cookie res: res, // used to automatically set an HTTP-only auth cookie
depth: 2, depth: 2,
locale: 'en', locale: "en",
fallbackLocale: false, fallbackLocale: false,
overrideAccess: false, overrideAccess: false,
showHiddenFields: true, showHiddenFields: true,
}) });
``` ```
#### Forgot Password #### Forgot Password
@@ -206,12 +220,13 @@ const result = await payload.login({
```js ```js
// Returned token will allow for a password reset // Returned token will allow for a password reset
const token = await payload.forgotPassword({ const token = await payload.forgotPassword({
collection: 'users', // required collection: "users", // required
data: { // required data: {
email: 'dev@payloadcms.com', // required
email: "dev@payloadcms.com",
}, },
req: req, // pass an Express `req` which will be provided to all hooks req: req, // pass an Express `req` which will be provided to all hooks
}) });
``` ```
#### Reset Password #### Reset Password
@@ -223,13 +238,14 @@ const token = await payload.forgotPassword({
// user: { ... } // the user document that just logged in // user: { ... } // the user document that just logged in
// } // }
const result = await payload.forgotPassword({ const result = await payload.forgotPassword({
collection: 'users', // required collection: "users", // required
data: { // required data: {
token: 'afh3o2jf2p3f...', // the token generated from the forgotPassword operation // required
token: "afh3o2jf2p3f...", // the token generated from the forgotPassword operation
}, },
req: req, // pass an Express `req` which will be provided to all hooks req: req, // pass an Express `req` which will be provided to all hooks
res: res, // used to automatically set an HTTP-only auth cookie res: res, // used to automatically set an HTTP-only auth cookie
}) });
``` ```
#### Unlock #### Unlock
@@ -237,13 +253,14 @@ const result = await payload.forgotPassword({
```js ```js
// Returned result will be a boolean representing success or failure // Returned result will be a boolean representing success or failure
const result = await payload.unlock({ const result = await payload.unlock({
collection: 'users', // required collection: "users", // required
data: { // required data: {
email: 'dev@payloadcms.com', // required
email: "dev@payloadcms.com",
}, },
req: req, // pass an Express `req` which will be provided to all hooks req: req, // pass an Express `req` which will be provided to all hooks
overrideAccess: true, overrideAccess: true,
}) });
``` ```
#### Verify #### Verify
@@ -251,9 +268,9 @@ const result = await payload.unlock({
```js ```js
// Returned result will be a boolean representing success or failure // Returned result will be a boolean representing success or failure
const result = await payload.verify({ const result = await payload.verify({
collection: 'users', // required collection: "users", // required
token: 'afh3o2jf2p3f...', // the token saved on the user as `_verificationToken` token: "afh3o2jf2p3f...", // the token saved on the user as `_verificationToken`
}) });
``` ```
## Globals ## Globals
@@ -265,14 +282,14 @@ The following Global operations are available through the Local API:
```js ```js
// Result will be the Header Global. // Result will be the Header Global.
const result = await payload.findGlobal({ const result = await payload.findGlobal({
global: 'header', // required global: "header", // required
depth: 2, depth: 2,
locale: 'en', locale: "en",
fallbackLocale: false, fallbackLocale: false,
user: dummyUser, user: dummyUser,
overrideAccess: false, overrideAccess: false,
showHiddenFields: true, showHiddenFields: true,
}) });
``` ```
#### Update #### Update
@@ -280,22 +297,23 @@ const result = await payload.findGlobal({
```js ```js
// Result will be the updated Header Global. // Result will be the updated Header Global.
const result = await payload.updateGlobal({ const result = await payload.updateGlobal({
global: 'header', // required global: "header", // required
data: { // required data: {
// required
nav: [ nav: [
{ {
url: 'https://google.com', url: "https://google.com",
}, },
{ {
url: 'https://payloadcms.com', url: "https://payloadcms.com",
}, },
], ],
}, },
depth: 2, depth: 2,
locale: 'en', locale: "en",
fallbackLocale: false, fallbackLocale: false,
user: dummyUser, user: dummyUser,
overrideAccess: false, overrideAccess: false,
showHiddenFields: true, showHiddenFields: true,
}) });
``` ```

View File

@@ -2,12 +2,14 @@
title: Production Deployment title: Production Deployment
label: Deployment label: Deployment
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: When your Payload based app is ready, tested, looking great, it is time to deploy. Learn how to deploy your app and what to consider before deployment.
keywords: deployment, production, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: deployment, production, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner type="success"> <Banner type="success">
So you've developed a Payload app, it's fully tested, and running great locally. Now it's time to launch. <strong>Awesome! Great work!</strong> Now, what's next? So you've developed a Payload app, it's fully tested, and running great
locally. Now it's time to launch. <strong>Awesome! Great work!</strong> Now,
what's next?
</Banner> </Banner>
There are many ways to deploy Payload to a production environment. When evaluating how you will deploy Payload, you need to consider these main aspects: There are many ways to deploy Payload to a production environment. When evaluating how you will deploy Payload, you need to consider these main aspects:
@@ -29,7 +31,13 @@ When you initialize Payload, you provide it with a `secret` property. This prope
Because _**you**_ are in complete control of who can do what with your data, you should double and triple-check that you wield that power responsibly before deploying to Production. Because _**you**_ are in complete control of who can do what with your data, you should double and triple-check that you wield that power responsibly before deploying to Production.
<Banner type="error"> <Banner type="error">
<strong>By default, all Access Control functions require that a user is successfully logged in to Payload to create, read, update, or delete data.</strong> But, if you allow public user registration, for example, you will want to make sure that your access control functions are more strict - permitting <strong>only appropriate users</strong> to perform appropriate actions. <strong>
By default, all Access Control functions require that a user is successfully
logged in to Payload to create, read, update, or delete data.
</strong>{" "}
But, if you allow public user registration, for example, you will want to make
sure that your access control functions are more strict - permitting{" "}
<strong>only appropriate users</strong> to perform appropriate actions.
</Banner> </Banner>
##### Building the Admin panel ##### Building the Admin panel
@@ -37,6 +45,7 @@ Because _**you**_ are in complete control of who can do what with your data, you
Before running in Production, you need to have built a production-ready copy of the Payload Admin panel. To do this, Payload provides the `build` NPM script. You can use it by adding a `script` to your `package.json` file like this: Before running in Production, you need to have built a production-ready copy of the Payload Admin panel. To do this, Payload provides the `build` NPM script. You can use it by adding a `script` to your `package.json` file like this:
`package.json`: `package.json`:
```js ```js
{ {
"name": "project-name-here", "name": "project-name-here",
@@ -95,15 +104,18 @@ Alternatively, persistent filesystems will never delete your files and can be tr
- Many other more traditional web hosts - Many other more traditional web hosts
<Banner type="error"> <Banner type="error">
<strong>Warning:</strong><br/> <strong>Warning:</strong>
If you rely on Payload's <strong>Upload</strong> functionality, make sure you either use a host with a persistent filesystem or have an integration with a third-party file host like Amazon S3. <br />
If you rely on Payload's <strong>Upload</strong> functionality, make sure you
either use a host with a persistent filesystem or have an integration with a
third-party file host like Amazon S3.
</Banner> </Banner>
##### Using ephemeral filesystem providers like Heroku ##### Using ephemeral filesystem providers like Heroku
If you don't use Payload's `upload` functionality, you can go ahead and use Heroku or similar platform easily. Everything will work exactly as you want it to. If you don't use Payload's `upload` functionality, you can go ahead and use Heroku or similar platform easily. Everything will work exactly as you want it to.
But, if you do, and you still want to use an ephemeral filesystem provider, you can write a hook-based solution to *copy* the files your users upload to a more permanent storage solution like Amazon S3 or DigitalOcean Spaces. But, if you do, and you still want to use an ephemeral filesystem provider, you can write a hook-based solution to _copy_ the files your users upload to a more permanent storage solution like Amazon S3 or DigitalOcean Spaces.
**To automatically send uploaded files to S3 or similar, you could:** **To automatically send uploaded files to S3 or similar, you could:**

View File

@@ -2,7 +2,7 @@
title: The Payload License title: The Payload License
label: Licensing label: Licensing
order: 30 order: 30
desc: Payload is a headless CMS and application framework. desc: Payload is free to use locally for development purposes. You can purchase a license when you are ready to deploy, or to receive support from Payload developers.
keywords: licensing, production, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: licensing, production, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -16,8 +16,9 @@ Payload is free to use locally for development purposes for as long as you like.
1. Add your license to a `.env` variable, and then add the `license` property to your `payload.init()` call. 1. Add your license to a `.env` variable, and then add the `license` property to your `payload.init()` call.
`server.js`: `server.js`:
```js ```js
const payload = require('payload'); const payload = require("payload");
payload.init({ payload.init({
license: process.env.PAYLOAD_LICENSE_KEY, license: process.env.PAYLOAD_LICENSE_KEY,
@@ -32,13 +33,17 @@ payload.init({
Payload licensing is enforced only through its Admin panel. Each time the Admin panel is loaded, a request is made to our licensing server that evaluates the domain that the panel was loaded from. We then verify that you have a valid, active license key and that the domain being used matches the license accordingly. Payload licensing is enforced only through its Admin panel. Each time the Admin panel is loaded, a request is made to our licensing server that evaluates the domain that the panel was loaded from. We then verify that you have a valid, active license key and that the domain being used matches the license accordingly.
<Banner type="success"> <Banner type="success">
<strong>Note:</strong><br/> <strong>Note:</strong>
Your Payload APIs will always be available, regardless of subscription status. This means you can have peace of mind that your critical operations relying on your API will not going to be hindered because of a lapse in billing issue or a network problem between systems. Only the Admin panel will be affected. <br />
Your Payload APIs will always be available, regardless of subscription status.
This means you can have peace of mind that your critical operations relying on
your API will not going to be hindered because of a lapse in billing issue or
a network problem between systems. Only the Admin panel will be affected.
</Banner> </Banner>
### How to choose the domain for your license ### How to choose the domain for your license
Payload licenses are specific to **one** domain, but you can use your Payload API from an unlimited amount of sources. However, you can *only access your Payload Admin panel from one domain*. This means that when you are selecting the domain you'd like to tie to your Payload license, you should choose the domain that you'd like to use to access your admin panel in production. Payload licenses are specific to **one** domain, but you can use your Payload API from an unlimited amount of sources. However, you can _only access your Payload Admin panel from one domain_. This means that when you are selecting the domain you'd like to tie to your Payload license, you should choose the domain that you'd like to use to access your admin panel in production.
**Examples:** **Examples:**
@@ -46,8 +51,10 @@ Payload licenses are specific to **one** domain, but you can use your Payload AP
- If you'd like to access via a root-level domain like `coolsitehere.com/admin`, you would use `coolsitehere.com` for your license. - If you'd like to access via a root-level domain like `coolsitehere.com/admin`, you would use `coolsitehere.com` for your license.
<Banner type="success"> <Banner type="success">
<strong>Note:</strong><br/> <strong>Note:</strong>
Even though your Payload license is tied to one domain, you can use your Admin panel for dev purposes however and wherever you'd like. <br />
Even though your Payload license is tied to one domain, you can use your Admin
panel for dev purposes however and wherever you'd like.
</Banner> </Banner>
#### How does Payload know if the license is being used for dev or production purposes? #### How does Payload know if the license is being used for dev or production purposes?
@@ -65,4 +72,5 @@ Our licensing service checks for any of the following criteria to determine if y
1. **Can I transfer a license?** You can change the domain name of a license in your Payload account by clicking on the license domain name, finding the "Change domain" link and following the instructions. If you need to transfer ownership to another user or organization, you can [contact us](mailto:info@payloadcms.com) for help. 1. **Can I transfer a license?** You can change the domain name of a license in your Payload account by clicking on the license domain name, finding the "Change domain" link and following the instructions. If you need to transfer ownership to another user or organization, you can [contact us](mailto:info@payloadcms.com) for help.
### Read the full license ### Read the full license
You can read the entirety of the Payload license directly in the distributed NPM package or in the Payload source code at [github.com](https://github.com/payloadcms/payload/blob/master/license.md) You can read the entirety of the Payload license directly in the distributed NPM package or in the Payload source code at [github.com](https://github.com/payloadcms/payload/blob/master/license.md)

View File

@@ -2,7 +2,7 @@
title: Preventing Production API Abuse title: Preventing Production API Abuse
label: Preventing Abuse label: Preventing Abuse
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: Payload has built-in security that can be configured to combat production API abuse such as limiting login attempts and IP requests.
keywords: abuse, production, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: abuse, production, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -18,16 +18,22 @@ Set the max number of failed login attempts before a user account is locked out
To prevent DDoS, brute-force, and similar attacks, you can set IP-based rate limits so that once a certain threshold of requests has been hit by a single IP, further requests from the same IP will be ignored. The Payload config `rateLimit` property accepts an object with the following properties: To prevent DDoS, brute-force, and similar attacks, you can set IP-based rate limits so that once a certain threshold of requests has been hit by a single IP, further requests from the same IP will be ignored. The Payload config `rateLimit` property accepts an object with the following properties:
| Option | Description | | Option | Description |
| ---------------------------- | -------------| | ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **`window`** | Time in milliseconds to track requests per IP | | **`window`** | Time in milliseconds to track requests per IP |
| **`max`** | Number of requests served from a single IP before limiting | | **`max`** | Number of requests served from a single IP before limiting |
| **`skip`** | Express middleware function that can return true (or promise resulting in true) that will bypass limit | | **`skip`** | Express middleware function that can return true (or promise resulting in true) that will bypass limit |
| **`trustProxy`** | True or false, to enable to allow requests to pass through a proxy such as a load balancer or an `nginx` reverse proxy | | **`trustProxy`** | True or false, to enable to allow requests to pass through a proxy such as a load balancer or an `nginx` reverse proxy |
<Banner type="warning"> <Banner type="warning">
<strong>Warning:</strong><br/> <strong>Warning:</strong>
Very commonly, NodeJS apps are served behind `nginx` reverse proxies and similar. If you use rate-limiting while you're behind a proxy, <strong>all</strong> IP addresses from everyone that uses your API will appear as if they are from a local origin (127.0.0.1), and your users will get rate-limited very quickly without cause. If you plan to host your app behind a proxy, make sure you set <strong>trustProxy</strong> to <strong>true</strong>. <br />
Very commonly, NodeJS apps are served behind `nginx` reverse proxies and
similar. If you use rate-limiting while you're behind a proxy,{" "}
<strong>all</strong> IP addresses from everyone that uses your API will appear
as if they are from a local origin (127.0.0.1), and your users will get
rate-limited very quickly without cause. If you plan to host your app behind a
proxy, make sure you set <strong>trustProxy</strong> to <strong>true</strong>.
</Banner> </Banner>
#### Max Depth #### Max Depth
@@ -43,6 +49,7 @@ CSRF prevention will verify the authenticity of each request to your API to prev
To securely allow headless operation you will need to configure the allowed origins for requests to be able to use the Payload API. You can see how to set CORS as well as other payload configuration settings [here](http://localhost:3000/docs/configuration/overview) To securely allow headless operation you will need to configure the allowed origins for requests to be able to use the Payload API. You can see how to set CORS as well as other payload configuration settings [here](http://localhost:3000/docs/configuration/overview)
### Limiting GraphQL Complexity ### Limiting GraphQL Complexity
Because GraphQL gives the power of query writing outside a server's control, someone with bad intentions might write a maliciously complex query and bog down your server. To prevent resource-intensive GraphQL requests, Payload provides a way specify complexity limits which are based on a complexity score that is calculated for each request. Because GraphQL gives the power of query writing outside a server's control, someone with bad intentions might write a maliciously complex query and bog down your server. To prevent resource-intensive GraphQL requests, Payload provides a way specify complexity limits which are based on a complexity score that is calculated for each request.
Any GraphQL request that is calculated to be too expensive is rejected. On the Payload config, in `graphQL` you can set the `maxComplexity` value as an integer. For reference, the default complexity value for each added field is 1, and all `relationship` and `upload` fields are assigned a value of 10. Any GraphQL request that is calculated to be too expensive is rejected. On the Payload config, in `graphQL` you can set the `maxComplexity` value as an integer. For reference, the default complexity value for each added field is 1, and all `relationship` and `upload` fields are assigned a value of 10.

View File

@@ -2,14 +2,22 @@
title: Querying your Documents title: Querying your Documents
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Payload provides a querying language through all APIs, allowing you to filter or search through documents within a Collection.
keywords: query, documents, overview, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: query, documents, overview, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
Payload provides an extremely granular querying language through all APIs. Each API takes the same syntax and fully supports all options. Payload provides an extremely granular querying language through all APIs. Each API takes the same syntax and fully supports all options.
<Banner> <Banner>
<strong>Here, "querying" relates to filtering or searching through documents within a Collection.</strong> You can build queries to pass to Find operations as well as to <a href="/docs/access-control/overview">restrict which documents certain users can access</a> via access control functions. <strong>
Here, "querying" relates to filtering or searching through documents within
a Collection.
</strong>{" "}
You can build queries to pass to Find operations as well as to{" "}
<a href="/docs/access-control/overview">
restrict which documents certain users can access
</a>{" "}
via access control functions.
</Banner> </Banner>
### Simple queries ### Simple queries
@@ -18,55 +26,54 @@ For example, say you have a collection as follows:
```js ```js
const Post = { const Post = {
slug: 'posts', slug: "posts",
fields: [ fields: [
{ {
name: 'color', name: "color",
type: 'select', type: "select",
options: [ options: ["mint", "dark-gray", "white"],
'mint',
'dark-gray',
'white',
],
}, },
{ {
name: 'featured', name: "featured",
type: 'checkbox', type: "checkbox",
} },
] ],
} };
``` ```
You may eventually have a lot of documents within this Collection. If you wanted to find only documents with `color` equal to `mint`, you could write a query as follows: You may eventually have a lot of documents within this Collection. If you wanted to find only documents with `color` equal to `mint`, you could write a query as follows:
```js ```js
const query = { const query = {
color: { // property name to filter on color: {
equals: 'mint', // operator to use and value to compare against // property name to filter on
equals: "mint", // operator to use and value to compare against
}, },
} };
``` ```
The above example demonstrates a simple query but you can get much more complex. The above example demonstrates a simple query but you can get much more complex.
### Operators ### Operators
| Operator | Description | | Operator | Description |
| -------------------- | ------------ | | -------------------- | ----------------------------------------------------------------------------------------- |
| `equals` | The value must be exactly equal. | | `equals` | The value must be exactly equal. |
| `not_equals` | The query will return all documents where the value is not equal. | | `not_equals` | The query will return all documents where the value is not equal. |
| `greater_than` | For numeric or date-based fields. | | `greater_than` | For numeric or date-based fields. |
| `greater_than_equal` | For numeric or date-based fields. | | `greater_than_equal` | For numeric or date-based fields. |
| `less_than` | For numeric or date-based fields. | | `less_than` | For numeric or date-based fields. |
| `less_than_equal` | For numeric or date-based fields. | | `less_than_equal` | For numeric or date-based fields. |
| `like` | The value must partially match. | | `like` | The value must partially match. |
| `in` | The value must be found within the provided comma-delimited list of values. | | `in` | The value must be found within the provided comma-delimited list of values. |
| `not_in` | The value must NOT be within the provided comma-delimited list of values. | | `not_in` | The value must NOT be within the provided comma-delimited list of values. |
| `exists` | Only return documents where the value either exists (`true`) or does not exist (`false`). | | `exists` | Only return documents where the value either exists (`true`) or does not exist (`false`). |
<Banner type="success"> <Banner type="success">
<strong>Tip</strong>:<br/> <strong>Tip</strong>:<br />
If you know your users will be querying on certain fields a lot, you can add <strong>index: true</strong> to a field's config which will speed up searches using that field immensely. If you know your users will be querying on certain fields a lot, you can add <strong>
index: true
</strong> to a field's config which will speed up searches using that field immensely.
</Banner> </Banner>
### And / Or Logic ### And / Or Logic
@@ -75,28 +82,30 @@ In addition to defining simple queries, you can join multiple queries together u
```js ```js
const query = { const query = {
or: [ // array of OR conditions or: [
// array of OR conditions
{ {
color: { color: {
equals: 'mint', equals: "mint",
}, },
}, },
{ {
and: [ // nested array of AND conditions and: [
// nested array of AND conditions
{ {
color: { color: {
equals: 'white', equals: "white",
} },
}, },
{ {
featured: { featured: {
equals: false, equals: false,
} },
} },
] ],
} },
] ],
} };
``` ```
Written in plain English, if the above query were passed to a `find` operation, it would translate to finding posts where either the `color` is `mint` OR the `color` is `white` AND `featured` is set to false. Written in plain English, if the above query were passed to a `find` operation, it would translate to finding posts where either the `color` is `mint` OR the `color` is `white` AND `featured` is set to false.
@@ -131,24 +140,29 @@ This one isn't too bad, but more complex queries get unavoidably more difficult
**For example, using fetch:** **For example, using fetch:**
```js ```js
import qs from 'qs'; import qs from "qs";
const query = { const query = {
color: { color: {
equals: 'mint', equals: "mint",
}, },
// This query could be much more complex // This query could be much more complex
// and QS would handle it beautifully // and QS would handle it beautifully
} };
const getPosts = async () => { const getPosts = async () => {
const stringifiedQuery = qs.stringify({ const stringifiedQuery = qs.stringify(
where: query // ensure that `qs` adds the `where` property, too! {
}, { addQueryPrefix: true }); where: query, // ensure that `qs` adds the `where` property, too!
},
{ addQueryPrefix: true }
);
const response = await fetch(`http://localhost:3000/api/posts${stringifiedQuery}`); const response = await fetch(
`http://localhost:3000/api/posts${stringifiedQuery}`
);
// Continue to handle the response below... // Continue to handle the response below...
} };
``` ```
### Local API Queries ### Local API Queries
@@ -158,19 +172,18 @@ The Local API's `find` operation accepts an object exactly how you write it. For
```js ```js
const getPosts = async () => { const getPosts = async () => {
const posts = await payload.find({ const posts = await payload.find({
collection: 'posts', collection: "posts",
where: { where: {
color: { color: {
equals: 'mint', equals: "mint",
}, },
}, },
}); });
return posts; return posts;
} };
``` ```
## Sort ## Sort
Payload `find` queries support a `sort` parameter through all APIs. Pass the `name` of a top-level field to sort by that field in ascending order. Prefix the name of the field with a minus symbol ("-") to sort in descending order. Payload `find` queries support a `sort` parameter through all APIs. Pass the `name` of a top-level field to sort by that field in ascending order. Prefix the name of the field with a minus symbol ("-") to sort in descending order.
@@ -179,6 +192,7 @@ Payload `find` queries support a `sort` parameter through all APIs. Pass the `na
**`https://localhost:3000/api/posts?sort=-createdAt`** **`https://localhost:3000/api/posts?sort=-createdAt`**
**GraphQL example:** **GraphQL example:**
``` ```
query { query {
Posts(sort: "-createdAt") { Posts(sort: "-createdAt") {
@@ -194,10 +208,10 @@ query {
```js ```js
const getPosts = async () => { const getPosts = async () => {
const posts = await payload.find({ const posts = await payload.find({
collection: 'posts', collection: "posts",
sort: '-createdAt', sort: "-createdAt",
}); });
return posts; return posts;
} };
``` ```

View File

@@ -2,7 +2,7 @@
title: Pagination title: Pagination
label: Pagination label: Pagination
order: 20 order: 20
desc: Payload is a headless CMS and application framework. desc: Payload queries are equipped with automatic pagination so you create paginated lists of documents within your app.
keywords: query, documents, pagination, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: query, documents, pagination, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
@@ -10,20 +10,21 @@ All collection `find` queries are paginated automatically. Responses are returne
**`Find` response properties:** **`Find` response properties:**
| Property | Description | | Property | Description |
| ------------- | ---------------------------------------------------------- | | ------------- | --------------------------------------------------------- |
| docs | Array of documents in the collection | | docs | Array of documents in the collection |
| totalDocs | Total available documents within the collection | | totalDocs | Total available documents within the collection |
| limit | Limit query parameter - defaults to `10` | | limit | Limit query parameter - defaults to `10` |
| totalPages | Total pages available, based upon the `limit` queried for | | totalPages | Total pages available, based upon the `limit` queried for |
| page | Current page number | | page | Current page number |
| pagingCounter | `number` of the first doc on the current page | | pagingCounter | `number` of the first doc on the current page |
| hasPrevPage | `true/false` if previous page exists | | hasPrevPage | `true/false` if previous page exists |
| hasNextPage | `true/false` if next page exists | | hasNextPage | `true/false` if next page exists |
| prevPage | `number` of previous page, `null` if it doesn't exist | | prevPage | `number` of previous page, `null` if it doesn't exist |
| nextPage | `number` of next page, `null` if it doesn't exist | | nextPage | `number` of next page, `null` if it doesn't exist |
**Example response:** **Example response:**
```js ```js
{ {
// Document Array // highlight-line // Document Array // highlight-line
@@ -54,7 +55,7 @@ All collection `find` queries are paginated automatically. Responses are returne
All Payload APIs support the pagination controls below. With them, you can create paginated lists of documents within your application: All Payload APIs support the pagination controls below. With them, you can create paginated lists of documents within your application:
| Control | Description | | Control | Description |
| --------- | ----------------------------------------------------------------------------------------- | | ------- | --------------------------------------- |
| `limit` | Limits the number of documents returned | | `limit` | Limits the number of documents returned |
| `page` | Get a specific page number | | `page` | Get a specific page number |

View File

@@ -2,12 +2,13 @@
title: REST API title: REST API
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Payload generates a fully functional REST API from your Collection and Global configs.
keywords: rest, api, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: rest, api, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner> <Banner>
A fully functional REST API is automatically generated from your Collection and Global configs. A fully functional REST API is automatically generated from your Collection
and Global configs.
</Banner> </Banner>
All Payload API routes are mounted prefixed to your config's `routes.api` URL segment (default: `/api`). All Payload API routes are mounted prefixed to your config's `routes.api` URL segment (default: `/api`).
@@ -24,13 +25,13 @@ Each collection is mounted using its `slug` value. For example, if a collection'
**All CRUD operations are exposed as follows:** **All CRUD operations are exposed as follows:**
| Method | Path | Description | | Method | Path | Description |
| -------- | --------------------------- | -------------------------------------- | | -------- | --------------------------- | --------------------------------- |
| `GET` | `/api/{collectionSlug}` | Find paginated documents | | `GET` | `/api/{collectionSlug}` | Find paginated documents |
| `GET` | `/api/{collectionSlug}/:id` | Find a specific document by ID | | `GET` | `/api/{collectionSlug}/:id` | Find a specific document by ID |
| `POST` | `/api/{collectionSlug}` | Create a new document | | `POST` | `/api/{collectionSlug}` | Create a new document |
| `PUT` | `/api/{collectionSlug}/:id` | Update a document by ID | | `PUT` | `/api/{collectionSlug}/:id` | Update a document by ID |
| `DELETE` | `/api/{collectionSlug}/:id` | Delete an existing document by ID | | `DELETE` | `/api/{collectionSlug}/:id` | Delete an existing document by ID |
##### Additional `find` query parameters ##### Additional `find` query parameters
@@ -43,22 +44,22 @@ The `find` endpoint supports the following additional query parameters:
## Auth Operations ## Auth Operations
| Method | Path | Description | | Method | Path | Description |
| -------- | --------------------------- | ----------- | | ------ | --------------------------------------- | --------------------------------------------------------------------------------------- |
| `POST` | `/api/{collectionSlug}/verify/:token` | [Email verification](/docs/authentication/operations#verify-by-email), if enabled. | | `POST` | `/api/{collectionSlug}/verify/:token` | [Email verification](/docs/authentication/operations#verify-by-email), if enabled. |
| `POST` | `/api/{collectionSlug}/unlock` | [Unlock a user's account](/docs/authentication/operations#unlock), if enabled. | | `POST` | `/api/{collectionSlug}/unlock` | [Unlock a user's account](/docs/authentication/operations#unlock), if enabled. |
| `POST` | `/api/{collectionSlug}/login` | [Logs in](/docs/authentication/operations#login) a user with email / password. | | `POST` | `/api/{collectionSlug}/login` | [Logs in](/docs/authentication/operations#login) a user with email / password. |
| `POST` | `/api/{collectionSlug}/logout` | [Logs out](/docs/authentication/operations#logout) a user. | | `POST` | `/api/{collectionSlug}/logout` | [Logs out](/docs/authentication/operations#logout) a user. |
| `POST` | `/api/{collectionSlug}/refresh-token` | [Refreshes a token](/docs/authentication/operations#refresh) that has not yet expired. | | `POST` | `/api/{collectionSlug}/refresh-token` | [Refreshes a token](/docs/authentication/operations#refresh) that has not yet expired. |
| `GET` | `/api/{collectionSlug}/me` | [Returns the currently logged in user with token](/docs/authentication/operations#me). | | `GET` | `/api/{collectionSlug}/me` | [Returns the currently logged in user with token](/docs/authentication/operations#me). |
| `POST` | `/api/{collectionSlug}/forgot-password` | [Password reset workflow](/docs/authentication/operations#forgot-password) entry point. | | `POST` | `/api/{collectionSlug}/forgot-password` | [Password reset workflow](/docs/authentication/operations#forgot-password) entry point. |
| `POST` | `/api/{collectionSlug}/reset-password` | [To reset the user's password](/docs/authentication/operations#reset-password). | | `POST` | `/api/{collectionSlug}/reset-password` | [To reset the user's password](/docs/authentication/operations#reset-password). |
## Globals ## Globals
Globals cannot be created or deleted, so there are only two REST endpoints opened: Globals cannot be created or deleted, so there are only two REST endpoints opened:
| Method | Path | Description | | Method | Path | Description |
| -------- | --------------------------- | ----------------------- | | ------ | --------------------------- | ----------------------- |
| `GET` | `/api/globals/{globalSlug}` | Get a global by slug | | `GET` | `/api/globals/{globalSlug}` | Get a global by slug |
| `POST` | `/api/globals/{globalSlug}` | Update a global by slug | | `POST` | `/api/globals/{globalSlug}` | Update a global by slug |

View File

@@ -2,16 +2,18 @@
title: Uploads title: Uploads
label: Overview label: Overview
order: 10 order: 10
desc: Payload is a headless CMS and application framework. desc: Payload supports uploads, storage and management of files directly on your server, combined with powerful file access control.
keywords: uploads, images, media, overview, documentation, Content Management System, cms, headless, javascript, node, react, express keywords: uploads, images, media, overview, documentation, Content Management System, cms, headless, javascript, node, react, express
--- ---
<Banner> <Banner>
Payload provides for everything you need to enable file upload, storage, and management directly on your server—including extremely powerful file access control. Payload provides for everything you need to enable file upload, storage, and
management directly on your server—including extremely powerful file access
control.
</Banner> </Banner>
![Upload admin panel functionality](https://payloadcms.com/images/upload-admin.jpg) ![Upload admin panel functionality](https://payloadcms.com/images/upload-admin.jpg)
*Admin panel screenshot depicting a Media Collection with Upload enabled* _Admin panel screenshot depicting a Media Collection with Upload enabled_
**Here are some common use cases of Uploads:** **Here are some common use cases of Uploads:**
@@ -22,7 +24,7 @@ keywords: uploads, images, media, overview, documentation, Content Management Sy
**By simply enabling Upload functionality on a Collection, Payload will automatically transform your Collection into a robust file management / storage solution. The following modifications will be made:** **By simply enabling Upload functionality on a Collection, Payload will automatically transform your Collection into a robust file management / storage solution. The following modifications will be made:**
1. `filename`, `mimeType`, and `filesize` fields will be automatically added to your Collection. Optionally, if you pass `imageSizes` to your Collection's Upload config, a [`sizes`](#image-sizes) array will also be added containing auto-resized image sizes and filenames. 1. `filename`, `mimeType`, and `filesize` fields will be automatically added to your Collection. Optionally, if you pass `imageSizes` to your Collection's Upload config, a [`sizes`](#image-sizes) array will also be added containing auto-resized image sizes and filenames.
1. The Admin panel will modify its built-in `List` component to show a thumbnail gallery of your Uploads instead of the default Table view 1. The Admin panel will modify its built-in `List` component to show a thumbnail gallery of your Uploads instead of the default Table view
1. The Admin panel will modify its `Edit` view(s) to add a new set of corresponding Upload UI which will allow for file upload 1. The Admin panel will modify its `Edit` view(s) to add a new set of corresponding Upload UI which will allow for file upload
1. The `create`, `update`, and `delete` Collection operations will be modified to support file upload, re-upload, and deletion 1. The `create`, `update`, and `delete` Collection operations will be modified to support file upload, re-upload, and deletion
@@ -31,45 +33,47 @@ keywords: uploads, images, media, overview, documentation, Content Management Sy
Every Payload Collection can opt-in to supporting Uploads by specifying the `upload` property on the Collection's config to either `true` or to an object containing `upload` options. Every Payload Collection can opt-in to supporting Uploads by specifying the `upload` property on the Collection's config to either `true` or to an object containing `upload` options.
<Banner type="success"> <Banner type="success">
<strong>Tip:</strong><br/> <strong>Tip:</strong>
A common pattern is to create a <strong>Media</strong> collection and enable <strong>upload</strong> on that collection. <br />A common pattern is to create a <strong>Media</strong> collection and
enable <strong>upload</strong> on that collection.
</Banner> </Banner>
#### Collection Upload Options #### Collection Upload Options
| Option | Description | | Option | Description |
| ---------------------- | -------------| | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **`staticURL`** * | The base URL path to use to access you uploads. Example: `/media` | | **`staticURL`** \* | The base URL path to use to access you uploads. Example: `/media` |
| **`staticDir`** * | The folder directory to use to store media in. Can be either an absolute path or relative to the directory that contains your config. | | **`staticDir`** \* | The folder directory to use to store media in. Can be either an absolute path or relative to the directory that contains your config. |
| **`imageSizes`** | If specified, image uploads will be automatically resized in accordance to these image sizes. [More](#image-sizes) | | **`imageSizes`** | If specified, image uploads will be automatically resized in accordance to these image sizes. [More](#image-sizes) |
| **`adminThumbnail`** | Which of your provided image sizes to use for the admin panel's thumbnail. Typically a size around 500x500px or so works well. | | **`adminThumbnail`** | Which of your provided image sizes to use for the admin panel's thumbnail. Typically a size around 500x500px or so works well. |
*An asterisk denotes that a property above is required.* _An asterisk denotes that a property above is required._
**Example Upload collection:** **Example Upload collection:**
```js ```js
const Media = { const Media = {
slug: 'media', slug: "media",
upload: { upload: {
staticURL: '/media', staticURL: "/media",
staticDir: 'media', staticDir: "media",
imageSizes: [ imageSizes: [
{ {
name: 'thumbnail', name: "thumbnail",
width: 400, width: 400,
height: 300, height: 300,
crop: 'centre', crop: "centre",
}, },
{ {
name: 'card', name: "card",
width: 768, width: 768,
height: 1024, height: 1024,
crop: 'centre', crop: "centre",
} },
], ],
adminThumbnail: 'thumbnail', adminThumbnail: "thumbnail",
} },
} };
``` ```
### Payload-wide Upload Options ### Payload-wide Upload Options
@@ -79,17 +83,17 @@ Payload relies on the [`express-fileupload`](https://www.npmjs.com/package/expre
A common example of what you might want to customize within Payload-wide Upload options would be to increase the allowed `fileSize` of uploads sent to Payload: A common example of what you might want to customize within Payload-wide Upload options would be to increase the allowed `fileSize` of uploads sent to Payload:
```js ```js
import { buildConfig } from 'payload/config'; import { buildConfig } from "payload/config";
export default buildConfig({ export default buildConfig({
serverURL: 'http://localhost:3000', serverURL: "http://localhost:3000",
collections: [ collections: [
{ {
slug: 'media', slug: "media",
fields: [ fields: [
{ {
name: 'alt', name: "alt",
type: 'text', type: "text",
}, },
], ],
upload: true, upload: true,
@@ -98,8 +102,8 @@ export default buildConfig({
upload: { upload: {
limits: { limits: {
fileSize: 5000000, // 5MB, written in bytes fileSize: 5000000, // 5MB, written in bytes
} },
} },
}); });
``` ```
@@ -114,8 +118,11 @@ Behind the scenes, Payload relies on [`sharp`](https://sharp.pixelplumbing.com/a
### Uploading Files ### Uploading Files
<Banner type="warning"> <Banner type="warning">
<strong>Important:</strong><br/> <strong>Important:</strong>
Uploading files is currently only possible through the REST API due to how GraphQL works. It's difficult and fairly nonsensical to support uploading files through GraphQL. <br />
Uploading files is currently only possible through the REST API due to how
GraphQL works. It's difficult and fairly nonsensical to support uploading
files through GraphQL.
</Banner> </Banner>
To upload a file, use your collection's [`create`](/docs/rest-api/overview#collections) endpoint. Send it all the data that your Collection requires, as well as a `file` key containing the file that you'd like to upload. To upload a file, use your collection's [`create`](/docs/rest-api/overview#collections) endpoint. Send it all the data that your Collection requires, as well as a `file` key containing the file that you'd like to upload.