Back to Payload

Edit View

docs/custom-components/edit-view.mdx

3.84.122.5 KB
Original Source

The Edit View is where users interact with individual Collection and Global Documents within the Admin Panel. The Edit View contains the actual form that submits the data to the server. This is where they can view, edit, and save their content. It contains controls for saving, publishing, and previewing the document, all of which can be customized to a high degree.

The Edit View can be swapped out in its entirety for a Custom View, or it can be injected with a number of Custom Components to add additional functionality or presentational elements without replacing the entire view.

<Banner type="warning"> **Note:** The Edit View is one of many [Document Views](./document-views) in the Payload Admin Panel. Each Document View is responsible for a different aspect of interacting with a single Document. </Banner>

Custom Edit View

To swap out the entire Edit View with a Custom View, use the views.edit.default property in your Collection Config or Global Config:

tsx
import { buildConfig } from 'payload'

const config = buildConfig({
  // ...
  admin: {
    components: {
      views: {
        edit: {
          // highlight-start
          default: {
            Component: '/path/to/MyCustomEditViewComponent',
          },
          // highlight-end
        },
      },
    },
  },
})

Here is an example of a custom Edit View:

Server Component

tsx
import React from 'react'
import type { DocumentViewServerProps } from 'payload'

export function MyCustomServerEditView(props: DocumentViewServerProps) {
  return <div>This is a custom Edit View (Server)</div>
}

Client Component

tsx
'use client'
import React from 'react'
import type { DocumentViewClientProps } from 'payload'

export function MyCustomClientEditView(props: DocumentViewClientProps) {
  return <div>This is a custom Edit View (Client)</div>
}

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

Custom Components

In addition to swapping out the entire Edit View with a Custom View, you can also override individual components. This allows you to customize specific parts of the Edit View without swapping out the entire view.

<Banner type="warning"> **Important:** Collection and Globals are keyed to a different property in the `admin.components` object and have slightly different options. Be sure to use the correct key for the entity you are working with. </Banner>

Collections

To override Edit View components for a Collection, use the admin.components.edit property in your Collection Config:

ts
import type { CollectionConfig } from 'payload'

export const MyCollection: CollectionConfig = {
  // ...
  admin: {
    components: {
      // highlight-start
      edit: {
        // ...
      },
      // highlight-end
    },
  },
}

The following options are available:

PathDescription
beforeDocumentControlsInject custom components before the Save / Publish buttons. More details.
editMenuItemsInject custom components within the 3-dot menu dropdown located in the document control bar. More details.
SaveButtonA button that saves the current document. More details.
SaveDraftButtonA button that saves the current document as a draft. More details.
PublishButtonA button that publishes the current document. More details.
UnpublishButtonA button that unpublishes the current document. More details.
PreviewButtonA button that previews the current document. More details.
DescriptionA description of the Collection. More details.
StatusA component that represents the status of the current document. More details.
UploadA file upload component. More details.

Globals

To override Edit View components for Globals, use the admin.components.elements property in your Global Config:

ts
import type { GlobalConfig } from 'payload'

export const MyGlobal: GlobalConfig = {
  // ...
  admin: {
    components: {
      // highlight-start
      elements: {
        // ...
      },
      // highlight-end
    },
  },
}

The following options are available:

PathDescription
beforeDocumentControlsInject custom components before the Save / Publish buttons. More details.
editMenuItemsInject custom components within the 3-dot menu dropdown located in the document control bar. More details.
SaveButtonA button that saves the current document. More details.
SaveDraftButtonA button that saves the current document as a draft. More details.
PublishButtonA button that publishes the current document. More details.
UnpublishButtonA button that unpublishes the current document. More details.
PreviewButtonA button that previews the current document. More details.
DescriptionA description of the Global. More details.
StatusA component that represents the status of the global. More details.

SaveButton

The SaveButton component allows you to render a custom Save Button in the Edit View.

Configuration Path

  • Collections: admin.components.edit.SaveButton
  • Globals: admin.components.elements.SaveButton

Example for Collections

ts
import type { CollectionConfig } from 'payload'

export const Posts: CollectionConfig = {
  slug: 'posts',
  admin: {
    components: {
      edit: {
        // highlight-start
        SaveButton: '/path/to/CustomSaveButton',
        // highlight-end
      },
    },
  },
}

Example for Globals

ts
import type { GlobalConfig } from 'payload'

export const Header: GlobalConfig = {
  slug: 'header',
  admin: {
    components: {
      elements: {
        // highlight-start
        SaveButton: '/path/to/CustomSaveButton',
        // highlight-end
      },
    },
  },
}

Here's an example of a custom SaveButton component:

Server Component

tsx
import React from 'react'
import { SaveButton } from '@payloadcms/ui'
import type { SaveButtonServerProps } from 'payload'

export function MySaveButton(props: SaveButtonServerProps) {
  return <SaveButton label="Save" />
}

Client Component

tsx
'use client'
import React from 'react'
import { SaveButton } from '@payloadcms/ui'
import type { SaveButtonClientProps } from 'payload'

export function MySaveButton(props: SaveButtonClientProps) {
  return <SaveButton label="Save" />
}

beforeDocumentControls

The beforeDocumentControls property allows you to render custom components just before the default document action buttons (like Save, Publish, or Preview). This is useful for injecting custom buttons, status indicators, or any other UI elements before the built-in controls.

To add beforeDocumentControls components, use the components.edit.beforeDocumentControls property in your Collection Config or components.elements.beforeDocumentControls in your Global Config:

Collections

export const MyCollection: CollectionConfig = {
  admin: {
    components: {
      edit: {
        // highlight-start
        beforeDocumentControls: ['/path/to/CustomComponent'],
        // highlight-end
      },
    },
  },
}

Globals

export const MyGlobal: GlobalConfig = {
  admin: {
    components: {
      elements: {
        // highlight-start
        beforeDocumentControls: ['/path/to/CustomComponent'],
        // highlight-end
      },
    },
  },
}

Here's an example of a custom beforeDocumentControls component:

Server Component

tsx
import React from 'react'
import type { BeforeDocumentControlsServerProps } from 'payload'

export function MyCustomDocumentControlButton(
  props: BeforeDocumentControlsServerProps,
) {
  return <div>This is a custom beforeDocumentControl button (Server)</div>
}

Client Component

tsx
'use client'
import React from 'react'
import type { BeforeDocumentControlsClientProps } from 'payload'

export function MyCustomDocumentControlButton(
  props: BeforeDocumentControlsClientProps,
) {
  return <div>This is a custom beforeDocumentControl button (Client)</div>
}

editMenuItems

The editMenuItems property allows you to inject custom components into the 3-dot menu dropdown located in the document controls bar. This dropdown contains default options including Create New, Duplicate, Delete, and other options when additional features are enabled. Any custom components you add will appear below these default items.

To add editMenuItems, use the components.edit.editMenuItems property in your Collection Config:

Config Example

ts
import type { CollectionConfig } from 'payload'

export const Pages: CollectionConfig = {
  slug: 'pages',
  admin: {
    components: {
      edit: {
        // highlight-start
        editMenuItems: ['/path/to/CustomEditMenuItem'],
        // highlight-end
      },
    },
  },
}

Here's an example of a custom editMenuItems component:

Server Component

tsx
import React from 'react'

import type { EditMenuItemsServerProps } from 'payload'

export const EditMenuItems = async (props: EditMenuItemsServerProps) => {
  const href = `/custom-action?id=${props.id}`

  return (
    <>
      <a href={href}>Custom Edit Menu Item</a>
      <a href={href}>
        Another Custom Edit Menu Item - add as many as you need!
      </a>
    </>
  )
}

Client Component

tsx
'use client'

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

import type { EditMenuItemsClientProps } from 'payload'

export const EditMenuItems = (props: EditMenuItemsClientProps) => {
  const handleClick = () => {
    console.log('Custom button clicked!')
  }

  return (
    <PopupList.ButtonGroup>
      <PopupList.Button onClick={handleClick}>
        Custom Edit Menu Item
      </PopupList.Button>
      <PopupList.Button onClick={handleClick}>
        Another Custom Edit Menu Item - add as many as you need!
      </PopupList.Button>
    </PopupList.ButtonGroup>
  )
}
<Banner type="info"> **Styling:** Use Payload's built-in `PopupList.Button` to ensure your menu items automatically match the default dropdown styles. If you want a different look, you can customize the appearance by passing your own `className` to `PopupList.Button`, or use a completely custom button built with a standard HTML `button` element or any other component that fits your design preferences. </Banner>

SaveDraftButton

The SaveDraftButton component allows you to render a custom Save Draft Button in the Edit View.

Configuration Path

  • Collections: admin.components.edit.SaveDraftButton
  • Globals: admin.components.elements.SaveDraftButton

Example for Collections

ts
import type { CollectionConfig } from 'payload'

export const Posts: CollectionConfig = {
  slug: 'posts',
  versions: {
    drafts: true,
  },
  admin: {
    components: {
      edit: {
        // highlight-start
        SaveDraftButton: '/path/to/CustomSaveDraftButton',
        // highlight-end
      },
    },
  },
}

Example for Globals

ts
import type { GlobalConfig } from 'payload'

export const Header: GlobalConfig = {
  slug: 'header',
  versions: {
    drafts: true,
  },
  admin: {
    components: {
      elements: {
        // highlight-start
        SaveDraftButton: '/path/to/CustomSaveDraftButton',
        // highlight-end
      },
    },
  },
}

Here's an example of a custom SaveDraftButton component:

Server Component

tsx
import React from 'react'
import { SaveDraftButton } from '@payloadcms/ui'
import type { SaveDraftButtonServerProps } from 'payload'

export function MySaveDraftButton(props: SaveDraftButtonServerProps) {
  return <SaveDraftButton />
}

Client Component

tsx
'use client'
import React from 'react'
import { SaveDraftButton } from '@payloadcms/ui'
import type { SaveDraftButtonClientProps } from 'payload'

export function MySaveDraftButton(props: SaveDraftButtonClientProps) {
  return <SaveDraftButton />
}

PublishButton

The PublishButton component allows you to render a custom Publish Button in the Edit View.

Configuration Path

  • Collections: admin.components.edit.PublishButton
  • Globals: admin.components.elements.PublishButton

Example for Collections

ts
import type { CollectionConfig } from 'payload'

export const Posts: CollectionConfig = {
  slug: 'posts',
  versions: {
    drafts: true,
  },
  admin: {
    components: {
      edit: {
        // highlight-start
        PublishButton: '/path/to/CustomPublishButton',
        // highlight-end
      },
    },
  },
}

Example for Globals

ts
import type { GlobalConfig } from 'payload'

export const Header: GlobalConfig = {
  slug: 'header',
  versions: {
    drafts: true,
  },
  admin: {
    components: {
      elements: {
        // highlight-start
        PublishButton: '/path/to/CustomPublishButton',
        // highlight-end
      },
    },
  },
}

Here's an example of a custom PublishButton component:

Server Component

tsx
import React from 'react'
import { PublishButton } from '@payloadcms/ui'
import type { PublishButtonServerProps } from 'payload'

export function MyPublishButton(props: PublishButtonServerProps) {
  return <PublishButton label="Publish" />
}

Client Component

tsx
'use client'
import React from 'react'
import { PublishButton } from '@payloadcms/ui'

export function MyPublishButton() {
  return <PublishButton label="Publish" />
}

UnpublishButton

The UnpublishButton property allows you to render a custom Unpublish Button in the Edit View.

To add an UnpublishButton component, use the components.edit.UnpublishButton property in your Collection Config or components.elements.UnpublishButton in your Global Config:

ts
import type { CollectionConfig } from 'payload'

export const MyCollection: CollectionConfig = {
  // ...
  admin: {
    components: {
      edit: {
        // highlight-start
        UnpublishButton: '/path/to/MyUnpublishButton',
        // highlight-end
      },
    },
  },
}

Here's an example of a custom UnpublishButton component:

Server Component

tsx
import React from 'react'
import { UnpublishButton } from '@payloadcms/ui'
import type { UnpublishButtonServerProps } from 'payload'

export function MyUnpublishButton(props: UnpublishButtonServerProps) {
  return <UnpublishButton label="Unpublish" />
}

Client Component

tsx
'use client'
import React from 'react'
import { UnpublishButton } from '@payloadcms/ui'

export function MyUnpublishButton() {
  return <UnpublishButton label="Unpublish" />
}

PreviewButton

The PreviewButton component allows you to render a custom Preview Button in the Edit View.

Configuration Path

  • Collections: admin.components.edit.PreviewButton
  • Globals: admin.components.elements.PreviewButton

Example for Collections

ts
import type { CollectionConfig } from 'payload'

export const Posts: CollectionConfig = {
  slug: 'posts',
  admin: {
    preview: () => 'https://example.com/preview',
    components: {
      edit: {
        // highlight-start
        PreviewButton: '/path/to/CustomPreviewButton',
        // highlight-end
      },
    },
  },
}

Example for Globals

ts
import type { GlobalConfig } from 'payload'

export const Header: GlobalConfig = {
  slug: 'header',
  admin: {
    preview: () => 'https://example.com/preview',
    components: {
      elements: {
        // highlight-start
        PreviewButton: '/path/to/CustomPreviewButton',
        // highlight-end
      },
    },
  },
}

Here's an example of a custom PreviewButton component:

Server Component

tsx
import React from 'react'
import { PreviewButton } from '@payloadcms/ui'
import type { PreviewButtonServerProps } from 'payload'

export function MyPreviewButton(props: PreviewButtonServerProps) {
  return <PreviewButton />
}

Client Component

tsx
'use client'
import React from 'react'
import { PreviewButton } from '@payloadcms/ui'
import type { PreviewButtonClientProps } from 'payload'

export function MyPreviewButton(props: PreviewButtonClientProps) {
  return <PreviewButton />
}

Description

The Description property allows you to render a custom description of the Collection or Global in the Edit View.

To add a Description component, use the components.edit.Description property in your Collection Config or components.elements.Description in your Global Config:

ts
import type { CollectionConfig } from 'payload'

export const MyCollection: CollectionConfig = {
  // ...
  admin: {
    components: {
      // highlight-start
      Description: '/path/to/MyDescriptionComponent',
      // highlight-end
    },
  },
}
<Banner type="warning"> **Note:** The `Description` component is shared between the Edit View and the [List View](./list-view). </Banner>

Here's an example of a custom Description component:

Server Component

tsx
import React from 'react'
import type { ViewDescriptionServerProps } from 'payload'

export function MyDescriptionComponent(props: ViewDescriptionServerProps) {
  return <div>This is a custom description component (Server)</div>
}

Client Component

tsx
'use client'
import React from 'react'
import type { ViewDescriptionClientProps } from 'payload'

export function MyDescriptionComponent(props: ViewDescriptionClientProps) {
  return <div>This is a custom description component (Client)</div>
}

Status

The Status component displays the document's draft/published state when versioning with drafts is enabled.

Configuration Path

  • Collections: admin.components.edit.Status
  • Globals: admin.components.elements.Status

Example for Collections

ts
import type { CollectionConfig } from 'payload'

export const Posts: CollectionConfig = {
  slug: 'posts',
  versions: {
    drafts: true,
  },
  admin: {
    components: {
      edit: {
        // highlight-start
        Status: '/path/to/CustomStatus',
        // highlight-end
      },
    },
  },
}

Example for Globals

ts
import type { GlobalConfig } from 'payload'

export const Header: GlobalConfig = {
  slug: 'header',
  versions: {
    drafts: true,
  },
  admin: {
    components: {
      elements: {
        // highlight-start
        Status: '/path/to/CustomStatus',
        // highlight-end
      },
    },
  },
}

Upload

The Upload property allows you to render a custom file upload component in the Edit View. This is only available for upload-enabled Collections.

To add an Upload component, use the components.edit.Upload property in your Collection Config:

ts
import type { CollectionConfig } from 'payload'

export const Media: CollectionConfig = {
  slug: 'media',
  upload: true,
  admin: {
    components: {
      edit: {
        // highlight-start
        Upload: '/path/to/MyUploadComponent#MyUploadServer',
        // highlight-end
      },
    },
  },
}
<Banner type="warning"> **Important:** Custom upload components must integrate with Payload's form system to work correctly. You cannot use a simple `<input type="file" />` as it won't connect to Payload's upload API. Instead, use Payload's built-in `<Upload>` component from `@payloadcms/ui` or properly integrate with form hooks like `useDocumentInfo()`. </Banner>

Here's an example of a custom Upload component:

Server Component

tsx
import React from 'react'
import type {
  PayloadServerReactComponent,
  SanitizedCollectionConfig,
} from 'payload'
import { CustomUploadClient } from './MyUploadComponent.client'

export const MyUploadServer: PayloadServerReactComponent<
  SanitizedCollectionConfig['admin']['components']['edit']['Upload']
> = (props) => {
  return (
    <div>
      <h2>Custom Upload Interface</h2>
      <CustomUploadClient {...props} />
    </div>
  )
}

Client Component

tsx
'use client'
import React from 'react'
import { Upload, useDocumentInfo } from '@payloadcms/ui'

export const CustomUploadClient = () => {
  const { collectionSlug, docConfig, initialState } = useDocumentInfo()

  return (
    <Upload
      collectionSlug={collectionSlug}
      initialState={initialState}
      uploadConfig={'upload' in docConfig ? docConfig.upload : undefined}
    />
  )
}

For more details on customizing upload components, including examples with custom actions and drawers, see the Upload documentation.