Fields

Select Field

The select field renders a dropdown menu in the admin UI. In single mode it stores a string, and in multi-select mode it stores a string[]. Each option generates a v.literal() validator, combined with v.union() to form a type-safe enum. Use it for statuses, categories, tags, and any field with a fixed set of choices.

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.
multiplebooleanfalseAllow selecting more than one option. Stores an array instead of a single value.
readOnlybooleanfalseRenders the select as disabled.
placeholderstring—Placeholder text shown when no option is selected.
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 articles = defineVextroCollection({
  slug: "articles",
  label: "Articles",
  collectionType: "content",
  tableName: "articles",
  fields: {
    title: f.text({ required: true }),
    status: f.select({
      required: true,
      options: ["draft", "published", "scheduled", "trashed"],
      sidebar: true,
      sidebarSection: "document",
      listColumn: true,
      listColumnWidth: "small",
    }),
    category: f.select({
      options: [
        { label: "News & Updates", value: "news" },
        { label: "Tutorials", value: "tutorial" },
        { label: "Case Studies", value: "case-study" },
      ],
      placeholder: "Choose a category...",
    }),
    tags: f.select({
      options: ["featured", "trending", "editors-pick", "breaking"],
      multiple: true,
      description: "Select one or more tags.",
    }),
  },
});

Admin behavior

In single mode, the select field renders a custom dropdown component. In multi-select mode (multiple: true), it renders a multi-select input that displays selected values as removable pills. Options defined as { label, value } objects display the label in the UI while storing the value in the database.

Convex validator mapping

The validator is built from the options array. For a single select with options ["draft", "published"], the generated validator is v.union(v.literal("draft"), v.literal("published")). For multi-select, it wraps that union in v.array().

Conditional display

archiveReason: f.select({
  options: ["outdated", "duplicate", "off-topic", "other"],
  required: true,
  condition: { field: "status", equals: "trashed" },
}),

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

Previous
Slug
Next
Radio