Fields

Virtual Field

The virtual field displays a computed value that is not stored in the database. Virtual fields are always read-only and are calculated server-side using a registered compute function. They are useful for showing derived values like full names, computed URLs, or aggregated counts.

Config Options

OptionTypeDefaultDescription
type"text" | "number" | "url" | "json" | "datetime"requiredDisplay type for rendering
computestring—Name of a registered server-side compute function
labelstring—Display label
descriptionstring—Description shown below the label
conditionFieldCondition—Condition for showing this field

Example Usage

import { f } from "vextro";

const fields = {
  firstName: f.text({ required: true }),
  lastName: f.text({ required: true }),
  slug: f.slug({ required: true }),

  fullName: f.virtual({
    type: "text",
    compute: "computeFullName",
    label: "Full Name",
  }),
  profileUrl: f.virtual({
    type: "url",
    compute: "computeProfileUrl",
    description: "Auto-generated from slug",
  }),
  totalOrders: f.virtual({
    type: "number",
    compute: "computeOrderCount",
    label: "Total Orders",
  }),
};

Display Types

TypeRenders as
textPlain text string
numberFormatted number
urlClickable link
jsonFormatted JSON viewer
datetimeFormatted date and time

Compute Functions

The compute option references a named function registered on the server. It receives the document and a query context, and can be synchronous or asynchronous:

registerCompute("computeFullName", (doc) =>
  `${doc.firstName} ${doc.lastName}`
);

No stored data

Virtual fields do not create a column in the Convex table. They are excluded from import/export and search indexing.

Previous
Join
Next
UI