--- title: "Text Field" aliases: [payload-text-field, text-field-payloadcms, slug-field-payload] tags: [payloadcms, fields, text, slug, forms] sources: [raw/fields__text.md] created: 2026-05-15 updated: 2026-05-15 --- ## Overview The Text Field is one of the most-used Payload fields. It saves a plain `string` to the database and renders a simple text input in the Admin Panel. Set `type: 'text'` in the field config. ```ts import type { Field } from 'payload' export const MyTextField: Field = { name: 'pageTitle', type: 'text', required: true, } ``` ## Key Takeaways - Stores a `string` in the database; one column per field (or multiple rows when `hasMany: true`). - `hasMany: true` turns it into an **ordered string array** — use `minRows`/`maxRows` to bound it. - `unique: true` creates a **database-level unique index** — not just an app-level check. - `saveToJWT: true` embeds the value in the user JWT — useful for roles/flags without extra DB lookups. See [[wiki/payloadcms/authentication-token-data|Authentication — Token Data]]. - `hidden: true` excludes the field from all APIs and the Admin Panel but still persists to DB. - `virtual: true` (boolean) disables DB persistence; or pass a string path to link to a [[wiki/payloadcms/fields-relationship|Relationship Field]]. - Supports `localized: true` — requires [[wiki/payloadcms/localization|localization enabled]] in root config. - Built-in **Slug Field** (`slugField()`) is available from `payload` — auto-generates URL-safe slugs from another field, with lock/unlock UI and re-generate button. ## Config Options | Option | Description | |--------|-------------| | `name` * | DB property name | | `label` | Admin Panel label (string or `{ [lang]: string }`) | | `unique` | DB-level unique index | | `minLength` / `maxLength` | Character length validation | | `validate` | Custom validation function (runs client + server) | | `index` | Build a DB index for faster queries | | `saveToJWT` | Include in user JWT (top-level auth fields only) | | `hooks` | Field lifecycle hooks | | `access` | Field-level access control | | `hidden` | Remove from all APIs; still saved to DB | | `defaultValue` | Default value or function | | `localized` | Per-locale string values | | `required` | Non-empty validation | | `hasMany` | Store as ordered string array | | `minRows` / `maxRows` | Array bounds when `hasMany: true` | | `virtual` | Disable DB column (boolean) or link to relationship (path string) | | `typescriptSchema` | Override generated TS type with JSON schema | ## Admin Options Extends the base [[wiki/payloadcms/fields-overview|field admin config]] with: | Option | Description | |--------|-------------| | `placeholder` | Placeholder string in the text input | | `autoComplete` | Browser autocomplete attribute value | | `rtl` | Force right-to-left text direction (`true`) | ## hasMany Mode ```ts { name: 'tags', type: 'text', hasMany: true, minRows: 1, maxRows: 10, } ``` Stores an ordered array of strings. Each value is a separate DB entry; the order is preserved. ## Built-in Slug Field Import `slugField` from `payload` to get an auto-generating slug with lock UI: ```ts import { slugField } from 'payload' export const PagesCollection: CollectionConfig = { slug: 'pages', fields: [ { name: 'title', type: 'text' }, slugField(), // defaults: name='slug', useAsSlug='title' ], } ``` ### Slug Config Options | Option | Default | Description | |--------|---------|-------------| | `name` | `'slug'` | Field name | | `useAsSlug` | `'title'` | Source field to generate slug from | | `checkboxName` | `'generateSlug'` | Lock/unlock checkbox field name | | `disableUnique` | `false` | Disable unique index (useful for multi-tenant slugs) | | `localized` | `false` | Localize both slug and checkbox fields | | `required` | `true` | Require the slug field | | `overrides` | — | Function to modify default field definitions | | `slugify` | — | Override default slugify function | | `position` | — | Admin Panel position | ### Custom Slugify Function ```ts import slugify from 'slugify' slugField({ slugify: ({ valueToSlugify, data, req }) => slugify(valueToSlugify, { lower: true, strict: true }), }) ``` > **Warning:** The built-in Slug Field is **experimental** and may change or be removed in future releases. ## Custom Components Payload supports custom Server and Client Components for both the Field and Label slots. Import base components from `@payloadcms/ui` and wrap them. ```tsx // Server Field component import { TextField } from '@payloadcms/ui' import type { TextFieldServerComponent } from 'payload' export const CustomTextField: TextFieldServerComponent = ({ clientField, path, schemaPath, permissions, }) => ( ) ``` See [[wiki/payloadcms/custom-components-authoring|Custom Components — Authoring Guide]] for RSC vs Client rules and Import Map details. ## Related Articles - [[wiki/payloadcms/fields-overview|Fields Overview]] — shared config: virtual, validation, defaultValue, admin options - [[wiki/payloadcms/fields-email|Email Field]] — text variant with built-in format validation - [[wiki/payloadcms/fields-number|Number Field]] — numeric equivalent with `hasMany` support - [[wiki/payloadcms/fields-select|Select Field]] — enum dropdown (use when values are constrained) - [[wiki/payloadcms/database-indexes|Database Indexes]] — `unique` and `index` gotchas - [[wiki/payloadcms/authentication-token-data|Authentication — Token Data]] — `saveToJWT` pattern - [[wiki/payloadcms/localization|Localization]] — enabling `localized` fields - [[wiki/payloadcms/custom-components-authoring|Custom Components — Authoring Guide]] --- *Source: raw/fields__text.md — https://payloadcms.com/docs/fields/text*