Back to Payload

Customizing Views

docs/custom-components/custom-views.mdx

3.84.114.8 KB
Original Source

Views are the individual pages that make up the Admin Panel, such as the Dashboard, List View, and Edit View. One of the most powerful ways to customize the Admin Panel is to create Custom Views. These are Custom Components that can either replace built-in views or be entirely new.

There are four types of views within the Admin Panel:

To swap in your own Custom View, first determine the scope that corresponds to what you are trying to accomplish, consult the list of available components, then author your React component(s) accordingly.

Configuration

Replacing Views

To customize views, use the admin.components.views property in your Payload Config. This is an object with keys for each view you want to customize. Each key corresponds to the view you want to customize.

The exact list of available keys depends on the scope of the view you are customizing, depending on whether it's a Root View, Collection View, or Global View. Regardless of the scope, the principles are the same.

Here is an example of how to swap out a built-in view:

ts
import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  admin: {
    components: {
      views: {
        // highlight-start
        dashboard: {
          Component: '/path/to/MyCustomDashboard',
        },
        // highlight-end
      },
    },
  },
})
<Banner type="success"> **Note:** The dashboard is a special case, where in addition to replacing the default view, [you can add widgets modularly](../custom-components/dashboard). </Banner>

For more granular control, pass a configuration object instead. Payload exposes the following properties for each view:

PropertyDescription
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 understands. Must begin with a forward slash (/).
exactBoolean. When true, will only match if the path matches the usePathname() exactly.
strictWhen 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.
sensitiveWhen true, will match if the path is case sensitive.
metaPage metadata overrides to apply to this view within the Admin Panel. More details.

* An asterisk denotes that a property is required.

Adding New Views

To add a new view to the Admin Panel, simply add your own key to the views object. This is true for all view scopes.

New views require at least the Component and path properties:

ts
import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  admin: {
    components: {
      views: {
        // highlight-start
        myCustomView: {
          Component: '/path/to/MyCustomView#MyCustomViewComponent',
          path: '/my-custom-view',
        },
        // highlight-end
      },
    },
  },
})
<Banner type="warning"> **Note:** 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>

Building Custom Views

Custom Views are simply Custom Components rendered at the page-level. Custom Views can either replace existing views or add entirely new ones. The process is generally the same regardless of the type of view you are customizing.

To understand how to build Custom Views, first review the Building Custom Components guide. Once you have a Custom Component ready, you can use it as a Custom View.

ts
import type { CollectionConfig } from 'payload'

export const MyCollectionConfig: CollectionConfig = {
  // ...
  admin: {
    components: {
      views: {
        // highlight-start
        edit: {
          Component: '/path/to/MyCustomView', // highlight-line
        },
        // highlight-end
      },
    },
  },
}

Default Props

Your Custom Views will be provided with the following props:

PropDescription
initPageResultAn object containing req, payload, permissions, etc.
clientConfigThe Client Config object. More details.
importMapThe import map object.
paramsAn object containing the Dynamic Route Parameters.
searchParamsAn object containing the Search Parameters.
docThe document being edited. Only available in Document Views. More details.
i18nThe i18n object.
payloadThe Payload class.
<Banner type="warning"> **Note:** The props above apply to **Root Views** and any view added at the root level. Collection List Views and Collection/Global Edit Views receive a different set of props specific to their context. See [List View Props](./list-view#props) and [Document Views](./document-views) for their respective prop references. </Banner>

Here is an example of a Custom View component:

tsx
import type { AdminViewServerProps } from 'payload'

import { Gutter } from '@payloadcms/ui'
import React from 'react'

export function MyCustomView(props: AdminViewServerProps) {
  return (
    <Gutter>
      <h1>Custom Default Root View</h1>
      <p>This view uses the Default Template.</p>
    </Gutter>
  )
}
<Banner type="success"> **Tip:** For consistent layout and navigation, you may want to wrap your Custom View with one of the built-in [Templates](./overview#templates). </Banner>

View Templates

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 how to use the Default Template in your Custom View:

tsx
import type { AdminViewServerProps } from 'payload'

import { DefaultTemplate } from '@payloadcms/next/templates'
import { Gutter } from '@payloadcms/ui'
import React from 'react'

export function MyCustomView({
  initPageResult,
  params,
  searchParams,
}: AdminViewServerProps) {
  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>
        <p>This view uses the Default Template.</p>
      </Gutter>
    </DefaultTemplate>
  )
}

Securing Custom Views

All Custom Views are public by default. 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.

Here is how you might secure a Custom View:

tsx
import type { AdminViewServerProps } from 'payload'

import { Gutter } from '@payloadcms/ui'
import React from 'react'

export function MyCustomView({ initPageResult }: AdminViewServerProps) {
  const {
    req: { user },
  } = initPageResult

  if (!user) {
    return <p>You must be logged in to view this page.</p>
  }

  return (
    <Gutter>
      <h1>Custom Default Root View</h1>
      <p>This view uses the Default Template.</p>
    </Gutter>
  )
}

Root Views

Root Views are the main views of the Admin Panel. These are views that are scoped directly under the /admin route, such as the Dashboard or Account views.

To swap out Root Views with your own, or to create entirely new ones, use the admin.components.views property at the root of your Payload Config:

ts
import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  admin: {
    components: {
      views: {
        // highlight-start
        dashboard: {
          Component: '/path/to/Dashboard',
        },
        // highlight-end
        // Other options include:
        // - account
        // - [key: string]
        // See below for more details
      },
    },
  },
})

For details on how to build Custom Views, including all available props, see Building Custom Views.

The following options are available:

PropertyDescription
accountThe Account view is used to show the currently logged in user's Account page.
dashboardThe main landing page of the Admin Panel.
[key]Any other key can be used to add a completely new Root View. More details.

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, use the admin.components.views property of your Collection Config:

ts
import type { CollectionConfig } from 'payload'

export const MyCollectionConfig: CollectionConfig = {
  // ...
  admin: {
    components: {
      views: {
        // highlight-start
        edit: {
          default: {
            Component: '/path/to/MyCustomCollectionView',
          },
        },
        // highlight-end
        // Other options include:
        // - list
        // - [key: string]
        // See below for more details
      },
    },
  },
}
<Banner type="success"> **Reminder:** The `edit` key is comprised of various nested views, known as Document Views, that relate to the same Collection Document. [More details](./document-views). </Banner>

The following options are available:

PropertyDescription
editThe Edit View corresponds to a single Document for any given Collection and consists of various nested views. More details.
listThe List View is used to show a list of Documents for any given Collection. More details.
[key]Any other key can be used to add a completely new Collection View. More details.

For details on how to build Custom Views, including all available props, see Building Custom Views.

Global Views

Global Views are views that are scoped under the /globals route, such as the Edit View.

To swap out Global Views with your own or create entirely new ones, use the admin.components.views property in your Global Config:

ts
import type { SanitizedGlobalConfig } from 'payload'

export const MyGlobalConfig: SanitizedGlobalConfig = {
  // ...
  admin: {
    components: {
      views: {
        // highlight-start
        edit: {
          default: {
            Component: '/path/to/MyCustomGlobalView',
          },
        },
        // highlight-end
        // Other options include:
        // - [key: string]
        // See below for more details
      },
    },
  },
}
<Banner type="success"> **Reminder:** The `edit` key is comprised of various nested views, known as Document Views, that relate to the same Global Document. [More details](./document-views). </Banner>

The following options are available:

PropertyDescription
editThe Edit View represents a single Document for any given Global and consists of various nested views. More details.
[key]Any other key can be used to add a completely new Global View. More details.

For details on how to build Custom Views, including all available props, see Building Custom Views.