- Removes mention of custom providers needing to be client components - Documents custom field `Filter` components - Adjusts language and other misc. grammar and spelling
376 lines
16 KiB
Plaintext
376 lines
16 KiB
Plaintext
---
|
|
title: Customizing Views
|
|
label: Customizing Views
|
|
order: 50
|
|
desc:
|
|
keywords:
|
|
---
|
|
|
|
Views are the individual pages that make up the [Admin Panel](./overview), such as the Dashboard, List, and Edit views. One of the most powerful ways to customize the Admin Panel is to create Custom Views. These are [Custom Components](./components) that can either replace built-in views or can be entirely new.
|
|
|
|
There are four types of views within the Admin Panel:
|
|
|
|
- [Root Views](#root-views)
|
|
- [Collection Views](#collection-views)
|
|
- [Global Views](#global-views)
|
|
- [Document Views](#document-views)
|
|
|
|
To swap in your own Custom View, first consult the list of available components, determine the scope that corresponds to what you are trying to accomplish, then [author your React component(s)](#building-custom-views) accordingly.
|
|
|
|
## Root Views
|
|
|
|
Root Views are the main views of the [Admin Panel](./overview). These are views that are scoped directly under the `/admin` route, such as the Dashboard or Account views.
|
|
|
|
To swap Root Views with your own, or to [create entirely new ones](#adding-new-root-views), use the `admin.components.views` property of your root [Payload Config](../configuration/overview):
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
|
|
const config = buildConfig({
|
|
// ...
|
|
admin: {
|
|
components: {
|
|
views: {
|
|
customView: {
|
|
Component: '/path/to/MyCustomView#MyCustomView', // highlight-line
|
|
path: '/my-custom-view',
|
|
}
|
|
},
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
Your Custom Root Views can optionally use one of the templates that Payload provides. The most common of these is the Default Template which provides the basic layout and navigation. Here is an example of what that might look like:
|
|
|
|
```tsx
|
|
import type { AdminViewProps } from 'payload'
|
|
|
|
import { DefaultTemplate } from '@payloadcms/next/templates'
|
|
import { Gutter } from '@payloadcms/ui'
|
|
import React from 'react'
|
|
|
|
export const MyCustomView: React.FC<AdminViewProps> = ({
|
|
initPageResult,
|
|
params,
|
|
searchParams,
|
|
}) => {
|
|
return (
|
|
<DefaultTemplate
|
|
i18n={initPageResult.req.i18n}
|
|
locale={initPageResult.locale}
|
|
params={params}
|
|
payload={initPageResult.req.payload}
|
|
permissions={initPageResult.permissions}
|
|
searchParams={searchParams}
|
|
user={initPageResult.req.user || undefined}
|
|
visibleEntities={initPageResult.visibleEntities}
|
|
>
|
|
<Gutter>
|
|
<h1>Custom Default Root View</h1>
|
|
<br />
|
|
<p>This view uses the Default Template.</p>
|
|
</Gutter>
|
|
</DefaultTemplate>
|
|
)
|
|
}
|
|
```
|
|
|
|
_For details on how to build Custom Views, including all available props, see [Building Custom Views](#building-custom-views)._
|
|
|
|
The following options are available:
|
|
|
|
| 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). |
|
|
|
|
For more granular control, pass a configuration object instead. Payload exposes the following properties for each view:
|
|
|
|
| Property | Description |
|
|
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
| **`Component`** \* | Pass in the component path 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 pathname. |
|
|
| **`sensitive`** | When true, will match if the path is case sensitive.|
|
|
| **`meta`** | Page metadata overrides to apply to this view within the Admin Panel. [More details](./metadata). |
|
|
|
|
_\* An asterisk denotes that a property is required._
|
|
|
|
### Adding New Views
|
|
|
|
To add a _new_ views to the [Admin Panel](./overview), simply add your own key to the `views` object with at least a `path` and `Component` property. For example:
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
|
|
const config = buildConfig({
|
|
// ...
|
|
admin: {
|
|
components: {
|
|
views: {
|
|
// highlight-start
|
|
myCustomView: {
|
|
// highlight-end
|
|
Component: '/path/to/MyCustomView#MyCustomViewComponent',
|
|
path: '/my-custom-view',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
The above example shows how to add a new [Root View](#root-views), but the pattern is the same for [Collection Views](#collection-views), [Global Views](#global-views), and [Document Views](#document-views). For help on how to build your own Custom Views, see [Building Custom Views](#building-custom-views).
|
|
|
|
<Banner type="warning">
|
|
<strong>Note:</strong>
|
|
<br />
|
|
Routes are cascading, so 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, define your nested route _before_ your parent
|
|
route.
|
|
</Banner>
|
|
|
|
<Banner type="warning">
|
|
<strong>Custom views are public</strong>
|
|
<br />
|
|
Custom views are public by default. 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>
|
|
|
|
## Collection Views
|
|
|
|
Collection Views are views that are scoped under the `/collections` route, such as the Collection List and Document Edit views.
|
|
|
|
To swap out Collection Views with your own, or to [create entirely new ones](#adding-new-views), use the `admin.components.views` property of your [Collection Config](../collections/overview):
|
|
|
|
```ts
|
|
import type { SanitizedCollectionConfig } from 'payload'
|
|
|
|
export const MyCollectionConfig: SanitizedCollectionConfig = {
|
|
// ...
|
|
admin: {
|
|
components: {
|
|
views: {
|
|
edit: {
|
|
root: {
|
|
Component: '/path/to/MyCustomEditView', // highlight-line
|
|
}
|
|
// other options include:
|
|
// default
|
|
// versions
|
|
// version
|
|
// api
|
|
// livePreview
|
|
// [key: string]
|
|
// See "Document Views" for more details
|
|
},
|
|
list: {
|
|
Component: '/path/to/MyCustomListView',
|
|
}
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
_For details on how to build Custom Views, including all available props, see [Building Custom Views](#building-custom-views)._
|
|
|
|
<Banner type="warning">
|
|
<strong>Note:</strong>
|
|
The `root` property will replace the _entire_ Edit View, including the title, tabs, etc., _as well as all nested [Document Views](#document-views)_, such as the API, Live Preview, and Version views. To replace only the Edit View precisely, use the `edit.default` key instead.
|
|
</Banner>
|
|
|
|
The following options are available:
|
|
|
|
| Property | Description |
|
|
| ---------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
| **`edit`** | The Edit View is used to edit a single document for any given Collection. [More details](#document-views). |
|
|
| **`list`** | The List View is used to show a list of documents for any given Collection. |
|
|
|
|
<Banner type="success">
|
|
<strong>Note:</strong>
|
|
You can also add _new_ Collection Views to the config by adding a new key to the `views` object with at least a `path` and `Component` property. See [Adding New Views](#adding-new-views) for more information.
|
|
</Banner>
|
|
|
|
## Global Views
|
|
|
|
Global Views are views that are scoped under the `/globals` route, such as the Document Edit View.
|
|
|
|
To swap out Global Views with your own or [create entirely new ones](#adding-new-views), use the `admin.components.views` property in your [Global Config](../globals/overview):
|
|
|
|
```ts
|
|
import type { SanitizedGlobalConfig } from 'payload'
|
|
|
|
export const MyGlobalConfig: SanitizedGlobalConfig = {
|
|
// ...
|
|
admin: {
|
|
components: {
|
|
views: {
|
|
edit: {
|
|
root: {
|
|
Component: '/path/to/MyCustomEditView', // highlight-line
|
|
}
|
|
// other options include:
|
|
// default
|
|
// versions
|
|
// version
|
|
// api
|
|
// livePreview
|
|
// [key: string]
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
_For details on how to build Custom Views, including all available props, see [Building Custom Views](#building-custom-views)._
|
|
|
|
<Banner type="warning">
|
|
<strong>Note:</strong>
|
|
The `root` property will replace the _entire_ Edit View, including the title, tabs, etc., _as well as all nested [Document Views](#document-views)_, such as the API, Live Preview, and Version views. To replace only the Edit View precisely, use the `edit.default` key instead.
|
|
</Banner>
|
|
|
|
The following options are available:
|
|
|
|
| Property | Description |
|
|
| ---------- | ------------------------------------------------------------------- |
|
|
| **`edit`** | The Edit View is used to edit a single document for any given Global. [More details](#document-views). |
|
|
|
|
<Banner type="success">
|
|
<strong>Note:</strong>
|
|
You can also add _new_ Global Views to the config by adding a new key to the `views` object with at least a `path` and `Component` property. See [Adding New Views](#adding-new-views) for more information.
|
|
</Banner>
|
|
|
|
## Document Views
|
|
|
|
Document Views are views that are scoped under the `/collections/:collectionSlug/:id` or the `/globals/:globalSlug` route, such as the Edit View or the API View. All Document Views keep their overall structure across navigation changes, such as their title and tabs, and replace only the content below.
|
|
|
|
To swap out Document Views with your own, or to [create entirely new ones](#adding-new-document-views), use the `admin.components.views.Edit[key]` property in your [Collection Config](../collections/overview) or [Global Config](../globals/overview):
|
|
|
|
```ts
|
|
import type { SanitizedCollectionConfig } from 'payload'
|
|
|
|
export const MyCollectionOrGlobalConfig: SanitizedCollectionConfig = {
|
|
// ...
|
|
admin: {
|
|
components: {
|
|
views: {
|
|
edit: {
|
|
api: {
|
|
Component: '/path/to/MyCustomAPIViewComponent', // highlight-line
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
_For details on how to build Custom Views, including all available props, see [Building Custom Views](#building-custom-views)._
|
|
|
|
<Banner type="warning">
|
|
<strong>Note:</strong>
|
|
If you need to replace the _entire_ Edit View, including _all_ nested Document Views, use the `root` key. See [Custom Collection Views](#collection-views) or [Custom Global Views](#global-views) for more information.
|
|
</Banner>
|
|
|
|
The following options are available:
|
|
|
|
| Property | Description |
|
|
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
| **`root`** | The Root View overrides all other nested views and routes. No document controls or tabs are rendered when this key is set. |
|
|
| **`default`** | The Default View is the primary view in which your document is edited. It is rendered within the "Edit" tab. |
|
|
| **`versions`** | The Versions View is used to navigate the version history of a single document. It is rendered within the "Versions" tab. [More details](../versions). |
|
|
| **`version`** | The Version View is used to edit a single version of a document. It is rendered within the "Version" tab. [More details](../versions). |
|
|
| **`api`** | The API View is used to display the REST API JSON response for a given document. It is rendered within the "API" tab. |
|
|
| **`livePreview`** | The LivePreview view is used to display the Live Preview interface. It is rendered within the "Live Preview" tab. [More details](../live-preview). |
|
|
|
|
### Document Tabs
|
|
|
|
Each Document View can be given a new tab in the Edit View, if desired. Tabs are highly configurable, from as simple as changing the label to swapping out the entire component, they can be modified in any way. To add or customize tabs in the Edit View, use the `tab` key:
|
|
|
|
```ts
|
|
import type { SanitizedCollectionConfig } from 'payload'
|
|
|
|
export const MyCollection: SanitizedCollectionConfig = {
|
|
slug: 'my-collection',
|
|
admin: {
|
|
components: {
|
|
views: {
|
|
edit: {
|
|
myCustomTab: {
|
|
Component: '/path/to/MyCustomTab',
|
|
path: '/my-custom-tab',
|
|
tab: {
|
|
Component: '/path/to/MyCustomTabComponent' // highlight-line
|
|
}
|
|
},
|
|
anotherCustomTab: {
|
|
Component: '/path/to/AnotherCustomView',
|
|
path: '/another-custom-view',
|
|
// highlight-start
|
|
tab: {
|
|
label: 'Another Custom View',
|
|
href: '/another-custom-view',
|
|
}
|
|
// highlight-end
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
<Banner type="warning">
|
|
<strong>Note:</strong>
|
|
This applies to _both_ Collections _and_ Globals.
|
|
</Banner>
|
|
|
|
## Building Custom Views
|
|
|
|
Custom Views are just [Custom Components](./components) rendered at the page-level. To understand how to build Custom Views, first review the [Building Custom Components](./components#building-custom-components) guide. Once you have a Custom Component ready, you can use it as a Custom View.
|
|
|
|
```ts
|
|
import type { SanitizedCollectionConfig } from 'payload'
|
|
|
|
export const MyCollectionConfig: SanitizedCollectionConfig = {
|
|
// ...
|
|
admin: {
|
|
components: {
|
|
views: {
|
|
edit: {
|
|
Component: '/path/to/MyCustomView' // highlight-line
|
|
}
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
### Default Props
|
|
|
|
Your Custom Views will be provided with the following props:
|
|
|
|
| Prop | Description |
|
|
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| **`initPageResult`** | An object containing `req`, `payload`, `permissions`, etc. |
|
|
| **`clientConfig`** | The Client Config object. [More details](../components#accessing-the-payload-config). |
|
|
| **`importMap`** | The import map object. |
|
|
| **`params`** | An object containing the [Dynamic Route Parameters](https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes). |
|
|
| **`searchParams`** | An object containing the [Search Parameters](https://developer.mozilla.org/docs/Learn/Common_questions/What_is_a_URL#parameters). |
|
|
| **`doc`** | The document being edited. Only available in Document Views. [More details](#document-views). |
|
|
|
|
<Banner type="success">
|
|
<strong>Reminder:</strong>
|
|
All [Custom Server Components](./components) receive `payload` and `i18n` by default. See [Building Custom Components](./components#building-custom-components) for more details.
|
|
</Banner>
|
|
|
|
<Banner type="warning">
|
|
<strong>Important:</strong>
|
|
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>
|