docs: prepares docs for beta (#6808)

This commit is contained in:
Jacob Fletcher
2024-06-17 11:44:25 -04:00
committed by GitHub
85 changed files with 869 additions and 1368 deletions

View File

@@ -3,7 +3,7 @@ title: Collection Access Control
label: Collections
order: 20
desc: With Collection-level Access Control you can define which users can create, read, update or delete Collections.
keywords: collections, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: collections, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
You can define Collection-level Access Control within each Collection's `access` property. All Access Control functions accept one `args` argument.
@@ -51,10 +51,10 @@ 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` |
| **`data`** | The data passed to create the document with. |
| Option | Description |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
| **`data`** | The data passed to create the document with. |
**Example:**
@@ -80,7 +80,7 @@ Read access functions can return a boolean result or optionally return a [query
| Option | Description |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
| **`id`** | `id` of document requested, if within `findByID` |
**Example:**
@@ -111,7 +111,7 @@ Update access functions can return a boolean result or optionally return a [quer
| Option | Description |
| ---------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
| **`id`** | `id` of document requested to update |
| **`data`** | The data passed to update the document with |
@@ -138,7 +138,7 @@ Similarly to the Update function, returns a boolean or a [query constraint](/doc
| Option | Description |
| --------- | --------------------------------------------------------------------------------------------------- |
| **`req`** | The Express `request` object with additional `user` property, which is the currently logged in user |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object with additional `user` property, which is the currently logged in user |
| **`id`** | `id` of document requested to delete |
**Example:**
@@ -173,7 +173,7 @@ If the Collection is [used to access the Payload Admin panel](/docs/admin/overvi
| Option | Description |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
### Unlock
@@ -183,4 +183,4 @@ Determines which users can [unlock](/docs/authentication/operations#unlock) othe
| Option | Description |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |

View File

@@ -3,7 +3,7 @@ title: Field-level Access Control
label: Fields
order: 30
desc: Field-level Access Control is specified within a field's config, and allows you to define which users can create, read or update Fields.
keywords: fields, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: fields, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Field Access Control is specified with functions inside a field's config. All field-level Controls return a boolean value to allow or deny access for the specified operation. No field-level Access Controls support returning query constraints. All Access Control functions accept one `args` argument.
@@ -47,7 +47,7 @@ Returns a boolean which allows or denies the ability to set a field's value when
| Option | Description |
| ----------------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
| **`data`** | The full data passed to create the document. |
| **`siblingData`** | Immediately adjacent field data passed to create the document. |
@@ -59,7 +59,7 @@ Returns a boolean which allows or denies the ability to read a field's value. If
| Option | Description |
| ----------------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
| **`id`** | `id` of the document being read |
| **`doc`** | The full document data. |
| **`siblingData`** | Immediately adjacent field data of the document being read. |
@@ -74,7 +74,7 @@ If `false` is returned and you attempt to update the field's value, the operatio
| Option | Description |
| ----------------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
| **`id`** | `id` of the document being updated |
| **`data`** | The full data passed to update the document. |
| **`siblingData`** | Immediately adjacent field data passed to update the document with. |

View File

@@ -3,7 +3,7 @@ title: Globals Access Control
label: Globals
order: 40
desc: Global-level Access Control is specified within each Global's `access` property and allows you to define which users can read or update Globals.
keywords: globals, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: globals, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
You can define Global-level Access Control within each Global's `access` property. All Access Control functions accept one `args` argument.
@@ -45,7 +45,7 @@ Returns a boolean result or optionally a [query constraint](/docs/queries/overvi
| Option | Description |
| --------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
### Update
@@ -55,5 +55,5 @@ Returns a boolean result or optionally a [query constraint](/docs/queries/overvi
| Option | Description |
| ---------- | -------------------------------------------------------------------------- |
| **`req`** | The Express `request` object containing the currently authenticated `user` |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user` |
| **`data`** | The data passed to update the global with. |

View File

@@ -3,7 +3,7 @@ title: Access Control
label: Overview
order: 10
desc: Payload makes it simple to define and manage access control. By declaring roles, you can set permissions and restrict what your users can interact with.
keywords: overview, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: overview, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Access control within Payload is extremely powerful while remaining easy and intuitive to manage. Declaring who should have access to what documents is no more complex than writing a simple JavaScript function that either returns a `boolean` or a [`query`](/docs/queries/overview) constraint to restrict which documents users can interact with.
@@ -21,7 +21,7 @@ Access control within Payload is extremely powerful while remaining easy and int
## Default Settings
**By default, all Collections and Globals require that a user is logged in to be able to interact in any way.** The default Access Control function evaluates the `user` from the Express `req` and returns `true` if a user is logged in, and `false` if not.
**By default, all Collections and Globals require that a user is logged in to be able to interact in any way.** The default Access Control function evaluates the `user` from the `req` and returns `true` if a user is logged in, and `false` if not.
**Default Access function:**
@@ -37,9 +37,11 @@ const defaultPayloadAccess = ({ req: { user } }) => {
<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>
whatever it needs. But, you can opt back in by setting the option
<strong>
overrideAccess
</strong>{' '}
</strong>
{' '}
to <strong>false</strong>.
</Banner>

View File

@@ -1,54 +0,0 @@
---
title: Bundlers
label: Bundlers
order: 60
desc: Bundlers are used to bundle the code that serves Payload's Admin Panel.
---
Payload has two official bundlers, the [Webpack Bundler](/docs/admin/webpack) and the [Vite Bundler](/docs/admin/vite). You must install a bundler to use the admin panel.
## Install a bundler
Webpack (recommended):
```text
yarn add @payloadcms/bundler-webpack
```
Vite (beta):
```text
yarn add @payloadcms/bundler-vite
```
## Configure the bundler
```ts
// payload.config.ts
import { buildConfig } from 'payload/config'
import { webpackBundler } from '@payloadcms/bundler-webpack'
// import { viteBundler } from '@payloadcms/bundler-vite'
export default buildConfig({
// highlight-start
admin: {
bundler: webpackBundler(), // or viteBundler()
},
// highlight-end
})
```
## What are bundlers?
At their core, a bundler's main goal is to take a bunch of files and turn them into a few optimized files that you ship to the browser. The admin UI has a root `index.html` entry point, and from there the bundler traverses the dependency tree, bundling all of the files that are required from that point on.
Since the bundled file is sent to the browser, it can't include any server-only code. You will need to remove any server-only code from your admin UI before bundling it. You can learn more about [excluding server code](/docs/admin/excluding-server-code) section.
<Banner type="warning">
<strong>Using environment variables in the admin UI</strong>
<br />
Bundles should not contain sensitive information. By default, Payload excludes env variables from
the bundle. If you need to use env variables in your payload config, you need to prefix them with
`PAYLOAD_PUBLIC_` to make them available to the client-side code.
</Banner>

View File

@@ -3,12 +3,16 @@ title: Swap in your own React components
label: Custom Components
order: 20
desc: Fully customize your Admin Panel by swapping in your own React components. Add fields, remove views, update routes and change functions to sculpt your perfect Dashboard.
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
While designing the Payload Admin panel, we determined it should be as minimal and straightforward as possible to allow easy customization and control. There are many times where you may want to completely control how a whole view or a field works. You might even want to add in new views entirely. In order for Payload to support this level of customization without introducing versioning / future-proofing issues, Payload provides for a pattern to supply your own React components via your Payload config.
The [Payload Admin](./overview) panel is designed to be as minimal and straightforward as possible to allow easy customization and control. In order for Payload to support this level of customization without introducing versioning or future-proofing issues, Payload provides a pattern for you to supply your own React components via your Payload config.
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="warning">
All Custom Components in the Admin Panel are [React Server Components](https://react.dev/reference/rsc/server-components). This means they are rendered on the server
</Banner>
To swap in your own React component, first, consult the list of available components 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>
@@ -33,9 +37,9 @@ You can override a set of admin panel-wide components by providing a component t
| **`logout.Button`** | A custom React component. |
| **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. |
| **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. |
| **`providers`** | Define your own provider components that will wrap the Payload Admin UI. [More](#custom-providers) |
| **`actions`** | Array of custom components to be rendered in the Payload Admin UI header, providing additional interactivity and functionality. |
| **`views`** | Override or create new views within the Payload Admin UI. [More](#views) |
| **`providers`** | Define your own provider components that will wrap the [Admin Panel](./overview). [More](#custom-providers) |
| **`actions`** | Array of custom components to be rendered in the [Admin Panel](./overview) header, providing additional interactivity and functionality. |
| **`views`** | Override or create new [Views](./views) within the [Admin Panel](./overview). |
Here is a full example showing how to swap some of these components for your own.
@@ -73,78 +77,6 @@ export default buildConfig({
})
```
### Views
You can easily swap entire views with your own by using the `admin.components.views` property. At the root level, Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| --------------- | ----------------------------------------------------------------------------- |
| **`Account`** | The Account view is used to show the currently logged in user's Account page. |
| **`Dashboard`** | The main landing page of the Admin panel. |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. For example:
```ts
// payload.config.ts
{
// ...
admin: {
components: {
views: {
Account: MyCustomAccountView,
Dashboard: MyCustomDashboardView,
},
},
},
}
```
For more granular control, pass a configuration object instead. Each view corresponds to its own `<Route />` component in [React Router v5](https://v5.reactrouter.com). Payload exposes all of the properties of React Router:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| **`Component`** \* | Pass in the component that should be rendered when a user navigates to this route. |
| **`path`** \* | React Router `path`. [See the React Router docs](https://v5.reactrouter.com/web/api/Route/path-string-string) for more info. |
| **`exact`** | React Router `exact` property. [More](https://v5.reactrouter.com/web/api/Route/exact-bool) |
| **`strict`** | React Router `strict` property. [More](https://v5.reactrouter.com/web/api/Route/strict-bool) |
| **`sensitive`** | React Router `sensitive` property. [More](https://v5.reactrouter.com/web/api/Route/sensitive-bool) |
_\* An asterisk denotes that a property is required._
### Adding new views
To add a _new_ view to the Admin Panel, simply add another key to the `views` object with at least a `path` and `Component` property. For example:
```ts
// payload.config.ts
{
// ...
admin: {
components: {
views: {
MyCustomView: {
Component: MyCustomView,
path: '/my-custom-view',
},
},
},
},
}
```
<Banner type="warning">
<strong>Note:</strong>
<br />
Routes are cascading. This means that unless explicitly given the `exact` property, they will
match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all
routes in your application. Alternatively, you could define your nested route _before_ your parent
route.
</Banner>
_For more examples regarding how to customize components, look at the following [examples](https://github.com/payloadcms/payload/tree/main/test/admin/components)._
For help on how to build your own custom view components, see [building a custom view component](#building-a-custom-view-component).
## Collections
You can override components on a collection-by-collection basis via the `admin.components` property.
@@ -159,25 +91,33 @@ You can override components on a collection-by-collection basis via the `admin.c
| **`edit.SaveDraftButton`** | Replace the default `Save Draft` button with a custom component. Drafts must be enabled and autosave must be disabled. |
| **`edit.PublishButton`** | Replace the default `Publish` button with a custom component. Drafts must be enabled. |
| **`edit.PreviewButton`** | Replace the default `Preview` button with a custom component. |
| **`views`** | Override or create new views within the Payload Admin UI. [More](#collection-views) |
| **`views`** | Override or create new [Views](./views) within the [Admin Panel](./overview). |
Here is a full example showing how to swap some of these components for your own:
`Collection.ts`
`CustomSaveButton.tsx`
```tsx
import * as React from 'react'
import { CustomSaveButtonProps } from 'payload/types'
import {
CustomSaveButtonProps,
CustomSaveDraftButtonProps,
CustomPublishButtonProps,
CustomPreviewButtonProps,
} from 'payload/types'
export const CustomSaveButton: CustomSaveButtonProps = ({ DefaultButton, label, save }) => {
return <DefaultButton label={label} save={save} />
const CustomSaveButton: CustomSaveButtonProps = ({
DefaultButton,
label,
save
}) => {
return (
<DefaultButton
label={label}
save={save}
/>
)
}
```
`CustomSaveDraftButton.tsx`
```tsx
import { CustomSaveDraftButtonProps } from 'payload/types'
export const CustomSaveDraftButton: CustomSaveDraftButtonProps = ({
DefaultButton,
@@ -185,8 +125,20 @@ export const CustomSaveDraftButton: CustomSaveDraftButtonProps = ({
label,
saveDraft,
}) => {
return <DefaultButton label={label} disabled={disabled} saveDraft={saveDraft} />
return (
<DefaultButton
label={label}
disabled={disabled}
saveDraft={saveDraft}
/>
)
}
```
`CustomPublishButton.tsx`
```tsx
import { CustomPreviewButtonProps } from 'payload/types'
export const CustomPublishButton: CustomPublishButtonProps = ({
DefaultButton,
@@ -194,8 +146,20 @@ export const CustomPublishButton: CustomPublishButtonProps = ({
label,
publish,
}) => {
return <DefaultButton label={label} disabled={disabled} publish={publish} />
return (
<DefaultButton
label={label}
disabled={disabled}
publish={publish}
/>
)
}
```
`CustomPreviewButton`
```tsx
import { CustomPreviewButtonProps } from 'payload/types'
export const CustomPreviewButton: CustomPreviewButtonProps = ({
DefaultButton,
@@ -203,8 +167,25 @@ export const CustomPreviewButton: CustomPreviewButtonProps = ({
label,
preview,
}) => {
return <DefaultButton label={label} disabled={disabled} preview={preview} />
return (
<DefaultButton
label={label}
disabled={disabled}
preview={preview}
/>
)
}
```
`collection.ts`
```tsx
import * as React from 'react'
import { CustomSaveButton } from './CustomSaveButton'
import { CustomSaveDraftButton } from './CustomSaveDraftButton'
import { CustomPublishButton } from './CustomPublishButton'
import { CustomPreviewButton } from './CustomPreviewButton'
export const MyCollection: SanitizedCollectionConfig = {
slug: 'my-collection',
@@ -221,82 +202,6 @@ export const MyCollection: SanitizedCollectionConfig = {
}
```
### Collection views
To swap out entire views on collections, you can use the `admin.components.views` property on the collection's config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ---------- | ------------------------------------------------------------------------- |
| **`Edit`** | The Edit view is used to edit a single document for a given collection. |
| **`List`** | The List view is used to show a list of documents for a given collection. |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, tabs, etc, _as well as all nested routes_.
```ts
// Collection.ts
{
// ...
admin: {
components: {
views: {
Edit: MyCustomEditView,
List: MyCustomListView,
},
},
},
}
```
_For help on how to build your own custom view components, see [building a custom view component](#building-a-custom-view-component)._
**Customizing Nested Views within 'Edit' in Collections**
The `Edit` view in collections consists of several nested views, each serving a unique purpose. You can customize these nested views using the `admin.components.views.Edit` property in the collection's configuration. This approach allows you to replace specific nested views while keeping the overall structure of the `Edit` view intact, including the page breadcrumbs, title, tabs, etc.
Here's an example of how you can customize nested views within the `Edit` view in collections, including the use of the `actions` property:
```ts
// Collection.ts
{
// ...
admin: {
components: {
views: {
Edit: {
Default: {
Component: MyCustomDefaultTab,
actions: [CollectionEditButton], // Custom actions for the default edit view
},
API: {
Component: MyCustomAPIView,
actions: [CollectionAPIButton], // Custom actions for API view
},
LivePreview: {
Component: MyCustomLivePreviewView,
actions: [CollectionLivePreviewButton], // Custom actions for Live Preview
},
Version: {
Component: MyCustomVersionView,
actions: [CollectionVersionButton], // Custom actions for Version view
},
Versions: {
Component: MyCustomVersionsView,
actions: [CollectionVersionsButton], // Custom actions for Versions view
},
},
List: {
actions: [CollectionListButton],
},
},
},
},
}
```
**Adding New Tabs to 'Edit' View**
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
## Globals
As with Collections, you can override components on a global-by-global basis via the `admin.components` property.
@@ -307,362 +212,11 @@ As with Collections, you can override components on a global-by-global basis via
| **`elements.SaveDraftButton`** | Replace the default `Save Draft` button with a custom component. Drafts must be enabled and autosave must be disabled. |
| **`elements.PublishButton`** | Replace the default `Publish` button with a custom component. Drafts must be enabled. |
| **`elements.PreviewButton`** | Replace the default `Preview` button with a custom component. |
| **`views`** | Override or create new views within the Payload Admin UI. [More](#global-views) |
### Global views
To swap out views for globals, you can use the `admin.components.views` property on the global's config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ---------- | ------------------------------------------------------------------- |
| **`Edit`** | The Edit view is used to edit a single document for a given Global. |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, and tabs, _as well as all nested views_.
```ts
// Global.ts
{
// ...
admin: {
components: {
views: {
Edit: MyCustomEditView,
},
},
},
}
```
_For help on how to build your own custom view components, see [building a custom view component](#building-a-custom-view-component)._
**Customizing Nested Views within 'Edit' in Globals**
Similar to collections, Globals allow for detailed customization within the `Edit` view. This includes the ability to swap specific nested views while maintaining the overall structure of the `Edit` view. You can use the `admin.components.views.Edit` property in the Globals configuration to achieve this, and this will only replace the nested view, leaving the page breadcrumbs, title, and tabs intact.
Here's how you can customize nested views within the `Edit` view in Globals, including the use of the `actions` property:
```ts
// Global.ts
{
// ...
admin: {
components: {
views: {
Edit: {
Default: {
Component: MyCustomGlobalDefaultTab,
actions: [GlobalEditButton], // Custom actions for the default edit view
},
API: {
Component: MyCustomGlobalAPIView,
actions: [GlobalAPIButton], // Custom actions for API view
},
LivePreview: {
Component: MyCustomGlobalLivePreviewView,
actions: [GlobalLivePreviewButton], // Custom actions for Live Preview
},
Version: {
Component: MyCustomGlobalVersionView,
actions: [GlobalVersionButton], // Custom actions for Version view
},
Versions: {
Component: MyCustomGlobalVersionsView,
actions: [GlobalVersionsButton], // Custom actions for Versions view
},
},
},
},
},
}
```
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
## Custom Tabs
You can easily swap individual collection or global edit views. To do this, pass an _object_ to the `admin.components.views.Edit` property of the config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **`Default`** | The Default view is the primary view in which your document is edited. |
| **`Versions`** | The Versions view is used to view the version history of a single document. [More details](../versions) |
| **`Version`** | The Version view is used to view a single version of a single document for a given collection. [More details](../versions). |
| **`API`** | The API view is used to display the REST API JSON response for a given document. |
| **`LivePreview`** | The LivePreview view is used to display the Live Preview interface. [More details](../live-preview) |
Here is an example:
```ts
// Collection.ts or Global.ts
export const MyCollection: SanitizedCollectionConfig = {
slug: 'my-collection',
admin: {
components: {
views: {
Edit: {
// You can also define `components.views.Edit` as a component, this will override _all_ nested views
Default: MyCustomDefaultTab,
Versions: MyCustomVersionsTab,
Version: MyCustomVersionTab,
API: MyCustomAPITab,
LivePreview: MyCustomLivePreviewTab,
},
},
},
},
}
```
To add a _new_ tab to the `Edit` view, simply add another key to `components.views.Edit[key]` with at least a `path` and `Component` property. For example:
```ts
// `Collection.ts` or `Global.ts`
export const MyCollection: SanitizedCollectionConfig = {
slug: 'my-collection',
admin: {
components: {
views: {
Edit: {
MyCustomTab: {
Component: MyCustomTab,
path: '/my-custom-tab',
// You an swap the entire tab component out for your own
Tab: MyCustomTab,
},
AnotherCustomView: {
Component: AnotherCustomView,
path: '/another-custom-view',
// Or you can use the default tab component and just pass in your own label and href
Tab: {
label: 'Another Custom View',
href: '/another-custom-view',
},
},
},
},
},
},
}
```
## Building a custom view component
Your custom view components will be given all the props that a React Router `<Route />` typically would receive, as well as two props from Payload:
| Prop | Description |
| ----------------------- | ---------------------------------------------------------------------------- |
| **`user`** | The currently logged in user. Will be `null` if no user is logged in. |
| **`canAccessAdmin`** \* | If the currently logged in user is allowed to access the admin panel or not. |
<Banner type="warning">
<strong>Note:</strong>
<br />
It's up to you to secure your custom views. If your view requires a user to be logged in or to
have certain access rights, you should handle that within your view component yourself.
</Banner>
#### Example
You can find examples of custom views in the [Payload source code `/test/admin/components/views` folder](https://github.com/payloadcms/payload/tree/main/test/admin/components/views). There, you'll find two custom views:
1. A custom view that uses the `DefaultTemplate`, which is the built-in Payload template that displays the sidebar and "eyebrow nav"
1. A custom view that uses the `MinimalTemplate` - which is just a centered template used for things like logging in or out
To see how to pass in your custom views to create custom views of your own, take a look at the `admin.components.views` property of the [Payload test admin config](https://github.com/payloadcms/payload/blob/main/test/admin/config.ts).
## Fields
All Payload fields support the ability to swap in your own React components. So, for example, instead of rendering a default Text input, you might need to render a color picker that provides the editor with a custom color picker interface to restrict the data entered to colors only.
<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.
</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. [More](#cell-component) |
| **`Field`** | Swap out the field itself within all `Edit` views. [More](#field-component) |
As an alternative to replacing the entire Field component, you may want to keep the majority of the default Field component and only swap components within. This allows you to replace the **`Label`** or **`Error`** within a field component or add additional components inside the field with **`beforeInput`** or **`afterInput`**. **`beforeInput`** and **`afterInput`** are allowed in any fields that don't contain other fields, except [UI](/docs/fields/ui) and [Rich Text](/docs/fields/rich-text).
| Component | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
| **`Label`** | Override the default Label in the Field Component. [More](#label-component) |
| **`Error`** | Override the default Label in the Field Component. [More](#error-component) |
| **`beforeInput`** | An array of elements that will be added before `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
| **`afterInput`** | An array of elements that will be added after `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
## Cell Component
These are the props that will be passed to your custom Cell to use in your own components.
| Property | Description |
| ---------------- | ----------------------------------------------------------------- |
| **`field`** | An object that includes the field configuration. |
| **`colIndex`** | A unique number for the column in the list. |
| **`collection`** | An object with the config of the collection that the field is in. |
| **`cellData`** | The data for the field that the cell represents. |
| **`rowData`** | An object with all the field values for the row. |
#### Example
```tsx
import React from 'react'
import type { Props } from 'payload/components/views/Cell'
import './index.scss'
const baseClass = 'custom-cell'
const CustomCell: React.FC<Props> = (props) => {
const { field, colIndex, collection, cellData, rowData } = props
return <span className={baseClass}>{cellData}</span>
}
```
## Field Component
When writing your own custom components you can make use of a number of hooks to set data, get reactive changes to other fields, get the id of the document or interact with a context from a custom provider.
## Sending and receiving values from the form
When swapping out the `Field` component, you'll be responsible for sending and receiving the field's `value` from the form itself. To do so, import the `useField` hook as follows:
```tsx
import { useField } from 'payload/components/forms'
const CustomTextField: React.FC<{ path: string }> = ({ path }) => {
// highlight-start
const { value, setValue } = useField<string>({ path })
// highlight-end
return <input onChange={(e) => setValue(e.target.value)} value={value} />
}
```
<Banner type="success">
For more information regarding the hooks that are available to you while you build custom
components, including the <strong>useField</strong> hook, [click here](/docs/admin/hooks).
</Banner>
## Label Component
These are the props that will be passed to your custom Label.
| Property | Description |
| -------------- | ---------------------------------------------------------------- |
| **`htmlFor`** | Property used to set `for` attribute for label. |
| **`label`** | Label value provided in field, it can be used with i18n. |
| **`required`** | A boolean value that represents if the field is required or not. |
#### Example
```tsx
'use client'
import React from 'react'
import { getTranslation } from '@payloadcms/translations'
import { useTranslation } from '@payloadcms/ui/providers/Translation'
type Props = {
htmlFor?: string
label?: Record<string, string> | false | string
required?: boolean
}
const CustomLabel: React.FC<Props> = (props) => {
const { htmlFor, label, required = false } = props
const { i18n } = useTranslation()
if (label) {
return (
<span>
{getTranslation(label, i18n)}
{required && <span className="required">*</span>}
</span>
)
}
return null
}
```
## Error Component
These are the props that will be passed to your custom Error.
| Property | Description |
| --------------- | ------------------------------------------------------------- |
| **`message`** | The error message. |
| **`showError`** | A boolean value that represents if the error should be shown. |
#### Example
```tsx
import React from 'react'
type Props = {
message: string
showError?: boolean
}
const CustomError: React.FC<Props> = (props) => {
const { message, showError } = props
if (showError) {
return <p style={{ color: 'red' }}>{message}</p>
} else return null
}
```
## afterInput and beforeInput
With these properties you can add multiple components before and after the input element. For example, you can add an absolutely positioned button to clear the current field value.
#### Example
```tsx
import React from 'react'
import { Field } from 'payload/types'
import './style.scss'
const ClearButton: React.FC = () => {
return (
<button
onClick={() => {
/* ... */
}}
>
X
</button>
)
}
const titleField: Field = {
name: 'title',
type: 'text',
admin: {
components: {
afterInput: [ClearButton],
},
},
}
export default titleField
```
| **`views`** | Override or create new [Views](./views) within the [Admin Panel](./overview). |
## Custom providers
As your admin customizations gets more complex you may want to share state between fields or other components. You can add custom providers to do add your own context to any Payload app for use in other custom components within the admin panel. Within your config add `admin.components.providers`, these can be used to share context or provide other custom functionality. Read the [React context](https://reactjs.org/docs/context.html) docs to learn more.
As your admin customizations gets more complex you may want to share state between fields or other components. You can add custom providers to do add your own context to any Payload app for use in other custom components within the [Admin Panel](./overview). Within your config add `admin.components.providers`, these can be used to share context or provide other custom functionality. See the [React Context](https://reactjs.org/docs/context.html) docs to learn more.
<Banner type="warning">
<strong>Reminder:</strong> Don't forget to pass the **children** prop through the provider

View File

@@ -1,9 +1,9 @@
---
title: Customizing CSS & SCSS
label: Customizing CSS
order: 40
order: 60
desc: Customize your Payload admin panel further by adding your own CSS or SCSS style sheet to the configuration, powerful theme and design options are waiting for you.
keywords: admin, css, scss, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: admin, css, scss, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
## Adding your own CSS / SCSS

View File

@@ -1,206 +0,0 @@
---
title: Excluding server-only code from admin UI
label: Excluding server code
order: 70
desc: Learn how to exclude server-only code from the Payload Admin UI bundle
---
Because the Admin Panel browser bundle includes your Payload Config file, files using server-only modules need to be excluded.
It's common for your config to rely on server only modules to perform logic in access control functions, hooks, and other contexts.
Any file that imports a server-only module such as `fs`, `stripe`, `authorizenet`, `nodemailer`, etc. **cannot** be included in the browser bundle.
## Example Scenario
Say we have a collection called `Subscriptions` that has a `beforeChange` hook that creates a Stripe subscription whenever a Subscription document is created in Payload.
**Collection config**:
```ts
// collections/Subscriptions/index.ts
import { CollectionConfig } from 'payload/types'
import createStripeSubscription from './hooks/createStripeSubscription'
export const Subscription: CollectionConfig = {
slug: 'subscriptions',
hooks: {
beforeChange: [createStripeSubscription],
},
fields: [
{
name: 'stripeSubscriptionID',
type: 'text',
required: true,
},
],
}
```
**Collection hook**:
```ts
// collections/Subscriptions/hooks/createStripeSubscription.ts
// highlight-start
import Stripe from 'stripe' // <-- server-only module
// highlight-end
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)
export const createStripeSubscription = async ({ data, operation }) => {
if (operation === 'create') {
const dataWithStripeID = { ...data }
// use Stripe to create a Stripe subscription
const subscription = await stripe.subscriptions.create({
// Configure the subscription accordingly
})
// Automatically add the Stripe subscription ID
// to the data that will be saved to this Subscription doc
dataWithStripeID.stripeSubscriptionID = subscription.id
return dataWithStripeID
}
return data
}
```
<Banner type="error">
<strong>Warning:</strong>
<br />
The above code is NOT production-ready and should not be referenced to create Stripe
subscriptions. Although creating a beforeChange hook is a completely valid spot to do things like
create subscriptions, the code above is incomplete and insecure, meant for explanation purposes
only.
</Banner>
**As-is, this collection will prevent your Admin panel from bundling or loading correctly, because Stripe relies on some Node-only packages.**
## How to exclude server-only code
You need to make sure that you use `alias`es to tell your bundler to import "safe" files vs. attempting to import any server-side code that you need to get rid of. Depending on your bundler (Webpack, Vite, etc.) the steps involved may be slightly different.
The basic idea is to create a file that exports an empty object, and then alias import paths of any files that import server-only modules to that empty object file.
This way when your bundler goes to import a file that contains server-only modules, it will instead import the empty object file, which will not break the browser bundle.
### Aliasing server-only modules
To remove files that contain server-only modules from your bundle, you can use an `alias`.
In the Subscriptions config file above, we are importing the hook like so:
```ts
// collections/Subscriptions/index.ts
import createStripeSubscription from './hooks/createStripeSubscription'
```
By default the browser bundle will now include all the code from that file and any files down the tree. We know that the file imports `stripe`.
To fix this, we need to alias the `createStripeSubscription` file to a different file that can safely be included in the browser bundle.
First, we will create a mock file to replace the server-only file when bundling:
```js
// mocks/modules.js
export default {}
/**
* NOTE: if you are destructuring an import
* the mock file will need to export matching
* variables as the destructured object.
*
* export const namedExport = {}
*/
```
Aliasing with [Webpack](/docs/admin/webpack) can be done by:
```ts
// payload.config.ts
import { buildConfig } from 'payload/config'
import { webpackBundler } from '@payloadcms/bundler-webpack'
import { Subscriptions } from './collections/Subscriptions'
const mockModulePath = path.resolve(__dirname, 'mocks/emptyObject.js')
const fullFilePath = path.resolve(
__dirname,
'collections/Subscriptions/hooks/createStripeSubscription',
)
export default buildConfig({
collections: [Subscriptions],
admin: {
bundler: webpackBundler(),
webpack: (config) => {
return {
...config,
resolve: {
...config.resolve,
// highlight-start
alias: {
...config.resolve.alias,
[fullFilePath]: mockModulePath,
},
// highlight-end
},
}
},
},
})
```
Aliasing with [Vite](/docs/admin/vite) can be done by:
```ts
// payload.config.ts
import { buildConfig } from 'payload/config'
import { viteBundler } from '@payloadcms/bundler-vite'
import { Subscriptions } from './collections/Subscriptions'
const mockModulePath = path.resolve(__dirname, 'mocks/emptyObject.js')
export default buildConfig({
collections: [Subscriptions],
admin: {
bundler: viteBundler(),
vite: (incomingViteConfig) => {
const existingAliases = incomingViteConfig?.resolve?.alias || {}
let aliasArray: { find: string | RegExp; replacement: string }[] = []
// Pass the existing Vite aliases
if (Array.isArray(existingAliases)) {
aliasArray = existingAliases
} else {
aliasArray = Object.values(existingAliases)
}
// highlight-start
// Add your own aliases using the find and replacement keys
// remember, vite aliases are exact-match only
aliasArray.push({
find: '../server-only-module',
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js'),
})
// highlight-end
return {
...incomingViteConfig,
resolve: {
...(incomingViteConfig?.resolve || {}),
alias: aliasArray,
},
}
},
},
})
```

194
docs/admin/fields.mdx Normal file
View File

@@ -0,0 +1,194 @@
---
title: Customizing Fields
label: Customizing Fields
order: 40
desc:
keywords:
---
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.
</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. [More](#cell-component) |
| **`Field`** | Swap out the field itself within all `Edit` views. [More](#field-component) |
As an alternative to replacing the entire Field component, you may want to keep the majority of the default Field component and only swap components within. This allows you to replace the **`Label`** or **`Error`** within a field component or add additional components inside the field with **`beforeInput`** or **`afterInput`**. **`beforeInput`** and **`afterInput`** are allowed in any fields that don't contain other fields, except [UI](/docs/fields/ui) and [Rich Text](/docs/fields/rich-text).
| Component | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
| **`Label`** | Override the default Label in the Field Component. [More](#label-component) |
| **`Error`** | Override the default Label in the Field Component. [More](#error-component) |
| **`beforeInput`** | An array of elements that will be added before `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
| **`afterInput`** | An array of elements that will be added after `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
## Cell Component
These are the props that will be passed to your custom Cell to use in your own components.
| Property | Description |
| ---------------- | ----------------------------------------------------------------- |
| **`field`** | An object that includes the field configuration. |
| **`colIndex`** | A unique number for the column in the list. |
| **`collection`** | An object with the config of the collection that the field is in. |
| **`cellData`** | The data for the field that the cell represents. |
| **`rowData`** | An object with all the field values for the row. |
#### Example
```tsx
import React from 'react'
import type { Props } from 'payload/components/views/Cell'
import './index.scss'
const baseClass = 'custom-cell'
const CustomCell: React.FC<Props> = (props) => {
const { field, colIndex, collection, cellData, rowData } = props
return <span className={baseClass}>{cellData}</span>
}
```
## Field Component
When writing your own custom components you can make use of a number of hooks to set data, get reactive changes to other fields, get the id of the document or interact with a context from a custom provider.
### Sending and receiving values from the form
When swapping out the `Field` component, you'll be responsible for sending and receiving the field's `value` from the form itself. To do so, import the `useField` hook as follows:
```tsx
import { useField } from 'payload/components/forms'
const CustomTextField: React.FC<{ path: string }> = ({ path }) => {
// highlight-start
const { value, setValue } = useField<string>({ path })
// highlight-end
return <input onChange={(e) => setValue(e.target.value)} value={value} />
}
```
<Banner type="success">
For more information regarding the hooks that are available to you while you build custom
components, including the <strong>useField</strong> hook, [click here](/docs/admin/hooks).
</Banner>
## Label Component
These are the props that will be passed to your custom Label.
| Property | Description |
| -------------- | ---------------------------------------------------------------- |
| **`htmlFor`** | Property used to set `for` attribute for label. |
| **`label`** | Label value provided in field, it can be used with i18n. |
| **`required`** | A boolean value that represents if the field is required or not. |
#### Example
```tsx
import React from 'react'
import { useTranslation } from 'react-i18next'
import { getTranslation } from 'payload/utilities/getTranslation'
type Props = {
htmlFor?: string
label?: Record<string, string> | false | string
required?: boolean
}
const CustomLabel: React.FC<Props> = (props) => {
const { htmlFor, label, required = false } = props
const { i18n } = useTranslation()
if (label) {
return (
<span>
{getTranslation(label, i18n)}
{required && <span className="required">*</span>}
</span>
)
}
return null
}
```
## Error Component
These are the props that will be passed to your custom Error.
| Property | Description |
| --------------- | ------------------------------------------------------------- |
| **`message`** | The error message. |
| **`showError`** | A boolean value that represents if the error should be shown. |
#### Example
```tsx
import React from 'react'
type Props = {
message: string
showError?: boolean
}
const CustomError: React.FC<Props> = (props) => {
const { message, showError } = props
if (showError) {
return <p style={{ color: 'red' }}>{message}</p>
} else return null
}
```
## afterInput and beforeInput
With these properties you can add multiple components before and after the input element. For example, you can add an absolutely positioned button to clear the current field value.
#### Example
```tsx
import React from 'react'
import { Field } from 'payload/types'
import './style.scss'
const ClearButton: React.FC = () => {
return (
<button
onClick={() => {
/* ... */
}}
>
X
</button>
)
}
const titleField: Field = {
name: 'title',
type: 'text',
admin: {
components: {
afterInput: [ClearButton],
},
},
}
export default titleField
```

View File

@@ -1,9 +1,9 @@
---
title: React Hooks
label: React Hooks
order: 30
order: 50
desc: Make use of all of the powerful React hooks that Payload provides.
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload provides a variety of powerful hooks that can be used within your own React components. With them, you can interface with Payload itself and build just about any type of complex customization you can think of—directly in familiar React code.

View File

@@ -3,16 +3,15 @@ title: The Admin Panel
label: Overview
order: 10
desc: Manage your data and customize the Admin Panel by swapping in your own React components. Create, modify or remove views, fields, styles and much more.
keywords: admin, components, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: admin, components, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload dynamically generates a beautiful, fully functional React admin panel to manage your data. It's extremely powerful and can be customized / extended upon easily by swapping in your own React components. You can add additional views, modify how built-in views look / work, swap out Payload branding for your client's, build your own field types and much more.
Payload dynamically generates a beautiful, fully functional Admin Panel to manage your users and data. The Payload Admin Panel is highly performant, even with 100+ fields, and is written fully in TypeScript. It is built with [React](https://react.dev) using the [Next.js App Router](https://nextjs.org/docs/app) and fully supports [React Server Components](https://react.dev/reference/rsc/server-components) which enables the use of the [Local API](/docs/local-api/overview) on the front-end.
The Payload Admin panel can be bundled with our officially supported [Vite](/docs/admin/vite) and [webpack](/docs/admin/webpack) bundlers or you can integrate another bundler following our adapter pattern approach.
When bundled, it is code-split, highly performant (even with 100+ fields), and written fully in TypeScript.
You can endlessly customize and extend the Admin UI by swapping your own in [Custom Components](./components) for everything from field labels to entire views. You can also modify built-in views, build your own fields, [swap out Payload branding for your own](https://payloadcms.com/blog/white-label-admin-ui), and so much more.
<Banner type="success">
The Admin panel is meant to be simple enough to give you a starting point but not bring too much
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>
@@ -20,43 +19,36 @@ When bundled, it is code-split, highly performant (even with 100+ fields), and w
<LightDarkImage
srcLight="https://payloadcms.com/images/docs/admin.jpg"
srcDark="https://payloadcms.com/images/docs/admin-dark.jpg"
alt="Admin panel with collapsible sidebar"
caption="Redesigned admin panel with a collapsible sidebar that's open by default, providing greater extensibility and enhanced horizontal real estate."
alt="Admin Panel with collapsible sidebar"
caption="Redesigned Admin Panel with a collapsible sidebar that's open by default, providing greater extensibility and enhanced horizontal real estate."
/>
## Admin Options
All options for the Admin panel are defined in your base Payload config file.
All high-level options for the Admin Panel are defined in your Payload config under the `admin` key:
| Option | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `bundler` | The bundler that you would like to use to bundle the admin panel. Officially supported bundlers: [Webpack](/docs/admin/webpack) and [Vite](/docs/admin/vite). |
| `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) |
| `buildPath` | Specify an absolute path for where to store the built Admin panel bundle used in production. Defaults to `path.resolve(process.cwd(), 'build')`. |
| `meta` | Base meta data to use for the Admin panel. Included properties are `titleSuffix`, `icons`, and `openGraph`. Can be overridden on a per collection or per global basis. |
| `disable` | If set to `true`, the entire Admin panel will be disabled. |
| `indexHTML` | Optionally replace the entirety of the `index.html` file used by the Admin panel. Reference the [base index.html file](https://github.com/payloadcms/payload/blob/main/packages/payload/src/admin/index.html) to ensure your replacement has the appropriate HTML elements. |
| `css` | Absolute path to a stylesheet that you can use to override / customize the Admin panel styling. [More](/docs/admin/customizing-css). |
| `scss` | Absolute path to a Sass variables / mixins stylesheet meant to override Payload styles to make for an easy re-skinning of the Admin panel. [More](/docs/admin/customizing-css#overriding-scss-variables). |
| `dateFormat` | Global date format that will be used for all dates in the Admin panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. |
| `user` | The `slug` of a Collection that you want to be used to log in to the Admin Panel. [More](/docs/admin/overview#the-admin-user-collection) |
| `buildPath` | Specify an absolute path for where to store the built Admin bundle used in production. Defaults to `path.resolve(process.cwd(), 'build')`. |
| `meta` | Base meta data to use for the Admin Panel. Included properties are `titleSuffix`, `icons`, and `openGraph`. Can be overridden on a per collection or per global basis. |
| `disable` | If set to `true`, the entire Admin Panel will be disabled. |
| `dateFormat` | Global date format that will be used for all dates in the Admin Panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. |
| `avatar` | Set account profile picture. Options: `gravatar`, `default` or a custom React component. |
| `autoLogin` | Used to automate admin log-in for dev and demonstration convenience. [More](/docs/authentication/config). |
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
| `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) |
| `vite` | Customize the Vite config that's used to generate the Admin panel. [More](/docs/admin/vite) |
| `routes` | Replace built-in Admin Panel routes with your own custom routes. [More](/docs/admin/overview#custom-admin-panel-routes) |
| `components` | Component overrides that affect the entirety of the Admin Panel. [More](/docs/admin/components) |
| `routes` | Replace built-in Admin Panel routes with your own custom routes. [More](#custom-admin-panel-routes) |
### The Admin User Collection
<Banner type="warning">
<strong>Important:</strong>
<br />
The Payload Admin panel can only be used by one Collection that supports
[Authentication](/docs/authentication/overview).
The Admin Panel can only be used by a single auth-enabled Collection. To enable authentication for a Collection, simply set `auth: true` in the Collection's configuration. See [Authentication](/docs/authentication/overview) for more information.
</Banner>
To specify which Collection to use to log in to the Admin panel, pass the `admin` options a `user` key equal to the slug of the Collection that you'd like to use.
To specify which Collection to allow to login to the Admin Panel, pass the `admin.user` key equal to the slug of any auth-enabled Collection. See [Authentication](/docs/authentication/overview) for more information.
`payload.config.js`:
@@ -70,28 +62,45 @@ const config = buildConfig({
})
```
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.
<Banner type="info">
By default, if you have not specified a Collection, Payload will automatically provide a `User` Collection with access the Admin Panel. You can customize or override the fields and settings of the default `User` Collection by adding your own Collection with `slug: 'users'`. Doing this will force Payload to use your provided `User` Collection instead of its default version.
</Banner>
**Note: you can use whatever Collection you'd like to access the Admin panel as long as the Collection supports Authentication. It doesn't need to be called `users`!**
<Banner type="warning">
<strong>Note:</strong>
<br />
You can use whatever Collection you'd like to access the Admin Panel as long as the Collection supports [Authentication](/docs/authentication/overview). It doesn't need to be called `users`. For example, you could use a Collection called `admins` or `editors` instead.
</Banner>
For example, you may wish to have two Collections that both support `Authentication`:
For example, you may wish to have two Collections that both support Authentication:
- `admins` - meant to have a higher level of permissions to manage your data and access the Admin panel
- `customers` - meant for end users of your app that should not be allowed to log into the Admin panel
- `admins` - meant to have a higher level of permissions to manage your data and access the Admin Panel
- `customers` - meant for end users of your app that should not be allowed to log into the Admin Panel
This is totally possible. For the above scenario, by specifying `admin: { user: 'admins' }`, your Payload Admin panel will use `admins`. Any users logged in as `customers` will not be able to log in via the Admin panel.
### Light and dark modes
Users in the admin panel have access to choosing between light mode and dark mode for their editing experience. The setting is managed while logged into the admin UI within the user account page and will be stored with the browser. By default, the operating system preference is detected and used.
This is totally possible. For the above scenario, by specifying `admin: { user: 'admins' }`, your Admin Panel will use `admins`. Any users logged in as `customers` will not be able to log in via the Admin Panel.
### Restricting user access
If you would like to restrict which users from a single Collection can access the Admin panel, you can use the `admin` access control function. [Click here](/docs/access-control/overview#admin) to learn more.
It is also possible to allow _multiple admin user types_ into the Admin Panel with limited permissions. To do this, add a `roles` or similar field to your auth-enabled Collection and use the `access.admin` property to limit access. See [Access Control](/docs/access-control/overview) for full details. For a working example, check out the [Auth Example](https://github.com/payloadcms/payload/tree/main/examples/auth/payload).
### I18n
The Payload Admin Panel is translated in over 30 languages and counting. Languages are automatically detected based on the user's browser and all text displays in that language. If no language was detected, or if the user's language is not yet supported, English will be chosen. Users can easily specify their language by selecting one from their account page. See [I18n](../configuration/i18n) for more information.
<Banner>
<strong>Note:</strong>
<br />
If there is a language that Payload does not yet support, we accept code
[contributions](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md).
</Banner>
### Light and dark modes
Users in the Admin Panel have access to choosing between light mode and dark mode for their editing experience. The setting is managed while logged into the admin UI within the user account page and will be stored with the browser. By default, the operating system preference is detected and used.
### Custom admin panel routes
You can configure custom routes in the admin panel for the following routes:
You can configure custom routes in the Admin Panel for the following routes:
| Option | Default route |
| ----------------- | ----------------------- |

View File

@@ -3,7 +3,7 @@ title: Managing User Preferences
label: Preferences
order: 50
desc: Store the preferences of your users as they interact with the Admin panel.
keywords: admin, preferences, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: admin, preferences, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
As your users interact with your Admin panel, you might want to store their preferences in a persistent manner, so that when they revisit the Admin panel, they can pick right back up where they left off.

315
docs/admin/views.mdx Normal file
View File

@@ -0,0 +1,315 @@
---
title: Customizing Views
label: Customizing Views
order: 30
desc:
keywords:
---
### Root
You can easily swap entire views with your own by using the `admin.components.views` property. At the root level, Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| --------------- | ----------------------------------------------------------------------------- |
| **`Account`** | The Account view is used to show the currently logged in user's Account page. |
| **`Dashboard`** | The main landing page of the [Admin Panel](./overview). |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. For example:
```ts
// payload.config.ts
{
// ...
admin: {
components: {
views: {
Account: MyCustomAccountView,
Dashboard: MyCustomDashboardView,
},
},
},
}
```
For more granular control, pass a configuration object instead. Payload exposes the following properties for each view:
| Property | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`Component`** \* | Pass in the component that should be rendered when a user navigates to this route. |
| **`path`** \* | Any valid URL path or array of paths that [`path-to-regexp`](https://www.npmjs.com/package/path-to-regex) understands. |
| **`exact`** | Boolean. When true, will only match if the path matches the `usePathname()` exactly. |
| **`strict`** | When true, a path that has a trailing slash will only match a location.pathname with a trailing slash. This has no effect when there are additional URL segments in the location.pathname. |
| **`sensitive`** | When true, will match if the path is case sensitive. |
_\* An asterisk denotes that a property is required._
#### Adding new root views
To add a _new_ view to the [Admin Panel](./overview), simply add another key to the `views` object with at least a `path` and `Component` property. For example:
```ts
// payload.config.ts
{
// ...
admin: {
components: {
views: {
MyCustomView: {
Component: MyCustomView,
path: '/my-custom-view',
},
},
},
},
}
```
<Banner type="warning">
<strong>Note:</strong>
<br />
Routes are cascading. This means that unless explicitly given the `exact` property, they will
match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all
routes in your application. Alternatively, you could define your nested route _before_ your parent
route.
</Banner>
For help on how to build your own custom view components, see [Building Custom View Components](#building-custom-view-components). For more examples regarding how to customize components, [look at the following examples](https://github.com/payloadcms/payload/tree/main/test/admin/components)._
### Collections
To swap out entire views on collections, you can use the `admin.components.views` property on the collection's config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ---------- | ------------------------------------------------------------------------- |
| **`Edit`** | The Edit view is used to edit a single document for a given collection. |
| **`List`** | The List view is used to show a list of documents for a given collection. |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, tabs, etc, _as well as all nested routes_.
```ts
// Collection.ts
{
// ...
admin: {
components: {
views: {
Edit: MyCustomEditView,
List: MyCustomListView,
},
},
},
}
```
For help on how to build your own custom view components, see [Building Custom View Components](#building-custom-view-components).
**Customizing Nested Views within 'Edit' in Collections**
The `Edit` view in collections consists of several nested views, each serving a unique purpose. You can customize these nested views using the `admin.components.views.Edit` property in the collection's configuration. This approach allows you to replace specific nested views while keeping the overall structure of the `Edit` view intact, including the page breadcrumbs, title, tabs, etc.
Here's an example of how you can customize nested views within the `Edit` view in collections, including the use of the `actions` property:
```ts
// Collection.ts
{
// ...
admin: {
components: {
views: {
Edit: {
Default: {
Component: MyCustomDefaultTab,
actions: [CollectionEditButton], // Custom actions for the default edit view
},
API: {
Component: MyCustomAPIView,
actions: [CollectionAPIButton], // Custom actions for API view
},
LivePreview: {
Component: MyCustomLivePreviewView,
actions: [CollectionLivePreviewButton], // Custom actions for Live Preview
},
Version: {
Component: MyCustomVersionView,
actions: [CollectionVersionButton], // Custom actions for Version view
},
Versions: {
Component: MyCustomVersionsView,
actions: [CollectionVersionsButton], // Custom actions for Versions view
},
},
List: {
actions: [CollectionListButton],
},
},
},
},
}
```
**Adding New Tabs to 'Edit' View**
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
### Globals
To swap out views for globals, you can use the `admin.components.views` property on the global's config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ---------- | ------------------------------------------------------------------- |
| **`Edit`** | The Edit view is used to edit a single document for a given Global. |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, and tabs, _as well as all nested views_.
```ts
// Global.ts
{
// ...
admin: {
components: {
views: {
Edit: MyCustomEditView,
},
},
},
}
```
For help on how to build your own custom view components, see [Building Custom View Components](#building-custom-view-components).
**Customizing Nested Views within 'Edit' in Globals**
Similar to collections, Globals allow for detailed customization within the `Edit` view. This includes the ability to swap specific nested views while maintaining the overall structure of the `Edit` view. You can use the `admin.components.views.Edit` property in the Globals configuration to achieve this, and this will only replace the nested view, leaving the page breadcrumbs, title, and tabs intact.
Here's how you can customize nested views within the `Edit` view in Globals, including the use of the `actions` property:
```ts
// Global.ts
{
// ...
admin: {
components: {
views: {
Edit: {
Default: {
Component: MyCustomGlobalDefaultTab,
actions: [GlobalEditButton], // Custom actions for the default edit view
},
API: {
Component: MyCustomGlobalAPIView,
actions: [GlobalAPIButton], // Custom actions for API view
},
LivePreview: {
Component: MyCustomGlobalLivePreviewView,
actions: [GlobalLivePreviewButton], // Custom actions for Live Preview
},
Version: {
Component: MyCustomGlobalVersionView,
actions: [GlobalVersionButton], // Custom actions for Version view
},
Versions: {
Component: MyCustomGlobalVersionsView,
actions: [GlobalVersionsButton], // Custom actions for Versions view
},
},
},
},
},
}
```
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
### Custom Tabs
You can easily swap individual collection or global edit views. To do this, pass an _object_ to the `admin.components.views.Edit` property of the config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **`Default`** | The Default view is the primary view in which your document is edited. |
| **`Versions`** | The Versions view is used to view the version history of a single document. [More details](../versions) |
| **`Version`** | The Version view is used to view a single version of a single document for a given collection. [More details](../versions). |
| **`API`** | The API view is used to display the REST API JSON response for a given document. |
| **`LivePreview`** | The LivePreview view is used to display the Live Preview interface. [More details](../live-preview) |
Here is an example:
```ts
// Collection.ts or Global.ts
export const MyCollection: SanitizedCollectionConfig = {
slug: 'my-collection',
admin: {
components: {
views: {
Edit: {
// You can also define `components.views.Edit` as a component, this will override _all_ nested views
Default: MyCustomDefaultTab,
Versions: MyCustomVersionsTab,
Version: MyCustomVersionTab,
API: MyCustomAPITab,
LivePreview: MyCustomLivePreviewTab,
},
},
},
},
}
```
To add a _new_ tab to the `Edit` view, simply add another key to `components.views.Edit[key]` with at least a `path` and `Component` property. For example:
```ts
// `Collection.ts` or `Global.ts`
export const MyCollection: SanitizedCollectionConfig = {
slug: 'my-collection',
admin: {
components: {
views: {
Edit: {
MyCustomTab: {
Component: MyCustomTab,
path: '/my-custom-tab',
// You an swap the entire tab component out for your own
Tab: MyCustomTab,
},
AnotherCustomView: {
Component: AnotherCustomView,
path: '/another-custom-view',
// Or you can use the default tab component and just pass in your own label and href
Tab: {
label: 'Another Custom View',
href: '/another-custom-view',
},
},
},
},
},
},
}
```
### Building Custom View Components
Your custom view components will be provided with the following props:
| Prop | Description |
| ----------------------- | ---------------------------------------------------------------------------- |
| **`user`** | The currently logged in user. Will be `null` if no user is logged in. |
| **`canAccessAdmin`** \* | If the currently logged in user is allowed to access the [Admin Panel](./overview) or not. |
<Banner type="warning">
<strong>Note:</strong>
<br />
It's up to you to secure your custom views. If your view requires a user to be logged in or to
have certain access rights, you should handle that within your view component yourself.
</Banner>
### Examples
You can find examples of custom views in the [Payload source code `/test/admin/components/views` folder](https://github.com/payloadcms/payload/tree/main/test/admin/components/views). There, you'll find two custom views:
1. A custom view that uses the `DefaultTemplate`, which is the built-in Payload template that displays the sidebar and "eyebrow nav"
1. A custom view that uses the `MinimalTemplate` - which is just a centered template used for things like logging in or out
To see how to pass in your custom views to create custom views of your own, take a look at the `admin.components.views` property of the [Payload test admin config](https://github.com/payloadcms/payload/blob/main/test/admin/config.ts).

View File

@@ -1,163 +0,0 @@
---
title: Vite
label: Vite
order: 90
desc: NEEDS TO BE WRITTEN
---
<Banner type="info">
The Vite bundler is currently in beta. If you would like to help us test this package, we'd love
to hear from you if you find any [bugs or issues](https://github.com/payloadcms/payload/issues/)!
</Banner>
Payload has a Vite bundler that you can install and bundle the Admin Panel with. This is an alternative to the [Webpack](/docs/admin/webpack) bundler and might give some performance boosts to your development workflow.
To use Vite as your bundler, first you need to install the package:
```bash
yarn add @payloadcms/bundler-vite
```
Then you will need to add the [bundler](/docs/admin/bundlers) to your Payload config:
```ts
import { buildConfig } from '@payloadcms/config'
import { viteBundler } from '@payloadcms/bundler-vite'
export default buildConfig({
collections: [],
admin: {
bundler: viteBundler(),
},
})
```
Vite works fundamentally differently than Webpack. In development mode, it will first pre-bundle any of your dependencies that are CommonJS-only, and then it'll leverage ESM directly in your browser for a better HMR experience.
It then uses Rollup to create production builds of your admin UI. With Vite, you should see a decent performance boost—especially after your first cold start. However, that first cold start might take a few more seconds.
<Banner type="warning">
In most cases, Vite should work out of the box. But existing Payload plugins may need to make
compatibility changes to support Vite.
</Banner>
This is because Vite aliases work fundamentally differently than Webpack aliases, and Payload relies on aliasing server-only code out of the Payload config to ensure that the bundled admin JS works within your browser.
Here are the main differences between how Vite aliases work and how Webpack aliases work.
**Vite aliases do not work with absolute paths.**
In Vite, alias keys must <strong>exactly match</strong> a import paths. If you have 2 files that import the same server-only module, but have different import paths, you would need to add 2 aliases to support both import paths.
```ts
// File A
import serverOnlyModule from '../server-only-module'
// File B
import serverOnlyModule from '../../server-only-module'
// payload.config.ts
// You would need to add 2 aliases to support both import paths
export const buildConfig({
collections: [],
admin: {
bundler: viteBundler(),
vite: (incomingViteConfig) => {
const existingAliases = incomingViteConfig?.resolve?.alias || {};
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
// Pass the existing Vite aliases
if (Array.isArray(existingAliases)) {
aliasArray = existingAliases;
} else {
aliasArray = Object.values(existingAliases);
}
// Add your own aliases using the find and replacement keys
aliasArray.push({
find: '../server-only-module',
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
find: '../../server-only-module',
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
});
return {
...incomingViteConfig,
resolve: {
...(incomingViteConfig?.resolve || {}),
alias: aliasArray,
}
};
},
}
})
```
**Vite aliases do not get applied to pre-bundled dependencies.**
This especially affects plugins, as plugins will be pre-bundled by Vite using `esbuild`. To get around this and support Vite, plugin authors need to configure an alias to their plugin at the top level, so that the alias will work accordingly.
Here's an example. Say your plugin is called `payload-plugin-cool`. It's imported as follows:
```ts
import { myCoolPlugin } from 'payload-plugin-cool'
```
That plugin should create an alias to support Vite as follows:
```ts
{
// aliases go here
find: 'payload-plugin-cool',
replacement: path.resolve(__dirname, './my-admin-plugin.js')
}
```
This will effectively alias the entire plugin and work with Vite. If the plugin requires admin-specific code, then the `./my-admin-plugin.js` alias target file should reflect any changes necessary to the admin UI that the main server-side plugin performs.
## Extending the Vite config
The Payload config supports a new property for plugins to be able to extend the Vite config specifically. That property exists on the main Payload config under `admin.vite`. You can check out the [Vite docs](https://vitejs.dev/config/shared-options.html) for more information on what you can do with the Vite config.
It's a function that takes a Vite config, and returns an updated Vite config. Here's an example:
```ts
export const buildConfig({
collections: [],
admin: {
bundler: viteBundler(),
vite: (incomingViteConfig) => {
const existingAliases = incomingViteConfig?.resolve?.alias || {};
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
// Pass the existing Vite aliases
if (Array.isArray(existingAliases)) {
aliasArray = existingAliases;
} else {
aliasArray = Object.values(existingAliases);
}
// Add your own aliases using the find and replacement keys
aliasArray.push({
find: '../server-only-module',
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
});
return {
...incomingViteConfig,
resolve: {
...(incomingViteConfig?.resolve || {}),
alias: aliasArray,
}
};
},
}
})
```
Learn more about [aliasing server-only modules](https://payloadcms.com/docs/admin/excluding-server-code#aliasing-server-only-modules).
Even though there is a new property for Vite configs specifically, we have implemented some "compatibility" between Webpack and Vite out-of-the-box.
If your config specifies Webpack aliases, we attempt to leverage them automatically within the Vite config. They are merged into the Vite alias configuration seamlessly and may work out-of-the-box.

View File

@@ -1,67 +0,0 @@
---
title: Webpack
label: Webpack
order: 80
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
---
Payload has a Webpack (v5) bundler that you can build the Admin panel with. For now, we recommended using it because it is stable. If you are feeling a bit more adventurous you can give the [Vite](/docs/admin/vite) bundler a shot.
Out of the box, the Webpack bundler supports common functionalities such as SCSS and Typescript, but there are many cases where you may need to add support for additional functionalities.
## Installation
```bash
yarn add @payloadcms/bundler-webpack
```
### Import the bundler
```ts
// payload.config.ts
import { buildConfig } from 'payload/config'
import { webpackBundler } from '@payloadcms/bundler-webpack'
export default buildConfig({
// highlight-start
admin: {
bundler: webpackBundler(),
},
// highlight-end
})
```
## Extending Webpack
If you need to extend the Webpack config, you can do so by passing a function to the `admin.webpack` property on your Payload config.
The function will receive the Webpack config as an argument and should return the modified config.
```ts
// payload.config.ts
import { buildConfig } from 'payload/config'
import { webpackBundler } from '@payloadcms/bundler-webpack'
export default buildConfig({
admin: {
bundler: webpackBundler()
// highlight-start
webpack: (config) => {
// full control of the Webpack config
return config
},
// highlight-end
},
})
```
<Banner type="success">
<strong>Tip:</strong>
<br />
If changes to your Webpack aliases are not surfacing, they might be
[cached](https://webpack.js.org/configuration/cache/) in `node_modules/.cache/webpack`. Try
deleting that folder and restarting your server.
</Banner>

View File

@@ -3,7 +3,7 @@ title: Authentication Config
label: Config
order: 20
desc: Enable and customize options in the Authentication config for features including Forgot Password, Login Attempts, API key usage and more.
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload's Authentication is extremely powerful and gives you everything you need when you go to build a new app or site in a secure and responsible manner.
@@ -18,7 +18,7 @@ To enable Authentication on a collection, define an `auth` property and set it t
| **`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. |
| **`lockTime`** | Set the time (in milliseconds) that a user should be locked out if they fail authentication more times than `maxLoginAttempts` allows for. |
| **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the express `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. |
| **`depth`** | How many levels deep a `user` document should be populated when creating the JWT and binding the `user` to the `req`. Defaults to `0` and should only be modified if absolutely necessary, as this will affect performance. |
| **`cookies`** | Set cookie options, including `secure`, `sameSite`, and `domain`. For advanced users. |
| **`forgotPassword`** | Customize the way that the `forgotPassword` operation functions. [More](/docs/authentication/config#forgot-password) |
| **`verify`** | Set to `true` or pass an object with verification options to require users to verify by email before they are allowed to log into your app. [More](/docs/authentication/config#email-verification) |

View File

@@ -3,7 +3,7 @@ title: Authentication Operations
label: Operations
order: 30
desc: Enabling Authentication automatically makes key operations available such as Login, Logout, Verify, Unlock, Reset Password and more.
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Enabling Authentication on a Collection automatically exposes additional auth-based operations in the Local, REST, and GraphQL APIs.
@@ -107,7 +107,7 @@ query {
## Login
Accepts an `email` and `password`. On success, it will return the logged in user as well as a token that can be used to authenticate. In the GraphQL and REST APIs, this operation also automatically sets an HTTP-only cookie including the user's token. If you pass an Express `res` to the Local API operation, Payload will set a cookie there as well.
Accepts an `email` and `password`. On success, it will return the logged in user as well as a token that can be used to authenticate. In the GraphQL and REST APIs, this operation also automatically sets an HTTP-only cookie including the user's token. If you pass a `res` to the Local API operation, Payload will set a cookie there as well.
**Example REST API login**:

View File

@@ -3,7 +3,7 @@ title: Authentication Overview
label: Overview
order: 10
desc: Payload provides highly secure user Authentication out of the box, and you can fully customize, override, or remove the default Authentication support.
keywords: authentication, config, configuration, overview, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: authentication, config, configuration, overview, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<YouTube
@@ -77,14 +77,14 @@ Once enabled, each document that is created within the Collection can be thought
## Token-based auth
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: JWT` or `Authorization: Bearer` header, Payload will automatically identify the user and add its user JWT data to the Express `req`, which is available throughout Payload including within access control, hooks, and more.
Successfully logging in returns a `JWT` (JSON web token) which is how a user will identify themselves to Payload. By providing this JWT via either an HTTP-only cookie or an `Authorization: JWT` or `Authorization: Bearer` header, Payload will automatically identify the user and add its user JWT data to the `req`, which is available throughout Payload including within access control, hooks, and more.
You can specify what data gets encoded to the JWT token by setting `saveToJWT` to true in your auth collection fields. If you wish to use a different key other than the field `name`, you can provide it to `saveToJWT` as a string. It is also possible to use `saveToJWT` on fields that are nested in inside groups and tabs. If a group has a `saveToJWT` set it will include the object with all sub-fields in the token. You can set `saveToJWT: false` for any fields you wish to omit. If a field inside a group has `saveToJWT` set, but the group does not, the field will be included at the top level of the token.
<Banner type="success">
<strong>Tip:</strong>
<br />
You can access the logged-in user from access control functions and hooks via the Express{' '}
You can access the logged-in user from access control functions and hooks via the{' '}
<strong>req</strong>. The logged-in user is automatically added as the <strong>user</strong>{' '}
property.
</Banner>

View File

@@ -1,56 +0,0 @@
---
title: Using the Payload Auth Middleware
label: Using the Middleware
order: 40
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, 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.
</Banner>
<Banner type="warning">
Payload must be initialized before the `payload.authenticate` middleware can be used. This is done
by calling `payload.init()` prior to adding the middleware.
</Banner>
Example in `server.js`:
```ts
import express from 'express'
import payload from 'payload'
const app = express()
const start = async () => {
await payload.init({
secret: 'PAYLOAD_SECRET_KEY',
express: app,
})
const router = express.Router()
// Note: Payload must be initialized before the `payload.authenticate` middleware can be used
router.use(payload.authenticate) // highlight-line
router.get('/', (req, res) => {
if (req.user) {
return res.send(`Authenticated successfully as ${req.user.email}.`)
}
return res.send('Not authenticated')
})
app.use('/some-route-here', router)
app.listen(3000)
}
start()
```

View File

@@ -46,7 +46,7 @@ Any of the features in Payload Cloud that require environment variables will aut
<Banner type="warning">
Note: For security reasons, any variables you wish to provide to the Admin panel must be prefixed
with `PAYLOAD_PUBLIC_`.  Learn more
[here](https://payloadcms.com/docs/admin/webpack#admin-environment-vars).
[here](https://payloadcms.com/docs/admin/environment-vars).
</Banner>
## Payment

View File

@@ -61,7 +61,7 @@ From the Environment Variables page of the Settings tab, you can add, update and
<Banner>
Note: For security reasons, any variables you wish to provide to the Admin panel must be prefixed
with `PAYLOAD_PUBLIC_`.  Learn more
[here](https://payloadcms.com/docs/admin/webpack#admin-environment-vars).
[here](https://payloadcms.com/docs/admin/environment-vars).
</Banner>
## Custom Domains

View File

@@ -3,7 +3,7 @@ title: Collection Configs
label: Collections
order: 20
desc: Structure your Collections for your needs by defining fields, adding slugs and labels, establishing access control, tying in hooks, setting timestamps and more.
keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload Collections are defined through configs of their own, and you can define as many as your application needs. Each

View File

@@ -1,81 +0,0 @@
---
title: Express
label: Express
order: 60
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
---
Payload utilizes a few Express-specific middleware packages within its own routers. You can customize how they work by passing in configuration options to the main Payload config's `express` property.
## Custom Middleware
Payload allows you to pass in custom Express middleware to be used on all of the routes it opens. This is useful for adding logging or any other custom functionality to your endpoints.
There are 2 exposed properties. Each property is an array of middleware functions.
- `preMiddleware` - runs before any of the Payload middleware
- `postMiddleware` - runs after all of the Payload middleware
```ts
{
express: {
preMiddleware: [
(req, res, next) => {
// do something
next()
}
],
postMiddleware: [
(req, res, next) => {
// do something
next()
}
]
}
}
// Example logging middleware function
const requestLoggerMiddleware = (req, res, next) => {
req.payload.logger.info(`request: ${req.method} ${req.url}`)
next()
}
```
## JSON
`express.json()` is used to parse JSON body content into JavaScript objects accessible on the Express `req`. Payload allows you to customize all of the `json` method's options. Common examples of customization use-cases are increasing the max allowed JSON body size which defaults to `2MB`.
**Example payload.config.js for how to increase the max JSON size allowed to be sent to Payload endpoints:**
```js
{
express: {
json: {
limit: '4mb',
}
}
}
```
You can find a list of all available options that are able to be passed to `express.json()` [here](https://expressjs.com/en/api.html).
## Compression
Payload uses the `compression` package to optimize transfer size for all of the routes it opens, and you can pass customization options through the Payload config.
To customize compression options, pass an object to the Payload config's `express` property.
**Example payload.config.js:**
```js
{
express: {
compression: {
// settings go here
}
}
}
```
Typically, the default options for this package are suitable. However, for a list of all available customization options, [click here](http://expressjs.com/en/resources/middleware/compression.html).

View File

@@ -3,7 +3,7 @@ title: Global Configs
label: Globals
order: 30
desc: Set up your Global config for your needs by defining fields, adding slugs and labels, establishing access control, tying in hooks and more.
keywords: globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
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.

View File

@@ -3,12 +3,43 @@ title: I18n
label: I18n
order: 40
desc: Manage and customize internationalization support in your CMS editor experience
keywords: internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Not only does Payload support managing localized content, it also has internationalization support so that admin users can work in their preferred language. It comes included by default and can be extended in your config.
Not only does Payload support managing localized content, it also has internationalization support so that users in the [Admin Panel](../admin/overview) can work in their preferred language. Payload's i18n comes by default without any additional setup, and you can extend the default settings to customize the language settings to your needs.
While Payload's built-in features come translated, you may want to also translate parts of your project's configuration too. This is possible in places like collections and globals labels and groups, field labels, descriptions and input placeholder text. The admin UI will display all the correct translations you provide based on the user's language.
### Configuration Options
In your Payload config, you can add translations and customize the settings in `i18n`. Payload will use your custom options and merge it with the default, allowing you to override the settings Payload provides.
**Example Payload config extending i18n:**
```ts
import { buildConfig } from 'payload/config'
export default buildConfig({
//...
i18n: {
fallbackLng: 'en', // default
debug: false, // default
resources: {
en: {
custom: {
// namespace can be anything you want
key1: 'Translation with {{variable}}', // translation
},
// override existing translation keys
general: {
dashboard: 'Home',
},
},
},
},
//...
})
```
While Payload's built-in features come translated, you may want to also translate parts of your project's configuration too. This is possible in places like Collections and Globals labels and groups, field labels, descriptions and input placeholder text. The admin UI will display all the correct translations you provide based on the user's language.
Here is an example of a simple collection supporting both English and Spanish editors:
@@ -58,7 +89,7 @@ export const Articles: CollectionConfig = {
## Admin UI
The Payload admin panel reads the language settings of a user's browser and display all text in that language, or will fall back to English if the user's language is not yet supported.
The [Admin Panel](../admin/overview) reads the language settings of a user's browser and display all text in that language, or will fall back to English if the user's language is not yet supported.
After a user logs in, they can change their language selection in the `/account` view.
<Banner>
@@ -68,9 +99,9 @@ After a user logs in, they can change their language selection in the `/account`
[contributions](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md).
</Banner>
## Node Express
## Node
Payload's backend uses express middleware to set the language on incoming requests before they are handled. This allows backend validation to return error messages in the user's own language or system generated emails to be sent using the correct translation. You can make HTTP requests with the `accept-language` header and Payload will use that language.
Payload's backend sets the language on incoming requests before they are handled. This allows backend validation to return error messages in the user's own language or system generated emails to be sent using the correct translation. You can make HTTP requests with the `accept-language` header and Payload will use that language.
Anywhere in your Payload app that you have access to the `req` object, you can access payload's extensive internationalization features assigned to `req.i18n`. To access text translations you can use `req.t('namespace:key')`.

View File

@@ -3,7 +3,7 @@ title: Localization
label: Localization
order: 50
desc: Add and maintain as many locales as you need by adding Localization to your Payload config, set options for default locale, fallbacks, fields and more.
keywords: localization, internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: localization, internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload features deep field-based localization support. Maintaining as many locales as you need is easy. All

View File

@@ -3,7 +3,7 @@ title: The Payload Config
label: Overview
order: 10
desc: The Payload config is central to everything that Payload does, from adding custom React components, to modifying collections, controlling localization and much more.
keywords: overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
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.
@@ -13,7 +13,7 @@ Payload is a _config-based_, code-first CMS and application framework. The Paylo
<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
The serializable portions of this config are included in the Payload Admin bundle, so make sure you do not embed any sensitive
information.
</Banner>
@@ -21,7 +21,7 @@ Payload is a _config-based_, code-first CMS and application framework. The Paylo
| Option | Description |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `admin` \* | Base Payload admin configuration. Specify bundler\*, custom components, control metadata, set the Admin user collection, and [more](/docs/admin/overview#admin-options). Required. |
| `admin` \* | Base Payload admin configuration. Specify, custom components, control metadata, set the Admin user collection, and [more](/docs/admin/overview#admin-options). Required. |
| `editor` \* | Rich Text Editor which will be used by richText fields. Required. |
| `db` \* | Database Adapter which will be used by Payload. Read more [here](/docs/database/overview). Required. |
| `serverURL` | A string used to define the absolute URL of your app including the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port |
@@ -38,7 +38,6 @@ Payload is a _config-based_, code-first CMS and application framework. The Paylo
| `upload` | Base Payload upload configuration. [More](/docs/upload/overview#payload-wide-upload-options). |
| `routes` | Control the routing structure that Payload binds itself to. Specify `admin`, `api`, `graphQL`, and `graphQLPlayground`. |
| `email` | Base email settings to allow Payload to generate email such as Forgot Password requests and other requirements. [More](/docs/email/overview#configuration) |
| `express` | Express-specific middleware options such as compression and JSON parsing. [More](/docs/configuration/express) |
| `debug` | Enable to expose more detailed error information. |
| `telemetry` | Disable Payload telemetry by passing `false`. [More](/docs/configuration/overview#telemetry) |
| `rateLimit` | Control IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks and [more](/docs/production/preventing-abuse#rate-limiting-requests). |
@@ -56,16 +55,10 @@ import { buildConfig } from 'payload/config'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { postgresAdapter } from '@payloadcms/db-postgres' // beta
import { viteBundler } from '@payloadcms/bundler-vite'
import { webpackBundler } from '@payloadcms/bundler-webpack'
import { lexicalEditor } from '@payloadcms/richtext-lexical' // beta
import { slateEditor } from '@payloadcms/richtext-slate'
export default buildConfig({
admin: {
bundler: webpackBundler(), // or viteBundler()
},
db: mongooseAdapter({}) // or postgresAdapter({}),
editor: lexicalEditor({}) // or slateEditor({})
collections: [
@@ -139,7 +132,7 @@ project-name
<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. [Click here](/docs/admin/webpack#admin-environment-vars) for more info.
can access it. [Click here](/docs/admin/environment-vars) for more info.
</Banner>
## Customizing & Automating Config Location Detection

View File

@@ -2,7 +2,7 @@
title: Migrations
label: Migrations
order: 20
keywords: database, migrations, ddl, sql, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, express
keywords: database, migrations, ddl, sql, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, nextjs
desc: Payload features first-party database migrations all done in TypeScript.
---

View File

@@ -3,7 +3,7 @@ title: MongoDB
label: MongoDB
order: 40
desc: Payload has supported MongoDB natively since we started. The flexible nature of MongoDB lends itself well to Payload's powerful fields.
keywords: MongoDB, documentation, typescript, Content Management System, cms, headless, javascript, node, react, express
keywords: MongoDB, documentation, typescript, Content Management System, cms, headless, javascript, node, react, nextjs
---
To use Payload with MongoDB, install the package `@payloadcms/db-mongodb`. It will come with everything you need to

View File

@@ -2,7 +2,7 @@
title: Database
label: Overview
order: 10
keywords: database, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, express
keywords: database, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, nextjs
desc: With Payload, you bring your own database and own your data. You have full control.
---

View File

@@ -3,7 +3,7 @@ title: Postgres
label: Postgres
order: 50
desc: Payload supports Postgres through an officially supported Drizzle database adapter.
keywords: Postgres, documentation, typescript, Content Management System, cms, headless, javascript, node, react, express
keywords: Postgres, documentation, typescript, Content Management System, cms, headless, javascript, node, react, nextjs
---
To use Payload with Postgres, install the package `@payloadcms/db-postgres`. It leverages Drizzle ORM and `node-postgres` to interact with a Postgres database that you provide.

View File

@@ -2,7 +2,7 @@
title: Transactions
label: Transactions
order: 30
keywords: database, transactions, sql, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, express
keywords: database, transactions, sql, mongodb, postgres, documentation, Content Management System, cms, headless, typescript, node, react, nextjs
desc: Database transactions are fully supported within Payload.
---

View File

@@ -3,7 +3,7 @@ title: Email Functionality
label: Overview
order: 10
desc: Payload uses an adapter pattern to enable email functionality. Set up email functions such as password resets, order confirmations and more.
keywords: email, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: email, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
## Introduction

View File

@@ -0,0 +1,40 @@
---
title: Examples
label: Overview
order: 10
desc:
keywords: example, examples, starter, boilerplate, template, templates
---
Payload provides a vast array of examples to help you get started with your project no matter what you are working on. These examples are designed to be easy to get up and running, and to be easy to understand. They showcase nothing more than the specific features being demonstrated so you can easily decipher what is going on.
Examples are changing every day, so be sure to check back often to see what new examples have been added. If you have a specific example you would like to see, please feel free to start a new [Discussion](https://github.com/payloadcms/payload/discussions) or open a new [PR](https://github.com/payloadcms/payload/pulls) to add it yourself.
- [Auth](https://github.com/payloadcms/payload/tree/main/examples/auth)
- [Custom Server](https://github.com/payloadcms/payload/tree/main/examples/custom-server)
- [Draft Preview](https://github.com/payloadcms/payload/tree/main/examples/draft-preview)
- [Email](https://github.com/payloadcms/payload/tree/main/examples/email)
- [Form Builder](https://github.com/payloadcms/payload/tree/main/examples/form-builder)
- [Hierarchy](https://github.com/payloadcms/payload/tree/main/examples/hierarchy)
- [Live Preview](https://github.com/payloadcms/payload/tree/main/examples/live-preview)
- [Multi-tenant](https://github.com/payloadcms/payload/tree/main/examples/multi-tenant)
- [Nested Docs](https://github.com/payloadcms/payload/tree/main/examples/nested-docs)
- [Redirects](https://github.com/payloadcms/payload/tree/main/examples/redirects)
- [Tailwind / Shadcn-ui](https://github.com/payloadcms/payload/tree/main/examples/tailwind-shadcn-ui)
- [Tests](https://github.com/payloadcms/payload/tree/main/examples/testing)
- [Virtual Fields](https://github.com/payloadcms/payload/tree/main/examples/virtual-fields)
- [White-label Admin UI](https://github.com/payloadcms/payload/tree/main/examples/whitelabel)
When necessary, some examples include a front-end. Examples that require a front-end share this folder structure:
```plaintext
example/
├── payload/
├── next-app/
├── next-pages/
├── react-router/
├── vue/
├── svelte/
```
...where `payload` is your Payload project, and the other directories are dedicated to their respective front-end framework. We are adding new examples every day, so if your framework of choice is not yet supported in any particular example, please feel free to start a new [Discussion](https://github.com/payloadcms/payload/discussions) or open a new [PR](https://github.com/payloadcms/payload/pulls) to add it yourself.

View File

@@ -3,7 +3,7 @@ title: Array Field
label: Array
order: 20
desc: Array fields are intended for sets of repeating fields, that you define. Learn how to use array fields, see examples and options.
keywords: array, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: array, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Blocks Field
label: Blocks
order: 30
desc: The Blocks field type is a great layout build and can be used to construct any flexible content model. Learn how to use Block fields, see examples and options.
keywords: blocks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: blocks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Checkbox Field
label: Checkbox
order: 40
desc: Checkbox field types allow the developer to save a boolean value in the database. Learn how to use Checkbox fields, see examples and options.
keywords: checkbox, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: checkbox, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>The Checkbox field type saves a boolean in the database.</Banner>

View File

@@ -4,7 +4,7 @@ label: Code
order: 50
desc: The Code field type will store any string in the Database. Learn how to use Code fields, see examples and options.
keywords: code, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: code, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Collapsible Field
label: Collapsible
order: 60
desc: With the Collapsible field, you can place fields within a collapsible layout component that can be collapsed / expanded.
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Date Field
label: Date
order: 70
desc: The Date field type stores a Date in the database. Learn how to use and customize the Date field, see examples and options.
keywords: date, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: date, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Email Field
label: Email
order: 80
desc: The Email field enforces that the value provided is a valid email address. Learn how to use Email fields, see examples and options.
keywords: email, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: email, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>The Email field enforces that the value provided is a valid email address.</Banner>

View File

@@ -3,7 +3,7 @@ title: Group Field
label: Group
order: 90
desc: The Group field allows other fields to be nested under a common property. Learn how to use Group fields, see examples and options.
keywords: group, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: group, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -4,7 +4,7 @@ label: JSON
order: 50
desc: The JSON field type will store any string in the Database. Learn how to use JSON fields, see examples and options.
keywords: json, jsonSchema, schema, validation, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: json, jsonSchema, schema, validation, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Number Field
label: Number
order: 100
desc: Number fields store and validate numeric data. Learn how to use and format Number fields, see examples and Number field options.
keywords: number, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: number, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Fields Overview
label: Overview
order: 10
desc: Fields are the building blocks of Payload, find out how to add or remove a field, change field type, add hooks, define access control and validation.
keywords: overview, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: overview, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner type="info">

View File

@@ -4,7 +4,7 @@ label: Point
order: 110
desc: The Point field type stores coordinates in the database. Learn how to use Point field for geolocation and geometry.
keywords: point, geolocation, geospatial, geojson, 2dsphere, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: point, geolocation, geospatial, geojson, 2dsphere, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Radio Group Field
label: Radio Group
order: 120
desc: The Radio field type allows for the selection of one value from a predefined set of possible values. Learn how to use Radio fields, see examples and options.
keywords: radio, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: radio, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Relationship Field
label: Relationship
order: 130
desc: The Relationship field provides the ability to relate documents together. Learn how to use Relationship fields, see examples and options.
keywords: relationship, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: relationship, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Rich Text Field
label: Rich Text
order: 140
desc: The Rich Text field allows dynamic content to be written through the Admin Panel. Learn how to use Rich Text fields, see examples and options.
keywords: rich text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: rich text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Row Field
label: Row
order: 150
desc: With the Row field you can arrange fields next to each other in the Admin Panel to help you customize your Dashboard.
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: row, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Select Field
label: Select
order: 160
desc: The Select field provides a dropdown-style interface for choosing options from a predefined list. Learn how to use Select fields, see examples and options.
keywords: select, multi-select, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: select, multi-select, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Tabs Field
label: Tabs
order: 170
desc: The Tabs field is a great way to organize complex editing experiences into specific tab-based areas.
keywords: tabs, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: tabs, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Text Field
label: Text
order: 180
desc: Text field types simply save a string to the database and provide the Admin panel with a text input. Learn how to use Text fields, see examples and options.
keywords: text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: text, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Textarea Field
label: Textarea
order: 190
desc: Textarea field types save a string to the database, similar to the Text field type but equipped for longer text. Learn how to use Textarea fields, see examples and options.
keywords: textarea, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: textarea, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: UI Field
label: UI
order: 200
desc: UI fields are purely presentational and allow developers to customize the admin panel to a very fine degree, including adding actions and other functions.
keywords: custom field, react component, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: custom field, react component, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Upload Field
label: Upload
order: 210
desc: Upload fields will allow a file to be uploaded, only from a collection supporting Uploads. Learn how to use Upload fields, see examples and options.
keywords: upload, images media, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: upload, images media, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>

View File

@@ -3,7 +3,7 @@ title: Payload Concepts
label: Concepts
order: 20
desc: Payload is based around a small and intuitive set of concepts. Key concepts include collections, globals, fields and more.
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload is based around a small and intuitive set of concepts. Before starting to work with Payload, it's a good idea to familiarize yourself with the following:

View File

@@ -3,7 +3,7 @@ title: Installation
label: Installation
order: 30
desc: To quickly get started with Payload, simply run npx create-payload-app or install from scratch.
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, nextjs
---
## Software Requirements
@@ -30,7 +30,7 @@ Then just follow the prompts! You'll get set up with a new folder and a function
## Adding to an existing app
Adding Payload to either a new or existing TypeScript + Express app is super straightforward. To add to an existing app, just run `npm install --save --legacy-peer-deps payload`.
Adding Payload to either a new or existing TypeScript + Next.js app is super straightforward. To add to an existing app, just run `npm install --save --legacy-peer-deps payload`.
From there, the first step is writing a baseline config. Create a new `payload.config.ts` in your project's `/src` directory (or whatever your root TS dir is). The simplest config contains the following:

View File

@@ -3,7 +3,7 @@ title: What is Payload?
label: What is Payload?
order: 10
desc: Payload is a next-gen headless Content Management System (CMS) and application framework.
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, express
keywords: documentation, getting started, guide, Content Management System, cms, headless, javascript, node, react, nextjs
---
<YouTube

View File

@@ -3,7 +3,7 @@ title: Adding your own Queries and Mutations
label: Custom Queries and Mutations
order: 20
desc: Payload allows you to add your own GraphQL queries and mutations, simply set up GraphQL in your main Payload config by following these instructions.
keywords: graphql, resolvers, mutations, custom, queries, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: graphql, resolvers, mutations, custom, queries, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
You can add your own GraphQL queries and mutations to Payload, making use of all the types that Payload has defined for you.

View File

@@ -3,7 +3,7 @@ title: GraphQL Schema
label: GraphQL Schema
order: 30
desc: Output your own GraphQL schema based on your collections and globals to a file.
keywords: headless cms, typescript, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: headless cms, typescript, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
When working with GraphQL it is useful to have the schema for development of other projects that need to call on your GraphQL endpoint. In Payload the schema is controlled by your collections and globals and is made available to the developer or third parties, it is not necessary for developers using Payload to write schema types manually.

View File

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

View File

@@ -3,7 +3,7 @@ title: Collection Hooks
label: Collections
order: 20
desc: You can add hooks to any Collection, several hook types are available including beforeChange, afterRead, afterDelete and more.
keywords: hooks, collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: hooks, collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Collections feature the ability to define the following hooks:
@@ -75,7 +75,7 @@ import { CollectionBeforeOperationHook } from 'payload/types'
const beforeOperationHook: CollectionBeforeOperationHook = async ({
args, // original arguments passed into the operation
operation, // name of the operation
req, // full express request
req, // full Request object
}) => {
return args // return modified operation arguments as necessary
}
@@ -96,7 +96,7 @@ import { CollectionBeforeValidateHook } from 'payload/types'
const beforeValidateHook: CollectionBeforeValidateHook = async ({
data, // incoming data to update or create with
req, // full express request
req, // full Request object
operation, // name of the operation ie. 'create', 'update'
originalDoc, // original document
}) => {
@@ -113,7 +113,7 @@ import { CollectionBeforeChangeHook } from 'payload/types'
const beforeChangeHook: CollectionBeforeChangeHook = async ({
data, // incoming data to update or create with
req, // full express request
req, // full Request object
operation, // name of the operation ie. 'create', 'update'
originalDoc, // original document
}) => {
@@ -130,7 +130,7 @@ import { CollectionAfterChangeHook } from 'payload/types'
const afterChangeHook: CollectionAfterChangeHook = async ({
doc, // full document data
req, // full express request
req, // full Request object
previousDoc, // document data before updating the collection
operation, // name of the operation ie. 'create', 'update'
}) => {
@@ -147,7 +147,7 @@ import { CollectionBeforeReadHook } from 'payload/types'
const beforeReadHook: CollectionBeforeReadHook = async ({
doc, // full document data
req, // full express request
req, // full Request object
query, // JSON formatted query
}) => {
return doc
@@ -163,7 +163,7 @@ import { CollectionAfterReadHook } from 'payload/types'
const afterReadHook: CollectionAfterReadHook = async ({
doc, // full document data
req, // full express request
req, // full Request object
query, // JSON formatted query
findMany, // boolean to denote if this hook is running against finding one, or finding many
}) => {
@@ -179,7 +179,7 @@ Runs before the `delete` operation. Returned values are discarded.
import { CollectionBeforeDeleteHook } from 'payload/types';
const beforeDeleteHook: CollectionBeforeDeleteHook = async ({
req, // full express request
req, // full Request object
id, // id of document to delete
}) => {...}
```
@@ -192,7 +192,7 @@ Runs immediately after the `delete` operation removes records from the database.
import { CollectionAfterDeleteHook } from 'payload/types';
const afterDeleteHook: CollectionAfterDeleteHook = async ({
req, // full express request
req, // full Request object
id, // id of document to delete
doc, // deleted document
}) => {...}
@@ -210,7 +210,7 @@ import { CollectionAfterOperationHook } from 'payload/types'
const afterOperationHook: CollectionAfterOperationHook = async ({
args, // arguments passed into the operation
operation, // name of the operation
req, // full express request
req, // full Request object
result, // the result of the operation, before modifications
}) => {
return result // return modified result as necessary
@@ -225,7 +225,7 @@ For auth-enabled Collections, this hook runs during `login` operations where a u
import { CollectionBeforeLoginHook } from 'payload/types'
const beforeLoginHook: CollectionBeforeLoginHook = async ({
req, // full express request
req, // full Request object
user, // user being logged in
}) => {
return user
@@ -240,7 +240,7 @@ For auth-enabled Collections, this hook runs after successful `login` operations
import { CollectionAfterLoginHook } from 'payload/types';
const afterLoginHook: CollectionAfterLoginHook = async ({
req, // full express request
req, // full Request object
user, // user that was logged in
token, // user token
}) => {...}
@@ -254,7 +254,7 @@ For auth-enabled Collections, this hook runs after `logout` operations.
import { CollectionAfterLogoutHook } from 'payload/types';
const afterLogoutHook: CollectionAfterLogoutHook = async ({
req, // full express request
req, // full Request object
}) => {...}
```
@@ -266,8 +266,8 @@ For auth-enabled Collections, this hook runs after `refresh` operations.
import { CollectionAfterRefreshHook } from 'payload/types';
const afterRefreshHook: CollectionAfterRefreshHook = async ({
req, // full express request
res, // full express response
req, // full Request object
res, // full Response object
token, // newly refreshed user token
}) => {...}
```
@@ -280,7 +280,7 @@ For auth-enabled Collections, this hook runs after `me` operations.
import { CollectionAfterMeHook } from 'payload/types';
const afterMeHook: CollectionAfterMeHook = async ({
req, // full express request
req, // full Request object
response, // response to return
}) => {...}
```

View File

@@ -3,7 +3,7 @@ title: Field Hooks
label: Fields
order: 30
desc: Hooks can be added to any fields, and optionally modify the return value of the field before the operation continues.
keywords: hooks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: hooks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Field-level hooks offer incredible potential for encapsulating your logic. They help to isolate concerns and package up
@@ -74,7 +74,7 @@ Field Hooks receive one `args` argument that contains the following properties:
| **`originalDoc`** | The full original document in `update` operations. In the `afterChange` hook, this is the resulting document of the operation. |
| **`previousDoc`** | The document before changes were applied, only in `afterChange` hooks. |
| **`previousSiblingDoc`** | The sibling data of the document before changes being applied, only in `beforeChange` and `afterChange` hook. |
| **`req`** | The Express `request` object. It is mocked for Local API operations. |
| **`req`** | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. It is mocked for Local API operations. |
| **`value`** | The value of the field. |
| **`previousValue`** | The previous value of the field, before changes, only in `beforeChange` and `afterChange` hooks. |
| **`context`** | Context passed to this hook. More info can be found under [Context](/docs/hooks/context) |

View File

@@ -3,7 +3,7 @@ title: Global Hooks
label: Globals
order: 40
desc: Hooks can be added to any Global and allow you to validate data, flatten locales, hide protected fields, remove fields and more.
keywords: hooks, globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: hooks, globals, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Globals feature the ability to define the following hooks:
@@ -47,7 +47,7 @@ import { GlobalBeforeValidateHook } from 'payload/types'
const beforeValidateHook: GlobalBeforeValidateHook = async ({
data, // incoming data to update or create with
req, // full express request
req, // full Request object
originalDoc, // original document
}) => {
return data // Return data to update the document with
@@ -63,7 +63,7 @@ import { GlobalBeforeChangeHook } from 'payload/types'
const beforeChangeHook: GlobalBeforeChangeHook = async ({
data, // incoming data to update or create with
req, // full express request
req, // full Request object
originalDoc, // original document
}) => {
return data // Return data to update the document with
@@ -80,7 +80,7 @@ import { GlobalAfterChangeHook } from 'payload/types'
const afterChangeHook: GlobalAfterChangeHook = async ({
doc, // full document data
previousDoc, // document data before updating the collection
req, // full express request
req, // full Request object
}) => {
return data
}
@@ -95,7 +95,7 @@ import { GlobalBeforeReadHook } from 'payload/types'
const beforeReadHook: GlobalBeforeReadHook = async ({
doc, // full document data
req, // full express request
req, // full Request object
}) => {...}
```
@@ -108,7 +108,7 @@ import { GlobalAfterReadHook } from 'payload/types'
const afterReadHook: GlobalAfterReadHook = async ({
doc, // full document data
req, // full express request
req, // full Request object
findMany, // boolean to denote if this hook is running against finding one, or finding many (useful in versions)
}) => {...}
```

View File

@@ -3,7 +3,7 @@ title: Hooks Overview
label: Overview
order: 10
desc: Hooks allow you to add your own logic to Payload, including integrating with third-party APIs, adding auto-generated data, or modifing Payload's base functionality.
keywords: hooks, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: hooks, overview, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner type="info">
@@ -36,7 +36,7 @@ If your Hook simply performs a side-effect, such as updating a CRM, it might be
## Server-only execution
Payload Hooks are only triggered on the server. You can safely [remove your hooks](/docs/admin/webpack#aliasing-server-only-modules) from your Admin panel's client-side code by customizing the Webpack config, which not only keeps your Admin bundles' filesize small but also ensures that any server-side only code does not cause problems within browser environments.
Payload Hooks are only triggered on the server and are automatically excluded from the Payload Admin bundle.
## Hook Types

View File

@@ -3,7 +3,7 @@ title: Vercel Content Link
label: Vercel Content Link
order: 10
desc: Payload + Vercel Content Link allows yours editors to navigate directly from the content rendered on your front-end to the fields in Payload that control it.
keywords: vercel, vercel content link, visual editing, content source maps, Content Management System, cms, headless, javascript, node, react, express
keywords: vercel, vercel content link, content link, visual editing, content source maps, Content Management System, cms, headless, javascript, node, react, nextjs
---
[Vercel Content Link](https://vercel.com/docs/workflow-collaboration/edit-mode#content-link) will allow your editors to navigate directly from the content rendered on your front-end to the fields in Payload that control it. This requires no changes to your front-end code and very few changes to your Payload config.

View File

@@ -7,7 +7,7 @@ keywords: live preview, frontend, react, next.js, vue, nuxt.js, svelte, hook, us
---
<Banner type="info">
If your front-end application supports Server Components like the [Next.js App Router](https://nextjs.org/docs/app), etc., we suggest setting up [server-side Live Preview](./server).
If your front-end application supports Server Components like the [Next.js App Router](https://nextjs.org/docs/app), etc., we suggest setting up [server-side Live Preview](./server) instead.
</Banner>
While using Live Preview, the Admin panel emits a new `window.postMessage` event every time your document has changed. Your front-end application can listen for these events and re-render accordingly.

View File

@@ -6,11 +6,11 @@ desc: Learn how to implement Live Preview in your front-end application.
keywords: live preview, frontend, react, next.js, vue, nuxt.js, svelte, hook, useLivePreview
---
There are two ways to use Live Preview in your own application depending on whether your front-end framework supports server components:
There are two ways to use Live Preview in your own application depending on whether your front-end framework supports Server Components:
- [Server-side Live Preview (suggested)](./server)
- [Client-side Live Preview](./client)
<Banner type="info">
We suggest using server-side Live Preview if your framework supports it, it is both simpler to setup and more performant to run than the client-side alternative.
We suggest using server-side Live Preview if your framework supports Server Components, it is both simpler to setup and more performant to run than the client-side alternative.
</Banner>

View File

@@ -20,7 +20,7 @@ If your front-end application is built with [React](#react), you can use the `Re
## React
If your front-end application is built with [React](https://react.dev) or [Next.js](https://nextjs.org), you can use the `RefreshRouteOnSave` component that Payload provides.
If your front-end application is built with server-side [React](https://react.dev) like [Next.js App Router](https://nextjs.org/docs/app), you can use the `RefreshRouteOnSave` component that Payload provides.
First, install the `@payloadcms/live-preview-react` package:
@@ -28,7 +28,7 @@ First, install the `@payloadcms/live-preview-react` package:
npm install @payloadcms/live-preview-react
```
Then, render `RefreshRouteOnSave` anywhere in your `page.tsx`. Here's an example:
Then, render the `RefreshRouteOnSave` component anywhere in your `page.tsx`. Here's an example:
`page.tsx`:
@@ -64,7 +64,13 @@ import React from 'react'
export const RefreshRouteOnSave: React.FC = () => {
const router = useRouter()
return <PayloadLivePreview refresh={router.refresh} serverURL={process.env.PAYLOAD_SERVER_URL} />
return (
<PayloadLivePreview
refresh={() => router.refresh()}
serverURL={process.env.NEXT_PUBLIC_PAYLOAD_URL}
/>
)
}
```
@@ -153,13 +159,15 @@ export const RefreshRouteOnSave: React.FC<{
## Example
{/* TODO: add example once beta has been release and an example can be created */}
For a working demonstration of this, check out the official [Live Preview Example](https://github.com/payloadcms/payload/tree/main/examples/live-preview/payload). There you will find a fully working example of how to implement Live Preview in your Next.js App Router application.
## Troubleshooting
### Updates do not appear as fast as client-side Live Preview
If you are noticing that updates feel less snappy than client-side Live Preview (i.e. the `useLivePreview` hook), this is because of how the two differ in how they work—instead of emitting events against form state as you type, server-side Live Preview refreshes the route after a new document is saved. You can use autosave to mimic this effect. Try decreasing the value of `versions.autoSave.interval` to make the experience feel more responsive:
If you are noticing that updates feel less snappy than client-side Live Preview (i.e. the `useLivePreview` hook), this is because of how the two differ in how they work—instead of emitting events against _form state_, server-side Live Preview refreshes the route after a new document is _saved_.
Use [Autosave](../versions/autosave) to mimic this effect server-side. Try decreasing the value of `versions.autoSave.interval` to make the experience feel more responsive:
```ts
// collection.ts

View File

@@ -3,7 +3,7 @@ title: Local API
label: Overview
order: 10
desc: The Payload Local API allows you to interact with your database and execute the same operations that are available through REST and GraphQL within Node, directly on your server.
keywords: local api, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: local api, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
The Payload Local API gives you the ability to execute the same operations that are available through REST and GraphQL
@@ -23,7 +23,7 @@ can interact directly with your database.
Here are some common examples of how you can use the Local API:
- Seeding data via Node seed scripts that you write and maintain
- Opening custom Express routes which feature additional functionality but still rely on Payload
- Opening custom routes which feature additional functionality but still rely on Payload
- Within access control and hook functions
## Accessing payload
@@ -51,7 +51,7 @@ const afterChangeHook: CollectionAfterChangeHook = async () => {
#### Accessing from the `req`
Payload is available anywhere you have access to the Express `req` - including within your access control and hook
Payload is available anywhere you have access to the `req` - including within your access control and hook
functions.
Example:
@@ -310,7 +310,7 @@ const result = await payload.login({
email: 'dev@payloadcms.com',
password: 'rip',
},
req: req, // pass an Express `req` which will be provided to all hooks
req: req, // pass a Request object to be provided to all hooks
res: res, // used to automatically set an HTTP-only auth cookie
depth: 2,
locale: 'en',
@@ -330,7 +330,7 @@ const token = await payload.forgotPassword({
// required
email: 'dev@payloadcms.com',
},
req: req, // pass an Express `req` which will be provided to all hooks
req: req, // pass a Request object to be provided to all hooks
})
```
@@ -349,7 +349,7 @@ const result = await payload.resetPassword({
password: req.body.password, // the new password to set
token: 'afh3o2jf2p3f...', // the token generated from the forgotPassword operation
},
req: req, // pass an Express `req` which will be provided to all hooks
req: req, // pass a Request object to be provided to all hooks
res: res, // used to automatically set an HTTP-only auth cookie
})
```
@@ -364,7 +364,7 @@ const result = await payload.unlock({
// required
email: 'dev@payloadcms.com',
},
req: req, // pass an Express `req` which will be provided to all hooks
req: req, // pass a Request object to be provided to all hooks
overrideAccess: true,
})
```
@@ -427,10 +427,10 @@ const result = await payload.updateGlobal({
## Next.js Conflict with Local API
There is a known issue when using the Local API with Next.js version `13.4.13` and higher. Next.js executes within a
separate child process, and Payload has not been initalized yet in these instances. That means that unless you
separate child process, and Payload has not been initialized yet in these instances. That means that unless you
explicitly initialize Payload within your operation, it will not be running and return no data / an empty object.
As a workaround, we recommend leveraging the following pattern to determine and ensure Payload is initalized:
As a workaround, we recommend leveraging the following pattern to determine and ensure Payload is initialized:
```
import dotenv from 'dotenv'

View File

@@ -3,7 +3,7 @@ title: Building Your Own Plugin
label: Build Your Own
order: 50
desc: Starting to build your own plugin? Find everything you need and learn best practices with the Payload plugin template.
keywords: plugins, template, config, configuration, extensions, custom, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: plugins, template, config, configuration, extensions, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Building your own plugin is easy, and if you&apos;re already familiar with Payload then you&apos;ll have everything you need to get started. You can either start from scratch or use the Payload plugin template to get up and running quickly.
@@ -235,22 +235,6 @@ If you wish to add to the `onInit`, you must include the async/await. We don&apo
In the template, we have stubbed out a basic `onInitExtension` file that you can use, if not needed feel free to delete it.
## Webpack
If any of your files use server only packages such as fs, stripe, nodemailer, etc, they will need to be removed from the browser bundle. To do that, you can [alias the file imports with webpack](https://payloadcms.com/docs/admin/webpack#aliasing-server-only-modules).
When files are bundled for the browser, the import paths are essentially crawled to determine what files to include in the bundle. To prevent the server only files from making it into the bundle, we can alias their import paths to a file that can be included in the browser. This will short-circuit the import path crawling and ensure browser only code is bundled.
Webpack is another part of the Payload config that can be a little more tricky to extend. To help here, the template includes a helper function `extendWebpackConfig()` which takes care of spreading the existing webpack, so you can just add your new stuff:
```
config.admin = {
...(config.admin || {}),
// Add your aliases to the helper function below
webpack: extendWebpackConfig(incomingConfig)
}
```
## Types
If your plugin has options, you should define and provide types for these options in a separate file which gets exported from the main `index.ts`.
@@ -274,7 +258,7 @@ In addition to the setup covered above, here are other best practices to follow:
### Providing an enable / disable option
For a better user experience, provide a way to disable the plugin without uninstalling it. This is especially important if your plugin adds additional webpack aliases, this will allow you to still let the webpack run to prevent errors.
For a better user experience, provide a way to disable the plugin without uninstalling it.
### Include tests in your GitHub CI workflow

View File

@@ -3,7 +3,7 @@ title: Plugins
label: Overview
order: 10
desc: Plugins provide a great way to modularize Payload functionalities into easy-to-use enhancements and extensions of your Payload apps.
keywords: plugins, config, configuration, extensions, custom, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: plugins, config, configuration, extensions, custom, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload comes with a built-in Plugins infrastructure that allows developers to build their own modular and easily reusable sets of functionality.
@@ -39,12 +39,7 @@ import passwordProtect from 'payload-password-protect'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { postgresAdapter } from '@payloadcms/db-postgres'
import { viteBundler } from '@payloadcms/bundler-vite'
import { webpackBundler } from '@payloadcms/bundler-webpack'
const config = buildConfig({
bundler: webpackBundler() // or viteBundler(),
collections: [
{
slug: 'pages',

View File

@@ -3,7 +3,7 @@ title: Production Deployment
label: Deployment
order: 10
desc: When your Payload based app is ready, tested, looking great, it is time to deploy. Learn how to deploy your app and what to consider before deployment.
keywords: deployment, production, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: deployment, production, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner type="success">
@@ -48,10 +48,14 @@ wield that power responsibly before deploying to Production.
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.
access control functions are more strict - permitting
{' '}
<strong>
only appropriate users
</strong>
{' '}
to perform appropriate actions.
</Banner>
### Building the Admin panel
@@ -73,7 +77,7 @@ Payload provides the `build` NPM script. You can use it by adding a `script` to
}
```
Then, to build Payload, you would run `npm run build` in your project folder. A production-ready Admin bundle will be
Then, to build Payload, you would run `npm run build` in your project folder. A production-ready Payload Admin bundle will be
created in the `build` directory.
### Setting Node to Production
@@ -181,7 +185,7 @@ _copy_ the files your users upload to a more permanent storage solution like Ama
**To automatically send uploaded files to S3 or similar, you could:**
- Write an asynchronous `beforeChange` hook for all Collections that support Uploads, which takes any uploaded `file`
from the Express `req` and sends it to an S3 bucket
from the `req` and sends it to an S3 bucket
- Write an `afterRead` hook to save a `s3URL` field that automatically takes the `filename` stored and formats a full S3
URL
- Write an `afterDelete` hook that automatically deletes files from the S3 bucket

View File

@@ -3,7 +3,7 @@ title: Preventing Production API Abuse
label: Preventing Abuse
order: 20
desc: Payload has built-in security that can be configured to combat production API abuse such as limiting login attempts and IP requests.
keywords: abuse, production, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: abuse, production, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
## Introduction
@@ -22,7 +22,7 @@ To prevent DDoS, brute-force, and similar attacks, you can set IP-based rate lim
| ---------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **`window`** | Time in milliseconds to track requests per IP. Defaults to `90000` (15 minutes). |
| **`max`** | Number of requests served from a single IP before limiting. Defaults to `500`. |
| **`skip`** | Express middleware function that can return true (or promise resulting in true) that will bypass limit. |
| **`skip`** | 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">
@@ -53,7 +53,7 @@ Because GraphQL gives the power of query writing outside a server's control, som
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.
If you do not need GraphQL it is advised that you disable it altogether with the Payload config by setting `graphQL.disable: true`. Should you wish to enable GraphQL again, you can remove this property or set it `false`, any time. By turning it off, Payload will bypass creating schemas from your collections and will not register the express route.
If you do not need GraphQL it is advised that you disable it altogether with the Payload config by setting `graphQL.disable: true`. Should you wish to enable GraphQL again, you can remove this property or set it `false`, any time. By turning it off, Payload will bypass creating schemas from your collections and will not register the route.
## Malicious File Uploads

View File

@@ -3,7 +3,7 @@ title: Querying your Documents
label: Overview
order: 10
desc: Payload provides a querying language through all APIs, allowing you to filter or search through documents within a Collection.
keywords: query, documents, overview, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: query, documents, overview, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload provides an extremely granular querying language through all APIs. Each API takes the same syntax and fully supports all options.
@@ -12,9 +12,8 @@ Payload provides an extremely granular querying language through all APIs. Each
<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 [restrict which documents certain
users can access](/docs/access-control/overview) via access control functions.
users can [access](/docs/access-control/overview) via access control functions.
</Banner>
## Simple queries
@@ -146,7 +145,7 @@ query {
With the REST API, you can use the full power of Payload queries as well but they become a bit more unwieldy the more complex that they get.
Simple queries are fairly straightforward to write. To understand the syntax, you need to understand how Express and similar languages would go about parsing a complex URL search string into a JSON object. For example, the above [simple query](#simple-queries) would be parsed into a string like this:
Simple queries are fairly straightforward to write. To understand the syntax, you need to understand that complex URL search strings are parsed into a JSON object. For example, the above [simple query](#simple-queries) would be parsed into a string like this:
**`https://localhost:3000/api/posts?where[color][equals]=mint`**

View File

@@ -3,7 +3,7 @@ title: Pagination
label: Pagination
order: 20
desc: Payload queries are equipped with automatic pagination so you create paginated lists of documents within your app.
keywords: query, documents, pagination, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: query, documents, pagination, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
All collection `find` queries are paginated automatically. Responses are returned with top-level meta data related to pagination, and returned documents are nested within a `docs` array.

View File

@@ -3,7 +3,7 @@ title: REST API
label: Overview
order: 10
desc: Payload generates a fully functional REST API from your Collection and Global configs.
keywords: rest, api, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: rest, api, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
@@ -578,8 +578,8 @@ Each endpoint object needs to have:
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`path`** | A string for the endpoint route after the collection or globals slug |
| **`method`** | The lowercase HTTP verb to use: 'get', 'head', 'post', 'put', 'delete', 'connect' or 'options' |
| **`handler`** | A function or array of functions to be called with **req**, **res** and **next** arguments. [Express](https://expressjs.com/en/guide/routing.html#route-handlers) |
| **`root`** | When `true`, defines the endpoint on the root Express app, bypassing Payload handlers and the `routes.api` subpath. Note: this only applies to top-level endpoints of your Payload config, endpoints defined on `collections` or `globals` cannot be root. |
| **`handler`** | A function or array of functions to be called with **req**, **res** and **next** arguments. [Next.js](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) |
| **`root`** | When `true`, defines the endpoint on the root Next.js app, bypassing Payload handlers and the `routes.api` subpath. Note: this only applies to top-level endpoints of your Payload config, endpoints defined on `collections` or `globals` cannot be root. |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
Example:

View File

@@ -3,7 +3,7 @@ title: Troubleshooting
label: Troubleshooting
order: 10
desc: Troubleshooting Common Issues in Payload
keywords: admin, components, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, express, troubleshooting
keywords: admin, components, custom, customize, documentation, Content Management System, cms, headless, javascript, node, react, nextjs, troubleshooting
---
## Common Issues

View File

@@ -3,7 +3,7 @@ title: Generating TypeScript Interfaces
label: Generating Types
order: 20
desc: Generate your own TypeScript interfaces based on your collections and globals.
keywords: headless cms, typescript, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: headless cms, typescript, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
While building your own custom functionality into Payload, like plugins, hooks, access control functions, custom views, GraphQL queries / mutations, or anything else, you may benefit from generating your own TypeScript types dynamically from your Payload config itself.

View File

@@ -3,7 +3,7 @@ title: TypeScript - Overview
label: Overview
order: 10
desc: Payload is the most powerful TypeScript headless CMS available.
keywords: headless cms, typescript, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: headless cms, typescript, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload supports TypeScript natively, and not only that, the entirety of the CMS is built with TypeScript. To get started developing with Payload and TypeScript, you can use one of Payload's built-in boilerplates in one line via `create-payload-app`:

View File

@@ -3,7 +3,7 @@ title: Uploads
label: Overview
order: 10
desc: Payload supports uploads, storage and management of files directly on your server, combined with powerful file access control.
keywords: uploads, images, media, overview, documentation, Content Management System, cms, headless, javascript, node, react, express
keywords: uploads, images, media, overview, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>
@@ -50,7 +50,7 @@ Every Payload Collection can opt-in to supporting Uploads by specifying the `upl
| **`externalFileHeaderFilter`** | Accepts existing headers and can filter/modify them. |
| **`focalPoint`** | Set to `false` to disable the focal point selection tool in the Admin panel. The focal point selector is only available when `imageSizes` or `resizeOptions` are defined. [More](#crop-and-focal-point-selector) |
| **`formatOptions`** | An object with `format` and `options` that are used with the Sharp image library to format the upload file. [More](https://sharp.pixelplumbing.com/api-output#toformat) |
| **`handlers`** | Array of Express request handlers to execute before the built-in Payload static middleware executes. |
| **`handlers`** | Array of [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) handlers to execute before the built-in Payload static middleware executes. |
| **`imageSizes`** | If specified, image uploads will be automatically resized in accordance to these image sizes. [More](#image-sizes) |
| **`mimeTypes`** | Restrict mimeTypes in the file picker. Array of valid mimetypes or mimetype wildcards [More](#mimetypes) | |
| **`resizeOptions`** | An object passed to the the Sharp image library to resize the uploaded file. [More](https://sharp.pixelplumbing.com/api-resize) |

View File

@@ -3,7 +3,7 @@ title: Autosave
label: Autosave
order: 30
desc: Using Payload's Draft functionality, you can configure your collections and globals to autosave changes as drafts, and publish only you're ready.
keywords: version history, revisions, audit log, draft, publish, autosave, Content Management System, cms, headless, javascript, node, react, expresss
keywords: version history, revisions, audit log, draft, publish, autosave, Content Management System, cms, headless, javascript, node, react, nextjss
---
Extending on Payload's [Draft](/docs/versions/drafts) functionality, you can configure your collections and globals to autosave changes as drafts, and publish only you're ready. The Admin UI will automatically adapt to autosaving progress at an interval that you define, and will store all autosaved changes as a new Draft version. Never lose your work - and publish changes to the live document only when you're ready.

View File

@@ -3,7 +3,7 @@ title: Drafts
label: Drafts
order: 20
desc: Enable drafts on collection documents or globals and build true preview environments for your data.
keywords: version history, drafts, preview, draft, restore, publish, autosave, Content Management System, cms, headless, javascript, node, react, express
keywords: version history, drafts, preview, draft, restore, publish, autosave, Content Management System, cms, headless, javascript, node, react, nextjs
---
Payload's Draft functionality builds on top of the Versions functionality to allow you to make changes to your collection documents and globals, but publish only when you're ready. This functionality allows you to build powerful Preview environments for your data, where you can make sure your changes look good before publishing documents.

View File

@@ -3,7 +3,7 @@ title: Versions
label: Overview
order: 10
desc: Keep a version history or audit log of changes and publish collection documents and globals.
keywords: version history, revisions, audit log, draft, publish, restore, autosave, Content Management System, cms, headless, javascript, node, react, express
keywords: version history, revisions, audit log, draft, publish, restore, autosave, Content Management System, cms, headless, javascript, node, react, nextjs
---
<Banner>