4.2 KiB
4.2 KiB
| title | aliases | tags | sources | created | updated | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Number Field |
|
|
|
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/maxfor built-in range validation without writing a customvalidatefunction. hasMany: trueturns the field into an ordered number array — pair withminRows/maxRowsfor length constraints.admin.stepcontrols the browser spinner increment; useful for integer fields (step: 1).uniquecreates a DB-level index — avoid on arrays (hasMany) as uniqueness semantics are complex.virtual: trueskips DB storage entirely; use for computed/derived numeric values.
Related
- wiki/payloadcms/fields-basic — all scalar field types overview
- wiki/payloadcms/fields-email — similar scalar field with format validation
- wiki/payloadcms/fields-checkbox — another simple scalar field
- wiki/payloadcms/database-indexes — how
index: trueanduniquework at DB level - wiki/payloadcms/authentication-token-data — embedding field values in JWT
Sources
raw/fields__number.md- https://payloadcms.com/docs/fields/number