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
| Option | Type | Default | Description |
|---|---|---|---|
required | boolean | false | Makes 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. |
readOnly | boolean | false | Renders the radio group as disabled. |
label | string | (data) => string | Auto-generated | Custom label for the admin UI. |
description | string | — | Help text displayed below the label. |
condition | FieldCondition | — | Conditionally show or hide this field. |
sidebar | boolean | false | Place this field in the document sidebar. |
listColumn | boolean | false | Show 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.