---
title: "Radio Field"
aliases: [radio-group-field, payload-radio]
tags: [payloadcms, fields, radio, admin-ui]
sources: [raw/fields__radio.md]
created: 2026-05-15
updated: 2026-05-15
---

## Overview

The Radio Field allows selecting **one value** from a predefined set of options. Renders as a radio group in the Admin Panel.

```ts
import type { Field } from 'payload'

export const MyRadioField: Field = {
  name: 'color',
  type: 'radio',
  options: [
    { label: 'Mint', value: 'mint' },
    { label: 'Dark Gray', value: 'dark_gray' },
  ],
  defaultValue: 'mint',
}
```

## Config Options

| Option | Required | Description |
|--------|----------|-------------|
| `name` | Yes | DB property name |
| `options` | Yes | Array of strings or `{ label, value }` objects |
| `defaultValue` | — | Must match one of the option values |
| `label` | — | Field label in Admin Panel |
| `validate` | — | Custom validation function (runs on client + backend) |
| `index` | — | Add DB index for faster queries |
| `enumName` | — | Custom enum name for Postgres (auto-generated if omitted) |
| `interfaceName` | — | Creates a reusable TypeScript interface + GraphQL type |
| `saveToJWT` | — | Include value in user JWT (top-level auth collections) |
| `localized` | — | Enable per-locale values |
| `required` | — | Field must have a value |
| `hidden` | — | Hidden from all APIs + Admin Panel; still saved to DB |
| `virtual` | — | Exclude from DB (pass `true`) or link to relationship (pass path string) |
| `hooks` | — | Field hooks |
| `access` | — | Field-level access control |
| `admin` | — | Admin-specific options (see below) |
| `custom` | — | Extension point for plugins |
| `typescriptSchema` | — | Override generated TypeScript type with JSON schema |

## Admin Options

Inherits all base [[wiki/payloadcms/fields-overview|Field Admin Config]] options, plus:

| Property | Description |
|----------|-------------|
| `layout` | `'horizontal'` (default) or `'vertical'` — controls radio group orientation |

```ts
admin: {
  layout: 'horizontal', // or 'vertical'
}
```

## Option Values — Constraints

> **Warning:** Option values must be strings **without hyphens or special characters** due to GraphQL enum naming rules. Underscores are allowed.

- Bad: `'dark-gray'`, `'option.one'`
- Good: `'dark_gray'`, `'option_one'`
- Non-string values or values with special characters will be formatted automatically before use as a GraphQL enum — results may be unexpected.

## Custom Components

### Field Component

**Server:**
```tsx
import { RadioGroupField } from '@payloadcms/ui'
import type { RadioFieldServerComponent } from 'payload'

export const CustomRadioFieldServer: RadioFieldServerComponent = ({
  clientField, path, schemaPath, permissions,
}) => <RadioGroupField field={clientField} path={path} schemaPath={schemaPath} permissions={permissions} />
```

**Client:**
```tsx
'use client'
import { RadioGroupField } from '@payloadcms/ui'
import type { RadioFieldClientComponent } from 'payload'

export const CustomRadioFieldClient: RadioFieldClientComponent = (props) =>
  <RadioGroupField {...props} />
```

### Label Component

```tsx
import { FieldLabel } from '@payloadcms/ui'
import type { RadioFieldLabelServerComponent } from 'payload'

export const CustomRadioFieldLabelServer: RadioFieldLabelServerComponent = ({
  clientField, path,
}) => <FieldLabel label={clientField?.label || clientField?.name} path={path} required={clientField?.required} />
```

## Key Takeaways

- Radio stores a **single string value** — use [[wiki/payloadcms/fields-checkbox|Checkbox]] for boolean, [[wiki/payloadcms/fields-basic|Select]] for dropdown multi-select
- `options` can be plain strings or `{ label, value }` objects — prefer objects for i18n labels
- Option values **must not contain hyphens** — GraphQL enum constraint; use underscores instead
- `defaultValue` must be one of the defined option values, not an arbitrary string
- `admin.layout: 'horizontal'` (default) or `'vertical'` controls the visual arrangement
- `enumName` (Postgres) lets you control the generated enum name; auto-generated from `name` otherwise
- `interfaceName` creates a reusable TS interface and GraphQL type — useful for shared option sets

## Sources

- `raw/fields__radio.md` — Payload CMS official docs: https://payloadcms.com/docs/fields/radio
