Back to Payload

Array Field

docs/fields/array.mdx

3.84.112.5 KB
Original Source

The Array Field is used when you need to have a set of "repeating" Fields. It stores an array of objects containing fields that you define. These fields can be of any type, including other arrays, to achieve infinitely nested data structures.

Arrays are useful for many different types of content from simple to complex, such as:

<LightDarkImage srcLight="https://payloadcms.com/images/docs/fields/array.png" srcDark="https://payloadcms.com/images/docs/fields/array-dark.png" alt="Array field with two Rows in Payload Admin Panel" caption="Admin Panel screenshot of an Array field with two Rows" />

To create an Array Field, set the type to array in your Field Config:

ts
import type { Field } from 'payload'

export const MyArrayField: Field = {
  // ...
  // highlight-start
  type: 'array',
  fields: [
    // ...
  ],
  // highlight-end
}

Config Options

OptionDescription
name *To be used as the property name when stored and retrieved from the database. More details.
labelText used as the heading in the Admin Panel or an object with keys for each language. Auto-generated from name if not defined.
fields *Array of field types to correspond to each row of the Array.
validateProvide a custom validation function that will be executed on both the Admin Panel and the backend. More details.
minRowsA number for the fewest allowed items during validation when a value is present.
maxRowsA number for the most allowed items during validation when a value is present.
saveToJWTIf this field is top-level and nested in a config supporting Authentication, include its data in the user JWT.
hooksProvide Field Hooks to control logic for this field. More details.
accessProvide Field Access Control to denote what users can see and do with this field's data. More details.
hiddenRestrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel.
defaultValueProvide an array of row data to be used for this field's default value. More details.
localizedEnable localization for this field. Requires localization to be enabled in the Base config. If enabled, a separate, localized set of all data within this Array will be kept, so there is no need to specify each nested field as localized.
requiredRequire this field to have a value.
labelsCustomize the row labels appearing in the Admin dashboard.
adminAdmin-specific configuration. More details.
customExtension point for adding custom data (e.g. for plugins)
interfaceNameCreate a top level, reusable Typescript interface & GraphQL type.
dbNameCustom table name for the field when using SQL Database Adapter (Postgres). Auto-generated from name if not defined.
typescriptSchemaOverride field type generation with providing a JSON schema
virtualProvide true to disable field in the database, or provide a string path to link the field with a relationship. See Virtual Fields

* An asterisk denotes that a property is required.

<Banner type="warning"> Setting `unique: true` on a field **inside** an Array creates a collection-wide database unique index — not a per-document one. No two documents in the collection can share the same value at that nested path, and on MongoDB, documents without the array will collide on `null`. To enforce uniqueness within a single document's rows, use a custom [`validate`](/docs/fields/overview#validation) function on this Array field. [More details](/docs/database/indexes#unique-fields). </Banner>

Admin Options

To customize the appearance and behavior of the Array Field in the Admin Panel, you can use the admin option:

ts
import type { Field } from 'payload'

export const MyArrayField: Field = {
  // ...
  admin: {
    // highlight-line
    // ...
  },
}

The Array Field inherits all of the default admin options from the base Field Admin Config, plus the following additional options:

OptionDescription
initCollapsedSet the initial collapsed state
components.RowLabelReact component to be rendered as the label on the array row. Example
isSortableDisable order sorting by setting this value to false

Example

In this example, we have an Array Field called slider that contains a set of fields for a simple image slider. Each row in the array has a title, image, and caption. We also customize the row label to display the title if it exists, or a default label if it doesn't.

ts
import type { CollectionConfig } from 'payload'

export const ExampleCollection: CollectionConfig = {
  slug: 'example-collection',
  fields: [
    {
      name: 'slider', // required
      type: 'array', // required
      label: 'Image Slider',
      minRows: 2,
      maxRows: 10,
      interfaceName: 'CardSlider', // optional
      labels: {
        singular: 'Slide',
        plural: 'Slides',
      },
      fields: [
        // required
        {
          name: 'title',
          type: 'text',
        },
        {
          name: 'image',
          type: 'upload',
          relationTo: 'media',
          required: true,
        },
        {
          name: 'caption',
          type: 'text',
        },
      ],
    },
  ],
}

Custom Components

Field

Server Component

tsx
import type React from 'react'
import { ArrayField } from '@payloadcms/ui'
import type { ArrayFieldServerComponent } from 'payload'

export const CustomArrayFieldServer: ArrayFieldServerComponent = ({
  clientField,
  path,
  schemaPath,
  permissions,
}) => {
  return (
    <ArrayField
      field={clientField}
      path={path}
      schemaPath={schemaPath}
      permissions={permissions}
    />
  )
}

Client Component

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

export const CustomArrayFieldClient: ArrayFieldClientComponent = (props) => {
  return <ArrayField {...props} />
}

Label

Server Component

tsx
import React from 'react'
import { FieldLabel } from '@payloadcms/ui'
import type { ArrayFieldLabelServerComponent } from 'payload'

export const CustomArrayFieldLabelServer: ArrayFieldLabelServerComponent = ({
  clientField,
  path,
}) => {
  return (
    <FieldLabel
      label={clientField?.label || clientField?.name}
      path={path}
      required={clientField?.required}
    />
  )
}

Client Component

tsx
'use client'
import type { ArrayFieldLabelClientComponent } from 'payload'

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

export const CustomArrayFieldLabelClient: ArrayFieldLabelClientComponent = ({
  field,
  path,
}) => {
  return (
    <FieldLabel
      label={field?.label || field?.name}
      path={path}
      required={field?.required}
    />
  )
}

Row Label

tsx
'use client'

import { useRowLabel } from '@payloadcms/ui'

export const ArrayRowLabel = () => {
  const { data, rowNumber } = useRowLabel<{ title?: string }>()

  const customLabel = `${data.title || 'Slide'} ${String(rowNumber).padStart(2, '0')} `

  return <div>Custom Label: {customLabel}</div>
}