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
label: Custom Components
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
---
@@ -11,8 +11,10 @@ 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.
<Banner type="success">
<strong>Tip:</strong><br/>
Custom components will automatically be provided with all props that the default component would accept.
<strong>Tip:</strong>
<br />
Custom components will automatically be provided with all props that the
default component would accept.
</Banner>
### Base Component Overrides
@@ -20,7 +22,7 @@ To swap in your own React component, first, consult the list of available compon
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 |
| --------------------- | -------------|
| --------------------- | -------------------------------------------------------------------------------------------------- |
| **`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.Dashboard`** | The main landing page of the Admin panel. |
@@ -30,12 +32,19 @@ You can override a set of admin panel-wide components by providing a component t
#### Full example:
`payload.config.js`
```js
import { buildConfig } from 'payload/config';
import { MyCustomNav, MyCustomLogo, MyCustomIcon, MyCustomAccount, MyCustomDashboard } from './customComponents.js';
import { buildConfig } from "payload/config";
import {
MyCustomNav,
MyCustomLogo,
MyCustomIcon,
MyCustomAccount,
MyCustomDashboard,
} from "./customComponents.js";
export default buildConfig({
serverURL: 'http://localhost:3000',
serverURL: "http://localhost:3000",
admin: {
components: {
Nav: MyCustomNav,
@@ -46,20 +55,20 @@ export default buildConfig({
views: {
Account: MyCustomAccount,
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
You can override components on a Collection-by-Collection basis via each Collection's `admin` property.
| Path | Description |
| ---------------- | -------------|
| ---------------- | ------------------------------------------------------------------------------------------------ |
| **`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. |
@@ -68,7 +77,7 @@ You can override components on a Collection-by-Collection basis via each Collect
As with Collections, You can override components on a global-by-global basis via their `admin` property.
| Path | Description |
| ---------------- | -------------|
| ---------------- | --------------------------------------- |
| **`views.Edit`** | Used while this Global is being edited. |
### Fields
@@ -76,14 +85,18 @@ As with Collections, You can override components on a global-by-global basis via
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">
<strong>Tip:</strong><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.
<strong>Tip:</strong>
<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>
**Fields support the following custom components:**
| Component | Description |
| --------------- | -------------|
| ------------ | ------------------------------------------------------------------------------------------------------------------------ |
| **`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. |
| **`Field`** | Swap out the field itself within all `Edit` views. |
@@ -93,16 +106,11 @@ All Payload fields support the ability to swap in your own React components. So,
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
import { useFieldType } from 'payload/components/forms';
import { useFieldType } from "payload/components/forms";
const CustomTextField = ({ path }) => {
const { value, setValue } = useFieldType({ path });
return (
<input
onChange={(e) => setValue(e.target.value)}
value={value}
/>
)
}
return <input onChange={(e) => setValue(e.target.value)} value={value} />;
};
```

View File

@@ -2,7 +2,7 @@
title: Customizing CSS & SCSS
label: Customizing CSS
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
---

View File

@@ -2,7 +2,7 @@
title: The Admin Panel
label: Overview
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
---
@@ -11,19 +11,21 @@ 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.
<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>
![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
All options for the Admin panel are defined in your base Payload config file.
| 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) |
| `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. |
@@ -33,26 +35,28 @@ All options for the Admin panel are defined in your base Payload config file.
| `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) |
### The Admin User Collection
<Banner type="warning">
<strong>Important:</strong><br />
The Payload Admin panel can only be used by one Collection that supports <a href="/docs/authentication/">Authentication</a>.
<strong>Important:</strong>
<br />
The Payload Admin panel can only be used by one Collection that supports{" "}
<a href="/docs/authentication/">Authentication</a>.
</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.
`payload.config.js`:
```js
import { buildConfig } from 'payload/config';
import { buildConfig } from "payload/config";
const config = buildConfig({
serverURL: 'http://localhost:3000',
serverURL: "http://localhost:3000",
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.

View File

@@ -2,7 +2,7 @@
title: Webpack
label: Webpack
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
---

View File

@@ -2,7 +2,7 @@
title: Collection Access Control
label: Collections
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
---
@@ -11,7 +11,7 @@ You can define Collection-level Access Control within each Collection's `access`
## Available Controls
| Function | Allows/Denies Access |
| ------------------------ | -------------------- |
| ----------------------- | -------------------------------------------- |
| **[`create`](#create)** | Used in the `create` operation |
| **[`read`](#read)** | Used in the `find` and `findByID` operations |
| **[`update`](#update)** | Used in the `update` operation |
@@ -22,11 +22,12 @@ You can define Collection-level Access Control within each Collection's `access`
If a Collection supports [`Authentication`](/docs/authentication/overview), the following Access Controls become available:
| Function | Allows/Denies Access |
| ----------------------- | -------------------- |
| ----------------------- | -------------------------------------------------------------- |
| **[`admin`](#admin)** | Used to restrict access to the Payload Admin panel |
| **[`unlock`](#unlock)** | Used to restrict which users can access the `unlock` operation |
**Example Collection config:**
```js
export default {
slug: "posts",
@@ -49,7 +50,7 @@ Returns a boolean which allows/denies access to the `create` request.
**Available argument properties :**
| Option | Description |
| --------- | ----------- |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
### Read
@@ -59,7 +60,7 @@ Read access functions can return a boolean result or optionally return a [query
**Available argument properties :**
| Option | Description |
| --------- | ----------- |
| --------- | ------------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`id`** | `id` of document requested, if within `findByID`. Otherwise, `id` is undefined. |
@@ -70,7 +71,7 @@ Update access functions can return a boolean result or optionally return a [quer
**Available argument properties :**
| Option | Description |
| --------- | ----------- |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`id`** | `id` of document requested to update |
@@ -81,7 +82,7 @@ Similarly to the Update function, returns a boolean or a [query constraint](/doc
**Available argument properties :**
| Option | Description |
| --------- | ----------- |
| --------- | --------------------------------------------------------------------------------------------------- |
| **`req`** | The Express `request` object with additional `user` property, which is the currently logged in user |
| **`id`** | `id` of document requested to delete |
@@ -92,7 +93,7 @@ If the Collection is [used to access the Payload Admin panel](/docs/admin/overvi
**Available argument properties :**
| Option | Description |
| --------- | ----------- |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
### Unlock
@@ -102,5 +103,5 @@ Determines which users can [unlock](/docs/authentication/operations#unlock) othe
**Available argument properties :**
| Option | Description |
| --------- | ----------- |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |

View File

@@ -2,7 +2,7 @@
title: Field-level Access Control
label: Fields
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
---
@@ -11,12 +11,13 @@ Field Access Control is specified with functions inside a field's config. All fi
## Available Controls
| Function | Purpose |
| ------------------------ | ------- |
| ----------------------- | -------------------------------------------------------------------------------- |
| **[`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 |
| **[`update`](#update)** | Allows or denies the ability to update a field's value |
**Example Collection config:**
```js
export default {
slug: 'posts',
@@ -44,7 +45,7 @@ Returns a boolean which allows or denies the ability to set a field's value when
**Available argument properties:**
| Option | Description |
| --------- | ----------- |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
### Read
@@ -54,7 +55,7 @@ Returns a boolean which allows or denies the ability to read a field's value. If
**Available argument properties:**
| Option | Description |
| --------- | ----------- |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`id`** | `id` of the document being read |
@@ -65,6 +66,6 @@ Returns a boolean which allows or denies the ability to update a field's value.
**Available argument properties:**
| Option | Description |
| --------- | ----------- |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`id`** | `id` of the document being updated |

View File

@@ -2,22 +2,23 @@
title: Globals Access Control
label: Globals
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
---
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
| Function | Allows/Denies Access |
| ------------------------ | -------------------- |
| ----------------------- | -------------------------------------- |
| **[`read`](#read)** | Used in the `findOne` Global operation |
| **[`update`](#update)** | Used in the `update` Global operation |
**Example Global config:**
```js
export default {
slug: "header",
@@ -37,7 +38,7 @@ Returns a boolean result to allow or deny a user's ability to read the Global.
**Available argument properties:**
| Option | Description |
| --------- | ----------- |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
### Update
@@ -47,5 +48,5 @@ Returns a boolean result to allow or deny a user's ability to update the Global.
**Available argument properties:**
| Option | Description |
| --------- | ----------- |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |

View File

@@ -2,7 +2,7 @@
title: Access Control
label: Overview
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
---
@@ -28,12 +28,15 @@ const defaultPayloadAccess = ({ req: { user } }) => {
// Return `true` if a user is found
// and `false` if it is undefined or null
return Boolean(user);
}
};
```
<Banner type="success">
<strong>Note:</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>.
<strong>Note:</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>
### Access Control Types

View File

@@ -2,7 +2,7 @@
title: Authentication Config
label: Config
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
---
@@ -13,7 +13,7 @@ To enable Authentication on a collection, define an `auth` property and set it t
## Options
| 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) |
| **`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. |
@@ -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.
<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>
##### 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.
**For example, using Fetch:**
```js
const response = await fetch('http://localhost:3000/api/pages', {
const response = await fetch("http://localhost:3000/api/pages", {
headers: {
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.
<Banner type="success">
<strong>Tip:</strong><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.
<strong>Tip:</strong>
<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>
Example:
@@ -99,8 +106,13 @@ Example:
```
<Banner type="warning">
<strong>Important:</strong><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.
<strong>Important:</strong>
<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>
**`generateEmailSubject`**
@@ -153,8 +165,13 @@ Example:
```
<Banner type="warning">
<strong>Important:</strong><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.
<strong>Important:</strong>
<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>
**`generateEmailSubject`**

View File

@@ -2,7 +2,7 @@
title: Authentication Operations
label: Operations
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
---
@@ -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`
Example response:
```js
{
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`
Example response:
```js
{
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.
**Example REST API login**:
```js
const res = await fetch('http://localhost:3000/api/[collection-slug]/login', {
method: 'POST',
const res = await fetch("http://localhost:3000/api/[collection-slug]/login", {
method: "POST",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
body: JSON.stringify({
email: 'dev@payloadcms.com',
password: 'this-is-not-our-password...or-is-it?',
})
})
email: "dev@payloadcms.com",
password: "this-is-not-our-password...or-is-it?",
}),
});
const json = await res.json();
@@ -154,12 +157,12 @@ mutation {
```js
const result = await payload.login({
collection: '[collection-slug]',
collection: "[collection-slug]",
data: {
email: 'dev@payloadcms.com',
password: 'get-out',
email: "dev@payloadcms.com",
password: "get-out",
},
})
});
```
### 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.
**Example REST API logout**:
```js
const res = await fetch('http://localhost:3000/api/[collection-slug]/logout', {
method: 'POST',
const res = await fetch("http://localhost:3000/api/[collection-slug]/logout", {
method: "POST",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
})
});
```
**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.
**Example REST API token refresh**:
```js
const res = await fetch('http://localhost:3000/api/[collection-slug]/refresh', {
method: 'POST',
const res = await fetch("http://localhost:3000/api/[collection-slug]/refresh", {
method: "POST",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
})
});
const json = await res.json();
@@ -232,7 +237,10 @@ mutation {
```
<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>
### 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.
**Example REST API user verification**:
```js
const res = await fetch(`http://localhost:3000/api/[collection-slug]/verify/${TOKEN_HERE}`, {
method: 'POST',
const res = await fetch(
`http://localhost:3000/api/[collection-slug]/verify/${TOKEN_HERE}`,
{
method: "POST",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
})
}
);
```
**Example GraphQL Mutation**:
@@ -261,9 +273,9 @@ mutation {
```js
const result = await payload.verifyEmail({
collection: '[collection-slug]',
token: 'TOKEN_HERE',
})
collection: "[collection-slug]",
token: "TOKEN_HERE",
});
```
### 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.
**Example REST API unlock**:
```js
const res = await fetch(`http://localhost:3000/api/[collection-slug]/unlock`, {
method: 'POST',
method: "POST",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
})
});
```
**Example GraphQL Mutation**:
@@ -294,8 +307,8 @@ mutation {
```js
const result = await payload.unlock({
collection: '[collection-slug]',
})
collection: "[collection-slug]",
});
```
### 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).
**Example REST API Forgot Password**:
```js
const res = await fetch(`http://localhost:3000/api/[collection-slug]/forgot-password`, {
method: 'POST',
const res = await fetch(
`http://localhost:3000/api/[collection-slug]/forgot-password`,
{
method: "POST",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
body: JSON.stringify({
email: 'dev@payloadcms.com',
email: "dev@payloadcms.com",
}),
})
}
);
```
**Example GraphQL Mutation**:
@@ -331,17 +348,23 @@ mutation {
```js
const token = await payload.forgotPassword({
collection: '[collection-slug]',
collection: "[collection-slug]",
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">
<strong>Tip:</strong><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.
<strong>Tip:</strong>
<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>
### 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.
**Example REST API Reset Password**:
```js
const res = await fetch(`http://localhost:3000/api/[collection-slug]/reset-password`, {
method: 'POST',

View File

@@ -2,18 +2,19 @@
title: Authentication Overview
label: Overview
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
---
<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>
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)
*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:**
@@ -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.
<Banner type="success">
<strong>Tip:</strong><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.
<strong>Tip:</strong>
<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>
### 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:
```js
const response = await fetch('http://localhost:3000/api/pages', {
credentials: 'include',
const response = await fetch("http://localhost:3000/api/pages", {
credentials: "include",
});
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).
<Banner type="success">
<strong>Tip:</strong><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.
<strong>Tip:</strong>
<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>
### 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.
<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>
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`:
```js
import { buildConfig } from 'payload/config';
import { buildConfig } from "payload/config";
const config = buildConfig({
serverURL: 'http://localhost:3000',
serverURL: "http://localhost:3000",
collections: [
// collections here
],
// highlight-start
csrf: [ // whitelist of domains to allow cookie auth from
'https://your-frontend-app.com',
'https://your-other-frontend-app.com',
csrf: [
// whitelist of domains to allow cookie auth from
"https://your-frontend-app.com",
"https://your-other-frontend-app.com",
],
// 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.
Example:
```js
const request = await fetch('http://localhost:3000', {
const request = await fetch("http://localhost:3000", {
headers: {
Authorization: `JWT ${token}`
}
})
Authorization: `JWT ${token}`,
},
});
```
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
label: Using the Middleware
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
---
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.
<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>
Example in `server.js`:
```js
import express from 'express';
import payload from 'payload';
import express from "express";
import payload from "payload";
const app = express();
payload.init({
secret: 'PAYLOAD_SECRET_KEY',
mongoURL: 'mongodb://localhost/payload',
secret: "PAYLOAD_SECRET_KEY",
mongoURL: "mongodb://localhost/payload",
express: app,
});
@@ -31,18 +33,17 @@ const router = express.Router();
router.use(payload.authenticate); // highlight-line
router.get('/', (req, res) => {
router.get("/", (req, res) => {
if (req.user) {
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 () => {
payload.logger.info(`listening on ${3000}...`);
});
```

View File

@@ -2,7 +2,7 @@
title: Collection Configs
label: Collections
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
---
@@ -13,9 +13,9 @@ It's often best practice to write your Collections in separate files and then im
## Options
| Option | Description |
| ---------------- | -------------|
| **`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. |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`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. |
| **`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). |
| **`hooks`** | Entry points to "tie in" to Collection actions at specific points. [More](/docs/hooks/overview#collection-hooks) |
@@ -24,31 +24,31 @@ It's often best practice to write your Collections in separate files and then im
| **`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. |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
#### Simple collection example
```js
const Order = {
slug: 'orders',
slug: "orders",
labels: {
singular: 'Order',
plural: 'Orders',
singular: "Order",
plural: "Orders",
},
fields: [
{
name: 'total',
type: 'number',
name: "total",
type: "number",
required: true,
},
{
name: 'placedBy',
type: 'relationship',
relationTo: 'customers',
name: "placedBy",
type: "relationship",
relationTo: "customers",
required: true,
}
]
}
},
],
};
```
#### More collection config examples
@@ -60,7 +60,7 @@ 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.
| 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. |
| `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. |

View File

@@ -2,7 +2,7 @@
title: Express
label: Express
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
---

View File

@@ -2,51 +2,51 @@
title: Global Configs
label: Globals
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
---
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.
## Options
| Option | Description |
| ---------------- | -------------|
| **`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. |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`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. |
| **`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). |
| **`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) |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
#### Simple Global example
```js
const Nav = {
slug: 'nav',
label: 'Nav',
slug: "nav",
label: "Nav",
fields: [
{
name: 'items',
type: 'array',
name: "items",
type: "array",
required: true,
maxRows: 8,
fields: [
{
name: 'page',
label: 'Page',
type: 'relationship',
relationTo: 'pages', // "pages" is the slug of an existing collection
name: "page",
label: "Page",
type: "relationship",
relationTo: "pages", // "pages" is the slug of an existing collection
required: true,
}
]
},
]
}
],
},
],
};
```
#### More Global config examples
@@ -58,7 +58,7 @@ 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.
| Option | Description |
| ---------------------------- | -------------|
| ------------ | ------------------------------------------------------------------------------------------------------- |
| `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) |
### Access control

View File

@@ -2,7 +2,7 @@
title: Localization
label: Localization
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
---
@@ -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.
<Banner>
<strong>Note:</strong><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.
<strong>Note:</strong>
<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>
### Retrieving localized docs
@@ -115,7 +120,10 @@ query {
```
<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>
##### Local API
@@ -126,8 +134,8 @@ You can specify `locale` as well as `fallbackLocale` within the Local API as wel
```js
const posts = await payload.find({
collection: 'posts',
locale: 'es',
collection: "posts",
locale: "es",
fallbackLocale: false,
})
});
```

View File

@@ -2,16 +2,24 @@
title: The Payload Config
label: Overview
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
---
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">
<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>
## Options
@@ -40,54 +48,53 @@ Payload is a *config-based*, code-first CMS and application framework. The Paylo
#### Simple example
```js
import { buildConfig } from 'payload/config';
import { buildConfig } from "payload/config";
const config = buildConfig({
serverURL: 'http://localhost:3000',
serverURL: "http://localhost:3000",
collections: [
{
slug: 'pages',
slug: "pages",
fields: [
{
name: 'title',
label: 'Title',
type: 'text',
name: "title",
label: "Title",
type: "text",
required: true,
},
{
name: 'content',
label: 'Content',
type: 'richText',
name: "content",
label: "Content",
type: "richText",
required: true,
}
]
}
},
],
},
],
globals: [
{
slug: 'header',
label: 'Header',
slug: "header",
label: "Header",
fields: [
{
name: 'nav',
label: 'Nav',
type: 'array',
name: "nav",
label: "Nav",
type: "array",
fields: [
{
name: 'page',
label: 'Page',
type: 'relationship',
relationTo: 'pages',
name: "page",
label: "Page",
type: "relationship",
relationTo: "pages",
},
]
}
]
}
]
],
},
],
},
],
});
export default 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.
**Add this line to the top of your server:**
```
require('dotenv').config()
// ...
@@ -116,8 +124,13 @@ project-name
```
<Banner type="warning">
<strong>Important:</strong><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.
<strong>Important:</strong>
<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>
### Customizing & overriding the config location

View File

@@ -2,7 +2,7 @@
title: Email Functionality
label: Overview
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
---
@@ -26,19 +26,20 @@ 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().
| Option | Description |
| ---------------------------- | -------------|
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`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 |
| **`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 |
| **`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 |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
### Use SMTP
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:**
```js
payload.init({
email: {
@@ -62,7 +63,12 @@ payload.init({
```
<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>
### 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.
```js
const nodemailerSendgrid = require('nodemailer-sendgrid');
const payload = require('payload');
const nodemailerSendgrid = require("nodemailer-sendgrid");
const payload = require("payload");
const sendGridAPIKey = process.env.SENDGRID_API_KEY;
payload.init({
...sendGridAPIKey ? {
...(sendGridAPIKey
? {
email: {
transportOptions: nodemailerSendgrid({
apiKey: sendGridAPIKey,
}),
fromName: 'Admin',
fromAddress: 'admin@example.com',
fromName: "Admin",
fromAddress: "admin@example.com",
},
} : {},
}
: {}),
});
```
### 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.
```js
@@ -114,12 +123,15 @@ payload.init({
```
### 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).
### 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.
**Console output when starting payload with a mock email instance**
```
[06:37:21] INFO (payload): Starting Payload...
[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.
<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>
### Using multiple mail providers

View File

@@ -2,12 +2,14 @@
title: Array Field
label: Array
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
---
<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.
<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.
</Banner>
**Example uses:**
@@ -17,15 +19,15 @@ 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)
![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
| 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. |
| **`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) |
| **`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) |
@@ -37,11 +39,12 @@ keywords: array, fields, config, configuration, documentation, Content Managemen
| **`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. |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,12 +2,15 @@
title: Blocks Field
label: Blocks
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
---
<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.
<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.
</Banner>
**Example uses:**
@@ -17,42 +20,47 @@ 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`.
![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
| 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. |
| **`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) |
| **`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) |
| **`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. |
| **`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. |
| **`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. |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
### Block configs
Blocks are defined as separate configs of their own.
<Banner type="success">
<strong>Tip:</strong><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.
<strong>Tip:</strong>
<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>
| Option | Description |
| ---------------- | ----------- |
| **`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. |
| ------------------ | -------------------------------------------------------------------------------------------------------------------- |
| **`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. |
| **`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. |
| **`imageAltText`** | Customize this block's image thumbnail alt text. |
@@ -72,44 +80,46 @@ The Admin panel provides each block with a `blockName` field which optionally al
### Example
`collections/ExampleCollection.js`
```js
const QuoteBlock = {
slug: 'Quote', // required
imageURL: 'https://google.com/path/to/image.jpg',
imageAltText: 'A nice thumbnail image to show what this block looks like',
fields: [ // required
slug: "Quote", // required
imageURL: "https://google.com/path/to/image.jpg",
imageAltText: "A nice thumbnail image to show what this block looks like",
fields: [
// required
{
name: 'text',
label: 'Quote Text',
type: 'text',
name: "text",
label: "Quote Text",
type: "text",
required: true,
},
{
name: 'text',
label: 'Quotee',
type: 'text',
name: "text",
label: "Quotee",
type: "text",
},
]
],
};
const ExampleCollection = {
slug: 'example-collection',
slug: "example-collection",
fields: [
{
name: 'layout', // required
type: 'blocks', // required
label: 'layout',
name: "layout", // required
type: "blocks", // required
label: "layout",
minRows: 1,
maxRows: 20,
labels: {
singular: 'Layout',
plural: 'Layouts',
singular: "Layout",
plural: "Layouts",
},
blocks: [ // required
QuoteBlock
]
}
]
}
blocks: [
// required
QuoteBlock,
],
},
],
};
```

View File

@@ -2,19 +2,17 @@
title: Checkbox Field
label: Checkbox
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
---
<Banner >
The Checkbox field type saves a boolean in the database.
</Banner>
<Banner>The Checkbox field type saves a boolean in the database.</Banner>
### Config
| 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. |
| **`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. |
@@ -27,11 +25,12 @@ keywords: checkbox, fields, config, configuration, documentation, Content Manage
| **`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. |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,12 +2,14 @@
title: Code Field
label: Code
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
---
<Banner >
The Code field type saves a string in the database, but provides the Admin panel with a code editor styled interface.
<Banner>
The Code field type saves a string in the database, but provides the Admin
panel with a code editor styled interface.
</Banner>
This field uses `prismjs` for syntax highlighting and `react-simple-code-editor` for the editor itself.
@@ -15,8 +17,8 @@ This field uses `prismjs` for syntax highlighting and `react-simple-code-editor`
### Config
| 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. |
| **`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. |
@@ -32,7 +34,7 @@ This field uses `prismjs` for syntax highlighting and `react-simple-code-editor`
| **`required`** | Require this field to have a value. |
| **`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
@@ -43,6 +45,7 @@ Currently, the `language` property only supports JavaScript syntax but more supp
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,12 +2,13 @@
title: Date Field
label: Date
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
---
<Banner >
The Date field type saves a Date in the database and provides the Admin panel with a customizable time picker interface.
<Banner>
The Date field type saves a Date in the database and provides the Admin panel
with a customizable time picker interface.
</Banner>
This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepicker) for the Admin panel component.
@@ -15,8 +16,8 @@ This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepic
### Config
| 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. |
| **`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) |
@@ -29,7 +30,7 @@ This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepic
| **`required`** | Require this field to have a value. |
| **`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
@@ -42,6 +43,7 @@ Common use cases for customizing the `date` property are to restrict your field
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,19 +2,19 @@
title: Email Field
label: Email
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
---
<Banner >
<Banner>
The Email field enforces that the value provided is a valid email address.
</Banner>
### Config
| 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. |
| **`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. |
@@ -28,7 +28,7 @@ keywords: email, fields, config, configuration, documentation, Content Managemen
| **`required`** | Require this field to have a value. |
| **`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
@@ -45,6 +45,7 @@ Set this property to a string that will be used for browser autocomplete.
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,20 +2,21 @@
title: Group Field
label: Group
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
---
<Banner >
The Group field allows fields to be nested under a common property name. It also groups fields together visually in the Admin panel.
<Banner>
The Group field allows fields to be nested under a common property name. It
also groups fields together visually in the Admin panel.
</Banner>
### Config
| Option | Description |
| ---------------- | ----------- |
| **`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. |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`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. |
| **`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) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
@@ -27,11 +28,12 @@ keywords: group, fields, config, configuration, documentation, Content Managemen
| **`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. |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,19 +2,20 @@
title: Number Field
label: Number
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
---
<Banner >
The Number field stores and validates numeric entry and supports additional numerical validation and formatting features.
<Banner>
The Number field stores and validates numeric entry and supports additional
numerical validation and formatting features.
</Banner>
### Config
| 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. |
| **`min`** | Minimum value accepted. Used in the default `validation` function. |
| **`max`** | Maximum value accepted. Used in the default `validation` function. |
@@ -30,7 +31,7 @@ keywords: number, fields, config, configuration, documentation, Content Manageme
| **`required`** | Require this field to have a value. |
| **`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
@@ -51,6 +52,7 @@ Set this property to a string that will be used for browser autocomplete.
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,12 +2,14 @@
title: Fields Overview
label: Overview
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
---
<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>
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.
**Simple collection with two fields:**
```js
const Pages = {
slug: 'pages',
slug: "pages",
fields: [
{
name: 'my-field',
type: 'text', // highlight-line
label: 'My Field',
name: "my-field",
type: "text", // highlight-line
label: "My Field",
},
{
name: 'other-field',
type: 'checkbox', // highlight-line
label: 'Other Field'
name: "other-field",
type: "checkbox", // highlight-line
label: "Other Field",
},
],
}
};
```
### 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.
Example:
```js
{
slug: 'orders',
@@ -90,7 +94,7 @@ 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:
| Option | Description |
| ------------- | -------------|
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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. |
| `position` | Specify if the field should be rendered in the sidebar by defining `position: 'sidebar'`. |
@@ -114,13 +118,13 @@ The `condition` function should return a boolean that will control if the field
{
fields: [
{
name: 'enableGreeting',
type: 'checkbox',
name: "enableGreeting",
type: "checkbox",
defaultValue: false,
},
{
name: 'greeting',
type: 'text',
name: "greeting",
type: "text",
admin: {
// highlight-start
condition: (data, siblingData) => {
@@ -129,11 +133,11 @@ The `condition` function should return a boolean that will control if the field
} else {
return false;
}
}
},
// highlight-end
}
}
]
},
},
];
}
```

View File

@@ -2,20 +2,22 @@
title: Radio Field
label: Radio Group
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
---
<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.
<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.
</Banner>
### Config
| Option | Description |
| ---------------- | ----------- |
| **`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. |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`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. |
| **`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) |
| **`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. |
@@ -28,11 +30,16 @@ keywords: radio, fields, config, configuration, documentation, Content Managemen
| **`required`** | Require this field to have a value. |
| **`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">
<strong>Important:</strong><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.
<strong>Important:</strong>
<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>
### Admin config
@@ -46,6 +53,7 @@ The `layout` property allows for the radio group to be styled as a horizonally o
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,12 +2,13 @@
title: Relationship Field
label: Relationship
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
---
<Banner >
The Relationship field is one of the most powerful fields Payload features. It provides for the ability to easily relate documents together.
<Banner>
The Relationship field is one of the most powerful fields Payload features. It
provides for the ability to easily relate documents together.
</Banner>
**Example uses:**
@@ -19,9 +20,9 @@ keywords: relationship, fields, config, configuration, documentation, Content Ma
### Config
| Option | Description |
| ---------------- | ----------- |
| **`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. |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`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. |
| **`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. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
@@ -36,16 +37,19 @@ keywords: relationship, fields, config, configuration, documentation, Content Ma
| **`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. |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
<Banner type="success">
<strong>Tip:</strong><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.
<strong>Tip:</strong>
<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>
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,25 +2,34 @@
title: Rich Text Field
label: Rich Text
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
---
<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.
<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.
</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.
<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>
### Config
| 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. |
| **`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. |
@@ -32,7 +41,7 @@ The Admin component is built on the powerful [`slatejs`](https://docs.slatejs.or
| **`required`** | Require this field to have a value. |
| **`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
@@ -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.
<Banner type="success">
<strong>Tip:</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>.
<strong>Tip:</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>
### Specifying which elements and leaves to allow
@@ -93,9 +105,9 @@ 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:**
| Property | Description |
| ---------------- | ----------- |
| **`name`** * | The name to be used as a `type` for this element. |
| **`Button`** * | A React component to be rendered in the Rich Text toolbar. |
| --------------- | ---------------------------------------------------------- |
| **`name`** \* | The name to be used as a `type` for this element. |
| **`Button`** \* | A React component to be rendered in the Rich Text toolbar. |
| **`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.
@@ -105,6 +117,7 @@ Custom `Leaf` objects follow a similar pattern but require you to define the `Le
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',
@@ -156,45 +169,32 @@ 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:
```js
import React, { Fragment } from 'react';
import escapeHTML from 'escape-html';
import { Text } from 'slate';
import React, { Fragment } from "react";
import escapeHTML from "escape-html";
import { Text } from "slate";
const serialize = (children) => children.map((node, i) => {
const serialize = (children) =>
children.map((node, i) => {
if (Text.isText(node)) {
let text = <span dangerouslySetInnerHTML={{ __html: escapeHTML(node.text) }} />;
let text = (
<span dangerouslySetInnerHTML={{ __html: escapeHTML(node.text) }} />
);
if (node.bold) {
text = (
<strong key={i}>
{text}
</strong>
);
text = <strong key={i}>{text}</strong>;
}
if (node.code) {
text = (
<code key={i}>
{text}
</code>
);
text = <code key={i}>{text}</code>;
}
if (node.italic) {
text = (
<em key={i}>
{text}
</em>
);
text = <em key={i}>{text}</em>;
}
// Handle other leaf types here...
return (
<Fragment key={i}>
{text}
</Fragment>
);
return <Fragment key={i}>{text}</Fragment>;
}
if (!node) {
@@ -202,64 +202,35 @@ const serialize = (children) => children.map((node, i) => {
}
switch (node.type) {
case 'h1':
return (
<h1 key={i}>
{serialize(node.children)}
</h1>
);
case "h1":
return <h1 key={i}>{serialize(node.children)}</h1>;
// Iterate through all headings here...
case 'h6':
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 (
<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}
>
<a href={escapeHTML(node.url)} key={i}>
{serialize(node.children)}
</a>
);
default:
return (
<p key={i}>
{serialize(node.children)}
</p>
);
return <p key={i}>{serialize(node.children)}</p>;
}
});
});
```
<Banner>
<strong>Note:</strong><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!
<strong>Note:</strong>
<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>

View File

@@ -2,26 +2,28 @@
title: Row Field
label: Row
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
---
<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.
<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.
</Banner>
### Config
| 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. |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,20 +2,21 @@
title: Select Field
label: Select
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
---
<Banner >
The Select field provides a dropdown-style interface for choosing options from a predefined list as an enumeration.
<Banner>
The Select field provides a dropdown-style interface for choosing options from
a predefined list as an enumeration.
</Banner>
### Config
| Option | Description |
| ---------------- | ----------- |
| **`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. |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`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. |
| **`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. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
@@ -30,16 +31,22 @@ keywords: select, multi-select, fields, config, configuration, documentation, Co
| **`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. |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
<Banner type="warning">
<strong>Important:</strong><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.
<strong>Important:</strong>
<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>
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,19 +2,20 @@
title: Text Field
label: Text
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
---
<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.
<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.
</Banner>
### Config
| 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. |
| **`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. |
@@ -30,7 +31,7 @@ keywords: text, fields, config, configuration, documentation, Content Management
| **`required`** | Require this field to have a value. |
| **`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
@@ -47,6 +48,7 @@ Set this property to a string that will be used for browser autocomplete.
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,19 +2,20 @@
title: Textarea Field
label: Textarea
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
---
<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.
<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.
</Banner>
### Config
| 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. |
| **`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. |
@@ -30,7 +31,7 @@ keywords: textarea, fields, config, configuration, documentation, Content Manage
| **`required`** | Require this field to have a value. |
| **`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
@@ -47,6 +48,7 @@ Set this property to a string that will be used for browser autocomplete.
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,17 +2,22 @@
title: Upload Field
label: Upload
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
---
<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.
<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.
</Banner>
<Banner type="warning">
<strong>Important:</strong><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.
<strong>Important:</strong>
<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>
**Example uses:**
@@ -24,9 +29,9 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
### Config
| Option | Description |
| ---------------- | ----------- |
| **`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> |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`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> |
| **`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. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
@@ -41,11 +46,12 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
| **`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. |
*\* An asterisk denotes that a property is required.*
_\* An asterisk denotes that a property is required._
### Example
`collections/ExampleCollection.js`
```js
{
slug: 'example-collection',

View File

@@ -2,7 +2,7 @@
title: Payload Concepts
label: Concepts
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
---
@@ -19,7 +19,8 @@ By default, the Payload config lives in the root folder of your code and is name
### Collections
<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>
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
<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>
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
<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>
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
<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>
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
<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>
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
<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>
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`

View File

@@ -2,7 +2,7 @@
title: Installation
label: Installation
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
---

View File

@@ -2,7 +2,7 @@
title: What is Payload?
label: What is Payload?
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
---

View File

@@ -2,7 +2,7 @@
title: Adding your own Queries and Mutations
label: Custom Queries and Mutations
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
---
@@ -11,7 +11,7 @@ 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:
| Config Path | Description |
| -------------------- | -------------|
| ------------------- | --------------------------------------------------------------------------- |
| `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 |
@@ -34,18 +34,18 @@ Both `graphQL.queries` and `graphQL.mutations` functions should return an object
`payload.config.js`:
```js
import { buildConfig } from 'payload/config';
import myCustomQueryResolver from './graphQL/resolvers/myCustomQueryResolver';
import { buildConfig } from "payload/config";
import myCustomQueryResolver from "./graphQL/resolvers/myCustomQueryResolver";
export default buildConfig({
serverURL: 'http://localhost:3000',
serverURL: "http://localhost:3000",
graphQL: {
// highlight-start
queries: (GraphQL, payload) => {
return {
MyCustomQuery: {
type: new GraphQL.GraphQLObjectType({
name: 'MyCustomQuery',
name: "MyCustomQuery",
fields: {
text: {
type: GraphQL.GraphQLString,
@@ -57,14 +57,14 @@ export default buildConfig({
args: {
argNameHere: {
type: new GraphQL.GraphQLNonNull(GraphQLString),
}
},
},
resolve: myCustomQueryResolver,
})
}
}
}
}),
},
};
},
// highlight-end
}
})
},
});
```

View File

@@ -2,7 +2,7 @@
title: GraphQL Overview
label: Overview
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
---

View File

@@ -2,7 +2,7 @@
title: Collection Hooks
label: Collections
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
---
@@ -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.
`collections/example-hooks.js`
```js
// Collection config
module.exports = {
@@ -63,7 +64,7 @@ const beforeOperationHook = async ({
operation, // name of the operation
}) => {
return args; // Return operation arguments as necessary
}
};
```
### beforeValidate
@@ -78,7 +79,7 @@ const beforeValidateHook = async ({
originalDoc, // original document
}) => {
return data; // Return data to either create or update a document with
}
};
```
### beforeChange
@@ -93,7 +94,7 @@ const beforeChangeHook = async ({
originalDoc, // original document
}) => {
return data; // Return data to either create or update a document with
}
};
```
### afterChange
@@ -107,7 +108,7 @@ const afterChangeHook = async ({
operation, // name of the operation ie. 'create', 'update'
}) => {
return data;
}
};
```
### beforeRead
@@ -121,7 +122,7 @@ const beforeReadHook = async ({
query, // JSON formatted query
}) => {
return doc;
}
};
```
### afterRead
@@ -135,7 +136,7 @@ const afterReadHook = async ({
query, // JSON formatted query
}) => {
return doc;
}
};
```
### beforeDelete
@@ -172,7 +173,7 @@ const afterLoginHook = async ({
token, // user token
}) => {
return user;
}
};
```
### afterForgotPassword
@@ -186,5 +187,5 @@ const afterLoginHook = async ({
token, // user token
}) => {
return user;
}
};
```

View File

@@ -2,7 +2,7 @@
title: Field Hooks
label: Fields
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
---
@@ -26,6 +26,7 @@ Field-level hooks offer incredible potential for encapsulating your logic. They
## Config
Example field configuration:
```js
{
name: 'name',
@@ -47,8 +48,10 @@ 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.
<Banner type="success">
<strong>Tip:</strong><br />
It's a good idea to conditionally scope your logic based on which operation is executing.
<strong>Tip:</strong>
<br />
It's a good idea to conditionally scope your logic based on which operation is
executing.
</Banner>
#### Arguments
@@ -56,7 +59,7 @@ All field-level hooks are formatted to accept the same arguments, although some
Field Hooks receive one `args` argument that contains the following properties:
| Option | Description |
| ----------------- | -------------|
| ----------------- | ------------------------------------------------------------------------------------------------ |
| **`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. |
| **`originalDoc`** | The full original document in `update` or `read` operations. |
@@ -68,6 +71,10 @@ Field Hooks receive one `args` argument that contains the following properties:
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">
<strong>Important</strong><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.
<strong>Important</strong>
<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>

View File

@@ -2,7 +2,7 @@
title: Global Hooks
label: Globals
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
---
@@ -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.
`globals/example-hooks.js`
```js
// Global config
module.exports = {
@@ -48,7 +49,7 @@ const beforeValidateHook = async ({
originalDoc, // original document
}) => {
return data; // Return data to either create or update a document with
}
};
```
### beforeChange
@@ -63,7 +64,7 @@ const beforeChangeHook = async ({
originalDoc, // original document
}) => {
return data; // Return data to either create or update a document with
}
};
```
### afterChange
@@ -77,7 +78,7 @@ const afterChangeHook = async ({
operation, // name of the operation ie. 'create', 'update'
}) => {
return data;
}
};
```
### beforeRead

View File

@@ -2,12 +2,14 @@
title: Hooks Overview
label: Overview
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
---
<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>
**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
label: Overview
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
---
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">
<strong>Tip:</strong><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.
<strong>Tip:</strong>
<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>
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.
Example:
```js
import payload from 'payload';
import payload from "payload";
const afterChangeHook = async () => {
const posts = await payload.find({
collection: 'posts',
collection: "posts",
});
}
};
```
##### Accessing from the `req`
@@ -43,12 +50,13 @@ const afterChangeHook = async () => {
Payload is available anywhere you have access to the Express `req` - including within your access control and hook functions.
Example:
```js
const afterChangeHook = async ({ req: { payload }}) => {
const afterChangeHook = async ({ req: { payload } }) => {
const posts = await payload.find({
collection: 'posts',
collection: "posts",
});
}
};
```
### Local options available
@@ -56,7 +64,7 @@ const afterChangeHook = async ({ req: { payload }}) => {
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 |
| -------------------- | ------------ |
| ------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `collection` | Required for Collection operations. Specifies the Collection slug to operate against. |
| `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. |
@@ -66,11 +74,14 @@ You can specify more options within the Local API vs. REST or GraphQL due to the
| `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. |
*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">
<strong>Note:</strong><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.
<strong>Note:</strong>
<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>
## Collections
@@ -82,12 +93,13 @@ The following Collection operations are available through the Local API:
```js
// The created Post document is returned
const post = await payload.create({
collection: 'posts', // required
data: { // required
title: 'sure',
description: 'maybe',
collection: "posts", // required
data: {
// required
title: "sure",
description: "maybe",
},
locale: 'en',
locale: "en",
fallbackLocale: false,
user: dummyUserDoc,
overrideAccess: true,
@@ -96,7 +108,7 @@ const post = await payload.create({
// If creating verification-enabled auth doc,
// you can optionally disable the email that is auto-sent
disableVerificationEmail: true,
})
});
```
#### Find
@@ -124,15 +136,15 @@ const result = await payload.find({
```js
// Result will be a Post document.
const result = await payload.findByID({
collection: 'posts', // required
id: '507f1f77bcf86cd799439011', // required
collection: "posts", // required
id: "507f1f77bcf86cd799439011", // required
depth: 2,
locale: 'en',
locale: "en",
fallbackLocale: false,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
});
```
#### Update
@@ -140,19 +152,20 @@ const result = await payload.findByID({
```js
// Result will be the updated Post document.
const result = await payload.update({
collection: 'posts', // required
id: '507f1f77bcf86cd799439011', // required
data: { // required
title: 'sure',
description: 'maybe',
collection: "posts", // required
id: "507f1f77bcf86cd799439011", // required
data: {
// required
title: "sure",
description: "maybe",
},
depth: 2,
locale: 'en',
locale: "en",
fallbackLocale: false,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
});
```
#### Delete
@@ -160,15 +173,15 @@ const result = await payload.update({
```js
// Result will be the now-deleted Post document.
const result = await payload.delete({
collection: 'posts', // required
id: '507f1f77bcf86cd799439011', // required
collection: "posts", // required
id: "507f1f77bcf86cd799439011", // required
depth: 2,
locale: 'en',
locale: "en",
fallbackLocale: false,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
});
```
## Auth Operations
@@ -186,19 +199,20 @@ If a collection has [`Authentication`](/docs/authentication/overview) enabled, a
// }
const result = await payload.login({
collection: 'users', // required
data: { // required
email: 'dev@payloadcms.com',
password: 'rip',
collection: "users", // required
data: {
// required
email: "dev@payloadcms.com",
password: "rip",
},
req: req, // pass an Express `req` which will be provided to all hooks
res: res, // used to automatically set an HTTP-only auth cookie
depth: 2,
locale: 'en',
locale: "en",
fallbackLocale: false,
overrideAccess: false,
showHiddenFields: true,
})
});
```
#### Forgot Password
@@ -206,12 +220,13 @@ const result = await payload.login({
```js
// Returned token will allow for a password reset
const token = await payload.forgotPassword({
collection: 'users', // required
data: { // required
email: 'dev@payloadcms.com',
collection: "users", // required
data: {
// required
email: "dev@payloadcms.com",
},
req: req, // pass an Express `req` which will be provided to all hooks
})
});
```
#### Reset Password
@@ -223,13 +238,14 @@ const token = await payload.forgotPassword({
// user: { ... } // the user document that just logged in
// }
const result = await payload.forgotPassword({
collection: 'users', // required
data: { // required
token: 'afh3o2jf2p3f...', // the token generated from the forgotPassword operation
collection: "users", // required
data: {
// required
token: "afh3o2jf2p3f...", // the token generated from the forgotPassword operation
},
req: req, // pass an Express `req` which will be provided to all hooks
res: res, // used to automatically set an HTTP-only auth cookie
})
});
```
#### Unlock
@@ -237,13 +253,14 @@ const result = await payload.forgotPassword({
```js
// Returned result will be a boolean representing success or failure
const result = await payload.unlock({
collection: 'users', // required
data: { // required
email: 'dev@payloadcms.com',
collection: "users", // required
data: {
// required
email: "dev@payloadcms.com",
},
req: req, // pass an Express `req` which will be provided to all hooks
overrideAccess: true,
})
});
```
#### Verify
@@ -251,9 +268,9 @@ const result = await payload.unlock({
```js
// Returned result will be a boolean representing success or failure
const result = await payload.verify({
collection: 'users', // required
token: 'afh3o2jf2p3f...', // the token saved on the user as `_verificationToken`
})
collection: "users", // required
token: "afh3o2jf2p3f...", // the token saved on the user as `_verificationToken`
});
```
## Globals
@@ -265,14 +282,14 @@ The following Global operations are available through the Local API:
```js
// Result will be the Header Global.
const result = await payload.findGlobal({
global: 'header', // required
global: "header", // required
depth: 2,
locale: 'en',
locale: "en",
fallbackLocale: false,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
});
```
#### Update
@@ -280,22 +297,23 @@ const result = await payload.findGlobal({
```js
// Result will be the updated Header Global.
const result = await payload.updateGlobal({
global: 'header', // required
data: { // required
global: "header", // required
data: {
// required
nav: [
{
url: 'https://google.com',
url: "https://google.com",
},
{
url: 'https://payloadcms.com',
url: "https://payloadcms.com",
},
],
},
depth: 2,
locale: 'en',
locale: "en",
fallbackLocale: false,
user: dummyUser,
overrideAccess: false,
showHiddenFields: true,
})
});
```

View File

@@ -2,12 +2,14 @@
title: Production Deployment
label: Deployment
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
---
<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>
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.
<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>
##### 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:
`package.json`:
```js
{
"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
<Banner type="error">
<strong>Warning:</strong><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.
<strong>Warning:</strong>
<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>
##### 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.
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:**

View File

@@ -2,7 +2,7 @@
title: The Payload License
label: Licensing
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
---
@@ -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.
`server.js`:
```js
const payload = require('payload');
const payload = require("payload");
payload.init({
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.
<Banner type="success">
<strong>Note:</strong><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.
<strong>Note:</strong>
<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>
### 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:**
@@ -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.
<Banner type="success">
<strong>Note:</strong><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.
<strong>Note:</strong>
<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>
#### 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.
### 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)

View File

@@ -2,7 +2,7 @@
title: Preventing Production API Abuse
label: Preventing Abuse
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
---
@@ -19,15 +19,21 @@ 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:
| Option | Description |
| ---------------------------- | -------------|
| ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **`window`** | Time in milliseconds to track requests per IP |
| **`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 |
| **`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">
<strong>Warning:</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>.
<strong>Warning:</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>
#### 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)
### 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.
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
label: Overview
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
---
Payload provides an extremely granular querying language through all APIs. Each API takes the same syntax and fully supports all options.
<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>
### Simple queries
@@ -18,33 +26,30 @@ For example, say you have a collection as follows:
```js
const Post = {
slug: 'posts',
slug: "posts",
fields: [
{
name: 'color',
type: 'select',
options: [
'mint',
'dark-gray',
'white',
],
name: "color",
type: "select",
options: ["mint", "dark-gray", "white"],
},
{
name: 'featured',
type: 'checkbox',
}
]
}
name: "featured",
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:
```js
const query = {
color: { // property name to filter on
equals: 'mint', // operator to use and value to compare against
color: {
// 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.
@@ -52,7 +57,7 @@ The above example demonstrates a simple query but you can get much more complex.
### Operators
| Operator | Description |
| -------------------- | ------------ |
| -------------------- | ----------------------------------------------------------------------------------------- |
| `equals` | The value must be exactly equal. |
| `not_equals` | The query will return all documents where the value is not equal. |
| `greater_than` | For numeric or date-based fields. |
@@ -65,8 +70,10 @@ The above example demonstrates a simple query but you can get much more complex.
| `exists` | Only return documents where the value either exists (`true`) or does not exist (`false`). |
<Banner type="success">
<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.
<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.
</Banner>
### And / Or Logic
@@ -75,28 +82,30 @@ In addition to defining simple queries, you can join multiple queries together u
```js
const query = {
or: [ // array of OR conditions
or: [
// array of OR conditions
{
color: {
equals: 'mint',
equals: "mint",
},
},
{
and: [ // nested array of AND conditions
and: [
// nested array of AND conditions
{
color: {
equals: 'white',
}
equals: "white",
},
},
{
featured: {
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.
@@ -131,24 +140,29 @@ This one isn't too bad, but more complex queries get unavoidably more difficult
**For example, using fetch:**
```js
import qs from 'qs';
import qs from "qs";
const query = {
color: {
equals: 'mint',
equals: "mint",
},
// This query could be much more complex
// and QS would handle it beautifully
}
};
const getPosts = async () => {
const stringifiedQuery = qs.stringify({
where: query // ensure that `qs` adds the `where` property, too!
}, { addQueryPrefix: true });
const stringifiedQuery = qs.stringify(
{
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...
}
};
```
### Local API Queries
@@ -158,19 +172,18 @@ The Local API's `find` operation accepts an object exactly how you write it. For
```js
const getPosts = async () => {
const posts = await payload.find({
collection: 'posts',
collection: "posts",
where: {
color: {
equals: 'mint',
equals: "mint",
},
},
});
return posts;
}
};
```
## 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.
@@ -179,6 +192,7 @@ Payload `find` queries support a `sort` parameter through all APIs. Pass the `na
**`https://localhost:3000/api/posts?sort=-createdAt`**
**GraphQL example:**
```
query {
Posts(sort: "-createdAt") {
@@ -194,10 +208,10 @@ query {
```js
const getPosts = async () => {
const posts = await payload.find({
collection: 'posts',
sort: '-createdAt',
collection: "posts",
sort: "-createdAt",
});
return posts;
}
};
```

View File

@@ -2,7 +2,7 @@
title: Pagination
label: Pagination
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
---
@@ -11,7 +11,7 @@ All collection `find` queries are paginated automatically. Responses are returne
**`Find` response properties:**
| Property | Description |
| ------------- | ---------------------------------------------------------- |
| ------------- | --------------------------------------------------------- |
| docs | Array of documents in the collection |
| totalDocs | Total available documents within the collection |
| limit | Limit query parameter - defaults to `10` |
@@ -24,6 +24,7 @@ All collection `find` queries are paginated automatically. Responses are returne
| nextPage | `number` of next page, `null` if it doesn't exist |
**Example response:**
```js
{
// Document Array // highlight-line
@@ -55,6 +56,6 @@ 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:
| Control | Description |
| --------- | ----------------------------------------------------------------------------------------- |
| ------- | --------------------------------------- |
| `limit` | Limits the number of documents returned |
| `page` | Get a specific page number |

View File

@@ -2,12 +2,13 @@
title: REST API
label: Overview
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
---
<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>
All Payload API routes are mounted prefixed to your config's `routes.api` URL segment (default: `/api`).
@@ -25,7 +26,7 @@ Each collection is mounted using its `slug` value. For example, if a collection'
**All CRUD operations are exposed as follows:**
| Method | Path | Description |
| -------- | --------------------------- | -------------------------------------- |
| -------- | --------------------------- | --------------------------------- |
| `GET` | `/api/{collectionSlug}` | Find paginated documents |
| `GET` | `/api/{collectionSlug}/:id` | Find a specific document by ID |
| `POST` | `/api/{collectionSlug}` | Create a new document |
@@ -44,7 +45,7 @@ The `find` endpoint supports the following additional query parameters:
## Auth Operations
| Method | Path | Description |
| -------- | --------------------------- | ----------- |
| ------ | --------------------------------------- | --------------------------------------------------------------------------------------- |
| `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}/login` | [Logs in](/docs/authentication/operations#login) a user with email / password. |
@@ -59,6 +60,6 @@ The `find` endpoint supports the following additional query parameters:
Globals cannot be created or deleted, so there are only two REST endpoints opened:
| Method | Path | Description |
| -------- | --------------------------- | ----------------------- |
| ------ | --------------------------- | ----------------------- |
| `GET` | `/api/globals/{globalSlug}` | Get a global by slug |
| `POST` | `/api/globals/{globalSlug}` | Update a global by slug |

View File

@@ -2,16 +2,18 @@
title: Uploads
label: Overview
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
---
<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>
![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:**
@@ -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.
<Banner type="success">
<strong>Tip:</strong><br/>
A common pattern is to create a <strong>Media</strong> collection and enable <strong>upload</strong> on that collection.
<strong>Tip:</strong>
<br />A common pattern is to create a <strong>Media</strong> collection and
enable <strong>upload</strong> on that collection.
</Banner>
#### Collection Upload Options
| Option | Description |
| ---------------------- | -------------|
| **`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. |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **`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. |
| **`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. |
*An asterisk denotes that a property above is required.*
_An asterisk denotes that a property above is required._
**Example Upload collection:**
```js
const Media = {
slug: 'media',
slug: "media",
upload: {
staticURL: '/media',
staticDir: 'media',
staticURL: "/media",
staticDir: "media",
imageSizes: [
{
name: 'thumbnail',
name: "thumbnail",
width: 400,
height: 300,
crop: 'centre',
crop: "centre",
},
{
name: 'card',
name: "card",
width: 768,
height: 1024,
crop: 'centre',
}
crop: "centre",
},
],
adminThumbnail: 'thumbnail',
}
}
adminThumbnail: "thumbnail",
},
};
```
### 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:
```js
import { buildConfig } from 'payload/config';
import { buildConfig } from "payload/config";
export default buildConfig({
serverURL: 'http://localhost:3000',
serverURL: "http://localhost:3000",
collections: [
{
slug: 'media',
slug: "media",
fields: [
{
name: 'alt',
type: 'text',
name: "alt",
type: "text",
},
],
upload: true,
@@ -98,8 +102,8 @@ export default buildConfig({
upload: {
limits: {
fileSize: 5000000, // 5MB, written in bytes
}
}
},
},
});
```
@@ -114,8 +118,11 @@ Behind the scenes, Payload relies on [`sharp`](https://sharp.pixelplumbing.com/a
### Uploading Files
<Banner type="warning">
<strong>Important:</strong><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.
<strong>Important:</strong>
<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>
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.