Portal Community

Minimal Example

{
  "id": "attachment",
  "type": "file-upload",
  "label": "Attach Documents",
  "width": "full",
  "settings": {
    "accept": ["application/pdf", "image/jpeg", "image/png"],
    "maxSizeMb": 10
  }
}

Settings Reference

SettingTypeDefaultDescription
acceptstring[]all typesAllowed MIME types (e.g., "application/pdf") or extensions (e.g., ".pdf")
maxSizeMbnumber10Maximum file size in megabytes per file
multiplebooleanfalseAllow selection of multiple files at once
maxFilesnumberMaximum total files when multiple: true
uploadUrlstringEndpoint for immediate upload on file selection
uploadMethodPOST | PUTPOSTHTTP method for the upload request
uploadHeadersRecord<string,string>Additional HTTP headers for the upload request
showPreviewbooleantrueShow thumbnail preview for images after selection
dragDropbooleantrueEnable drag-and-drop file selection
dropZoneTextstring"Drop files here or click to browse"Custom text for the drop zone

File Type Filtering

Use MIME types or file extensions in accept. Both formats are supported:

// MIME types (preferred)
"accept": ["application/pdf", "image/jpeg", "image/png", "image/gif"]

// File extensions
"accept": [".pdf", ".jpg", ".jpeg", ".png"]

// Mixed (both work together)
"accept": ["application/pdf", ".docx", ".xlsx"]

// Wildcard groups
"accept": ["image/*", "application/pdf"]

Multiple File Upload

{
  "id": "supporting-docs",
  "type": "file-upload",
  "label": "Supporting Documentation",
  "description": "Attach up to 5 supporting documents (PDF, images, max 5MB each)",
  "width": "full",
  "settings": {
    "multiple": true,
    "maxFiles": 5,
    "accept": ["application/pdf", "image/*"],
    "maxSizeMb": 5,
    "showPreview": true,
    "dropZoneText": "Drop documents here or click to browse"
  }
}

Upload Behaviour

Files are handled in one of two ways depending on configuration:

ModeConfigurationBehaviour
Immediate uploaduploadUrl is setFile is uploaded to the endpoint as soon as it is selected. Progress bar shown. On success, the file reference (URL/ID) is stored in the form.
Deferred uploadNo uploadUrlFile is held in the browser until form submission. The submit action handler receives the File object in formValues and is responsible for uploading.

Immediate Upload with Progress

{
  "id": "profile-photo",
  "type": "file-upload",
  "label": "Profile Photo",
  "width": "half",
  "settings": {
    "accept": ["image/jpeg", "image/png", "image/webp"],
    "maxSizeMb": 2,
    "multiple": false,
    "showPreview": true,
    "uploadUrl": "/api/v1/files/upload",
    "uploadMethod": "POST",
    "uploadHeaders": {
      "X-Upload-Context": "profile-photo"
    }
  }
}

// On successful upload, the control stores:
// { fileId: "abc123", url: "https://cdn.example.com/photos/abc123.jpg", name: "photo.jpg", size: 45321 }

Deferred Upload in Submit Handler

// Form schema — no uploadUrl
{
  "id": "contract-pdf",
  "type": "file-upload",
  "label": "Signed Contract (PDF)",
  "settings": {
    "accept": ["application/pdf"],
    "maxSizeMb": 20
  }
}

// Submit action handler
export const submitWithFileHandler = async (ctx: FormActionContext) => {
  const file = ctx.formValues['contract-pdf'] as File | null;

  if (file) {
    const formData = new FormData();
    formData.append('contract', file);
    const uploadRes = await fetch('/api/v1/contracts/upload', {
      method: 'POST',
      body: formData
    });
    const { fileId } = await uploadRes.json();

    // Submit the rest of the form with the file reference
    await ctx.apiClient.post('/api/v1/submissions', {
      ...ctx.formValues,
      contractFileId: fileId
    });
  }

  ctx.complete();
};

Validation

File upload validation is performed client-side before upload or submission:

ValidationError Message
File type not in accept"File type not allowed. Accepted: PDF, JPEG, PNG"
File exceeds maxSizeMb"File too large. Maximum size: 10 MB"
Number of files exceeds maxFiles"Maximum 5 files allowed"
required: true and no file selected"Please attach at least one file"
File Upload and Data Binding File upload controls do not use the standard binding property. After upload, the file reference is stored in the form engine under the control's id, accessible in action handlers via ctx.formValues['control-id']. For immediate uploads, this is the server response object; for deferred, it is the browser File object.