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
| Option | Type | Default | Description |
|---|---|---|---|
type | "text" | "number" | "url" | "json" | "datetime" | required | Display type for rendering |
compute | string | — | Name of a registered server-side compute function |
label | string | — | Display label |
description | string | — | Description shown below the label |
condition | FieldCondition | — | 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
| Type | Renders as |
|---|---|
text | Plain text string |
number | Formatted number |
url | Clickable link |
json | Formatted JSON viewer |
datetime | Formatted 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.