obsidian/wiki/payloadcms/fields-number.md
2026-05-15 15:30:34 +01:00

4.2 KiB

title aliases tags sources created updated
Number Field
payload-number-field
number-field-payloadcms
payloadcms
fields
number
validation
raw/fields__number.md
2026-05-15 2026-05-15

Overview

The Number Field stores and validates numeric values. It supports min/max validation, array mode (hasMany), and browser-level step controls.

import type { Field } from 'payload'

export const MyNumberField: Field = {
  name: 'age',
  type: 'number',
}

Config Options

Option Description
name * Property name in DB
min Minimum accepted value (used in default validation)
max Maximum accepted value (used in default validation)
hasMany Makes field an ordered array of numbers instead of a single number
minRows Min array length (requires hasMany: true)
maxRows Max array length (requires hasMany: true)
unique DB-level unique index on this field's path
index Build DB index for faster queries
validate Custom validation function (runs on both Admin Panel and backend)
saveToJWT Include field value in user JWT (top-level auth collections)
hooks Field lifecycle hooks
access Field-level access control
hidden Hidden from all APIs (still saved to DB)
defaultValue Default value
localized Enable per-locale values (requires localization in base config)
required Field must have a value
virtual true = no DB column; or a string path to link with a relationship
typescriptSchema Override TS type generation with JSON schema
custom Extension point for plugins

Admin Options

admin: {
  step: 1,            // increment/decrement step for browser controls
  placeholder: '0',  // placeholder string
  autoComplete: 'age', // browser autocomplete hint
}

hasMany — Array of Numbers

{
  name: 'scores',
  type: 'number',
  hasMany: true,
  minRows: 1,
  maxRows: 10,
}

Stores an ordered array of numbers. Each element is still validated against min/max if provided.

Example

import type { CollectionConfig } from 'payload'

export const ExampleCollection: CollectionConfig = {
  slug: 'example-collection',
  fields: [
    {
      name: 'age',
      type: 'number',
      required: true,
      min: 0,
      max: 150,
      admin: {
        step: 1,
      },
    },
  ],
}

Custom Components

Import NumberField and FieldLabel from @payloadcms/ui.

Server Component:

import { NumberField } from '@payloadcms/ui'
import type { NumberFieldServerComponent } from 'payload'

export const CustomNumberFieldServer: NumberFieldServerComponent = ({
  clientField, path, schemaPath, permissions,
}) => <NumberField field={clientField} path={path} schemaPath={schemaPath} permissions={permissions} />

Client Component:

'use client'
import { NumberField } from '@payloadcms/ui'
import type { NumberFieldClientComponent } from 'payload'

export const CustomNumberFieldClient: NumberFieldClientComponent = (props) => <NumberField {...props} />

Label components follow the same server/client pattern using FieldLabel.

Key Takeaways

  • Use min/max for built-in range validation without writing a custom validate function.
  • hasMany: true turns the field into an ordered number array — pair with minRows/maxRows for length constraints.
  • admin.step controls the browser spinner increment; useful for integer fields (step: 1).
  • unique creates a DB-level index — avoid on arrays (hasMany) as uniqueness semantics are complex.
  • virtual: true skips DB storage entirely; use for computed/derived numeric values.

Sources