Customizing Fields

Fields within the Admin Panel can be endlessly customized in their appearance and behavior without affecting their underlying data structure. Fields are designed to withstand heavy modification or even complete replacement through the use of Custom Field Components, Conditional Logic, Custom Validations, and more.

For example, your app might need to render a specific interface that Payload does not inherently support, such as a color picker. To do this, you could replace the default Text Field input with your own user-friendly component that formats the data into a valid color value.

Admin Options

You can customize the appearance and behavior of fields within the Admin Panel through the admin property of any Field Config:

1
import type { CollectionConfig } from 'payload'
2
3
export const CollectionConfig: CollectionConfig = {
4
// ...
5
fields: [
6
// ...
7
{
8
name: 'myField',
9
type: 'text',
10
admin: {
11
// ...
12
},
13
}
14
]
15
}

The following options are available:

OptionDescription
conditionProgrammatically show / hide fields based on other fields. More details.
componentsAll Field Components can be swapped out for Custom Components that you define. More details.
descriptionHelper text to display alongside the field to provide more information for the editor. More details.
positionSpecify if the field should be rendered in the sidebar by defining position: 'sidebar'.
widthRestrict the width of a field. You can pass any string-based value here, be it pixels, percentages, etc. This property is especially useful when fields are nested within a Row type where they can be organized horizontally.
styleCSS Properties to inject into the root element of the field.
classNameAttach a CSS class attribute to the root DOM element of a field.
readOnlySetting a field to readOnly has no effect on the API whatsoever but disables the admin component's editability to prevent editors from modifying the field's value.
disabledIf a field is disabled, it is completely omitted from the Admin Panel.
disableBulkEditSet disableBulkEdit to true to prevent fields from appearing in the select options when making edits for multiple documents.
disableListColumnSet disableListColumn to true to prevent fields from appearing in the list view column selector.
disableListFilterSet disableListFilter to true to prevent fields from appearing in the list view filter options.
hiddenWill transform the field into a hidden input type. Its value will still submit with requests in the Admin Panel, but the field itself will not be visible to editors.

Field Components

Within the Admin Panel, fields are rendered in three distinct places:

  • Field - The actual form field rendered in the Edit View.
  • Cell - The table cell component rendered in the List View.
  • Filter - The filter component rendered in the List View.

To easily swap in Field Components with your own, use the admin.components property in your Field Config:

1
import type { CollectionConfig } from 'payload'
2
3
export const CollectionConfig: CollectionConfig = {
4
// ...
5
fields: [
6
// ...
7
{
8
// ...
9
admin: {
10
components: {
11
// ...
12
},
13
},
14
}
15
]
16
}

The following options are available:

ComponentDescription
FieldThe form field rendered of the Edit View. More details.
CellThe table cell rendered of the List View. More details.
FilterThe filter component rendered in the List View. More details.
LabelOverride the default Label of the Field Component. More details.
ErrorOverride the default Error of the Field Component. More details.
DescriptionOverride the default Description of the Field Component. More details.
beforeInputAn array of elements that will be added before the input of the Field Component. More details.
afterInputAn array of elements that will be added after the input of the Field Component. More details.

* beforeInput and afterInput are only supported in fields that do not contain other fields, such as Text, and Textarea.

The Field Component

The Field Component is the actual form field rendered in the Edit View. This is the input that user's will interact with when editing a document.

To easily swap in your own Field Component, use the admin.components.Field property in your Field Config:

1
import type { CollectionConfig } from 'payload'
2
3
export const CollectionConfig: CollectionConfig = {
4
// ...
5
fields: [
6
// ...
7
{
8
// ...
9
admin: {
10
components: {
11
Field: MyFieldComponent,
12
},
13
},
14
}
15
]
16
}

For details on how to build Custom Components, see Building Custom Components.

All Field Components receive the following props:

PropertyDescription
AfterInputThe rendered result of the admin.components.afterInput property. More details.
BeforeInputThe rendered result of the admin.components.beforeInput property. More details.
CustomDescriptionThe rendered result of the admin.components.Description property. More details.
CustomErrorThe rendered result of the admin.components.Error property. More details.
CustomLabelThe rendered result of the admin.components.Label property. More details.
pathThe static path of the field at render time. More details.
disabledThe admin.disabled property defined in the Field Config.
requiredThe admin.required property defined in the Field Config.
classNameThe admin.className property defined in the Field Config.
styleThe admin.style property defined in the Field Config.
customThe admin.custom property defined in the Field Config.
placeholderThe admin.placeholder property defined in the Field Config.
descriptionPropsAn object that contains the props for the FieldDescription component.
labelPropsAn object that contains the props needed for the FieldLabel component.
errorPropsAn object that contains the props for the FieldError component.
docPreferencesAn object that contains the preferences for the document.
labelThe label value provided in the field, it can be used with i18n.
localeThe locale of the field. More details.
localizedA boolean value that represents if the field is localized or not. More details.
readOnlyA boolean value that represents if the field is read-only or not.
rtlA boolean value that represents if the field should be rendered right-to-left or not. More details.
userThe currently authenticated user. More details.
validateA function that can be used to validate the field.
hasManyIf a relationship field, the hasMany property defined in the Field Config.
maxLengthIf a text field, the maxLength property defined in the Field Config.
minLengthIf a text field, the minLength property defined in the Field Config.

Sending and receiving values from the form

When swapping out the Field component, you are responsible for sending and receiving the field's value from the form itself.

To do so, import the useField hook from @payloadcms/ui and use it to manage the field's value:

1
'use client'
2
import { useField } from '@payloadcms/ui'
3
4
export const CustomTextField: React.FC = () => {
5
const { value, setValue } = useField()
6
7
return (
8
<input
9
onChange={(e) => setValue(e.target.value)}
10
value={value}
11
/>
12
)
13
}

The Cell Component

The Cell Component is rendered in the table of the List View. It represents the value of the field when displayed in a table cell.

To easily swap in your own Cell Component, use the admin.components.Cell property in your Field Config:

1
import type { Field } from 'payload'
2
3
export const myField: Field = {
4
name: 'myField',
5
type: 'text',
6
admin: {
7
components: {
8
Cell: MyCustomCell,
9
},
10
},
11
}

For details on how to build Custom Components, see Building Custom Components.

All Cell Components receive the following props:

PropertyDescription
nameThe name of the field.
classNameThe admin.className property defined in the Field Config.
fieldTypeThe type property defined in the Field Config.
schemaPathThe path to the field in the schema. Similar to path, but without dynamic indices.
isFieldAffectingDataA boolean value that represents if the field is affecting the data or not.
labelThe label value provided in the field, it can be used with i18n.
labelsAn object that contains the labels for the field.
linkA boolean representing whether this cell should be wrapped in a link.
onClickA function that is called when the cell is clicked.
dateDisplayFormatIf a date field, the admin.dateDisplayFormat property defined in the Field Config.
optionsIf a select field, this is an array of options defined in the Field Config. More details.
relationToIf a relationship. or upload field, this is the collection(s) the field is related to.
richTextComponentMapIf a richText field, this is an object that maps the rich text components. More details.
blocksIf a blocks field, this is an array of labels and slugs representing the blocks defined in the Field Config. More details.

The Label Component

The Label Component is rendered anywhere a field needs to be represented by a label. This is typically used in the Edit View, but can also be used in the List View and elsewhere.

To easily swap in your own Label Component, use the admin.components.Label property in your Field Config:

1
import type { Field } from 'payload'
2
3
export const myField: Field = {
4
name: 'myField',
5
type: 'text',
6
admin: {
7
components: {
8
Label: MyCustomLabel,
9
},
10
},
11
}

For details on how to build Custom Components, see Building Custom Components.

All Label Components receive the following props:

PropertyDescription
labelLabel value provided in field, it can be used with i18n.
requiredThe admin.required property defined in the Field Config.
schemaPathThe path to the field in the schema. Similar to path, but without dynamic indices.

The Error Component

The Error Component is rendered when a field fails validation. It is typically displayed beneath the field input in a visually-compelling style.

To easily swap in your own Error Component, use the admin.components.Error property in your Field Config:

1
import type { Field } from 'payload'
2
3
export const myField: Field = {
4
name: 'myField',
5
type: 'text',
6
admin: {
7
components: {
8
Error: MyCustomError,
9
},
10
},
11
}

For details on how to build Custom Components, see Building Custom Components.

All Error Components receive the following props:

PropertyDescription
path*The static path of the field at render time. More details.

The Description Property

Field Descriptions are used to provide additional information to the editor about a field, such as special instructions. Their placement varies from field to field, but typically are displayed with subtle style differences beneath the field inputs.

A description can be configured in three ways:

To easily add a Custom Description to a field, use the admin.description property in your Field Config:

1
import type { SanitizedCollectionConfig } from 'payload'
2
3
export const MyCollectionConfig: SanitizedCollectionConfig = {
4
// ...
5
fields: [
6
// ...
7
{
8
name: 'myField',
9
type: 'text',
10
admin: {
11
description: 'Hello, world!'
12
},
13
},
14
]
15
}

Description Functions

Custom Descriptions can also be defined as a function. Description Functions are executed on the server and can be used to format simple descriptions based on the user's current Locale.

To easily add a Description Function to a field, set the admin.description property to a function in your Field Config:

1
import type { SanitizedCollectionConfig } from 'payload'
2
3
export const MyCollectionConfig: SanitizedCollectionConfig = {
4
// ...
5
fields: [
6
// ...
7
{
8
name: 'myField',
9
type: 'text',
10
admin: {
11
description: ({ t }) => `${t('Hello, world!')}`
12
},
13
},
14
]
15
}

All Description Functions receive the following arguments:

ArgumentDescription
tThe t function used to internationalize the Admin Panel. More details

The Description Component

Alternatively to the Description Property, you can also use a Custom Component as the Field Description. This can be useful when you need to provide more complex feedback to the user, such as rendering dynamic field values or other interactive elements.

To easily add a Description Component to a field, use the admin.components.Description property in your Field Config:

1
import type { SanitizedCollectionConfig } from 'payload'
2
import { MyCustomDescription } from './MyCustomDescription'
3
4
export const MyCollectionConfig: SanitizedCollectionConfig = {
5
// ...
6
fields: [
7
// ...
8
{
9
name: 'myField',
10
type: 'text',
11
admin: {
12
components: {
13
Description: MyCustomDescription,
14
}
15
}
16
}
17
]
18
}

For details on how to build a Custom Description, see Building Custom Components.

All Description Components receive the following props:

PropertyDescription
descriptionThe description property defined in the Field Config.

afterInput and beforeInput

With these properties you can add multiple components before and after the input element, as their name suggests. This is useful when you need to render additional elements alongside the field without replacing the entire field component.

To add components before and after the input element, use the admin.components.beforeInput and admin.components.afterInput properties in your Field Config:

1
import type { SanitizedCollectionConfig } from 'payload'
2
3
export const MyCollectionConfig: SanitizedCollectionConfig = {
4
// ...
5
fields: [
6
// ...
7
{
8
name: 'myField',
9
type: 'text',
10
admin: {
11
components: {
12
beforeInput: [MyCustomComponent],
13
afterInput: [MyOtherCustomComponent],
14
}
15
}
16
}
17
]
18
}

For details on how to build Custom Components, see Building Custom Components.

Conditional Logic

You can show and hide fields based on what other fields are doing by utilizing conditional logic on a field by field basis. The condition property on a field's admin config accepts a function which takes three arguments:

  • data - the entire document's data that is currently being edited
  • siblingData - only the fields that are direct siblings to the field with the condition
  • { user } - the final argument is an object containing the currently authenticated user

The condition function should return a boolean that will control if the field should be displayed or not.

Example:

1
{
2
fields: [
3
{
4
name: 'enableGreeting',
5
type: 'checkbox',
6
defaultValue: false,
7
},
8
{
9
name: 'greeting',
10
type: 'text',
11
admin: {
12
condition: (data, siblingData, { user }) => {
13
if (data.enableGreeting) {
14
return true
15
} else {
16
return false
17
}
18
},
19
},
20
},
21
]
22
}
Next

React Hooks