Fields

Upload Field

The upload field references a document in an upload-enabled collection (such as "media" or "documents"). It renders an upload widget in the admin UI that supports drag-and-drop, file browsing, and previews. Use this field for file attachments, downloadable resources, or any file that should be managed through the upload system.

The underlying Convex validator is v.string() for single uploads or v.array(v.string()) for multiple, wrapped in v.optional() unless marked as required. The stored value is the document ID of the upload record.

Config options

OptionTypeRequiredDefaultDescription
relationTostring*Slug of the upload collection to reference (e.g., "media")
requiredbooleanfalseMakes the field required in the schema and admin UI
readOnlybooleanfalseRenders the field as non-editable
placeholderstringPlaceholder text for the upload area
labelstring | functionField nameCustom label for the admin UI
descriptionstringHelp text displayed below the field label
mimeTypesstring[]Accepted MIME types (e.g., ["application/pdf", "text/csv"])
maxFileSizenumberMaximum file size in bytes
displayPreviewbooleantrueShow a thumbnail or file icon preview
hasManybooleanfalseAllow multiple file uploads
conditionFieldConditionCondition for showing or hiding 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 resources = defineVextroCollection({
  slug: "resources",
  label: "Resources",
  collectionType: "content",
  tableName: "resources",
  fields: {
    title: f.text({ required: true }),
    document: f.upload({
      relationTo: "documents",
      required: true,
      mimeTypes: ["application/pdf"],
      maxFileSize: 10 * 1024 * 1024,
      label: "PDF Document",
      description: "Upload a PDF file (max 10 MB)",
    }),
    spreadsheet: f.upload({
      relationTo: "documents",
      mimeTypes: ["text/csv", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],
      label: "Data File",
    }),
    attachments: f.upload({
      relationTo: "media",
      hasMany: true,
      label: "Attachments",
      description: "Upload one or more files",
    }),
  },
});

Admin options

The upload widget supports drag-and-drop file selection and displays a file browser for the referenced upload collection. When mimeTypes is configured, the file input restricts selectable file types and rejects non-matching uploads with an error.

The maxFileSize option is validated client-side before upload begins. Files exceeding the limit are rejected with a clear error message showing the maximum allowed size.

When displayPreview is true (the default), uploaded files show a thumbnail for images or a file-type icon for other formats. Set to false to display only the filename and metadata.

Conditional display

resume: f.upload({
  relationTo: "documents",
  mimeTypes: ["application/pdf"],
  label: "Resume",
  condition: { field: "applicationType", equals: "employment" },
})
Previous
Relationship
Next
Image