Fields

Radio Field

The radio field renders a group of radio buttons in the admin UI and stores the selected value as a string in Convex. It is a visual alternative to the select field, best suited for single-choice fields with two to five options where all choices should be visible at once. The validator is a v.union() of v.literal() values, wrapped in v.optional() when the field is not required.

Config options

OptionTypeDefaultDescription
requiredbooleanfalseMakes the field required in both the schema and the admin UI.
options *Array<string | { label: string; value: string }>—The available choices. Can be plain strings or label/value objects.
layout"horizontal" | "vertical""vertical"Direction the radio buttons are laid out.
readOnlybooleanfalseRenders the radio group as disabled.
labelstring | (data) => stringAuto-generatedCustom label for the admin UI.
descriptionstring—Help text displayed below the label.
conditionFieldCondition—Conditionally show or hide this field.
sidebarbooleanfalsePlace this field in the document sidebar.
listColumnbooleanfalseShow as a default column in list views.

Example usage

import { f, defineVextroCollection } from "vextro";

export const surveys = defineVextroCollection({
  slug: "surveys",
  label: "Surveys",
  collectionType: "content",
  tableName: "surveys",
  fields: {
    question: f.text({ required: true }),
    difficulty: f.radio({
      required: true,
      options: [
        { label: "Easy", value: "easy" },
        { label: "Medium", value: "medium" },
        { label: "Hard", value: "hard" },
      ],
    }),
    visibility: f.radio({
      options: ["public", "private"],
      layout: "horizontal",
      sidebar: true,
      sidebarSection: "document",
    }),
  },
});

Admin behavior

The radio field renders a group of <input type="radio"> elements. In "vertical" layout (the default), options are stacked top to bottom. In "horizontal" layout, options are displayed in a row. Each option shows its label text next to the radio button. When readOnly is true, all radio buttons are disabled but the selected value remains visible.

Radio fields do not support the placeholder option because all choices are always visible.

When to use radio vs. select

Use radio when you have a small number of options (2-5) and want all choices visible without opening a dropdown. Use select when you have more than five options or when screen space is limited.

Conditional display

responseType: f.radio({
  options: ["approve", "reject"],
  layout: "horizontal",
  required: true,
  condition: { field: "status", equals: "pending" },
}),

When a condition is set, the field is always optional in the Convex schema regardless of the required setting.

Previous
Select
Next
Checkbox