Components
customfileupload
Standard citizen document upload. The file is encoded as base64 and sent inline as part of the application payload on submission.
Standard citizen document upload. The file is encoded as base64 and sent inline as part of the application payload on submission.
Read Form Rules before using this component — keys, labels, required fields, expressions, visibility, and validation all follow shared conventions.
When to use
- Uploading attachments that must travel with the form data (ID scans, certificates, supporting documents)
- The file does not need to be pre-uploaded to a CDN before submission
- No external integration endpoint is involved in the upload
When NOT to use
Instead of customfileupload, use… | For… |
|---|---|
custominternalfileupload | Large or sensitive documents that should be pre-uploaded to the CDN — sending them as base64 inline bloats the application payload |
externalfileupload | Files that must be pushed directly to an external system via an integration endpoint at upload time |
Props
| Prop | Type | Required? | Description |
|---|---|---|---|
label | string | required | Visible label. Must be unique across the form. |
required | boolean | required | Always false. The expression controls the runtime value. |
defaultRequired | boolean | required | true for required fields, false for optional ones. |
allowedFormats | array | required | Accepted file extensions in lowercase (e.g. ["pdf", "jpg", "jpeg", "png"]). Do not include uppercase variants — the check is case-insensitive. |
maximumUploadSize | number | required | Maximum file size in KB (e.g. 1024 = 1 MB, 500 = 500 KB). |
minimumUploadSize | number | optional | Minimum file size in KB. Use 1 to prevent empty files. |
placeholder | string | optional | Text shown on the upload button. |
hint | string | optional | Help text below the field — use for format/size guidance. |
hideField | boolean | optional | Hides the field and excludes its value. Toggle via expressions["props.hideField"]. |
Validation messages
| Key | When required | Notes |
|---|---|---|
required | Always | |
invalidfileformat | Always | State the field name and accepted formats. |
maximumUploadSize | Always | State the field name and size limit. |
minimumUploadSize | When minimumUploadSize is set |
Examples
PDF only
{
"key": "DEATH_CERTIFICATE",
"type": "customfileupload",
"props": {
"label": "Death Certificate",
"placeholder": "Select file to upload",
"required": false,
"defaultRequired": true,
"allowedFormats": ["pdf"],
"maximumUploadSize": 1024
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "This field is required.",
"invalidfileformat": "Only PDF files are allowed.",
"maximumUploadSize": "File must be smaller than 1 MB."
}
}
}Multiple image formats with hint
{
"key": "APPLICANT_PHOTO",
"type": "customfileupload",
"props": {
"label": "Applicant Photo",
"placeholder": "Select file to upload",
"required": false,
"defaultRequired": true,
"allowedFormats": ["jpg", "jpeg", "png"],
"maximumUploadSize": 2048,
"minimumUploadSize": 1,
"hint": "Upload a recent passport-size photo. JPG or PNG, max 2 MB."
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "This field is required.",
"invalidfileformat": "Only JPG and PNG files are allowed.",
"maximumUploadSize": "Photo must be 2 MB or smaller.",
"minimumUploadSize": "File size must be at least 1 KB."
}
}
}Common mistakes
- Setting
maximumUploadSizein bytes or MB — the prop is always in KB. - Including uppercase variants in
allowedFormats(e.g.["pdf", "PDF"]) — redundant; use lowercase only. - Omitting
allowedFormats— the component accepts any file type; always restrict explicitly. - Using
customfileuploadfor large documents — usecustominternalfileupload(CDN pre-upload) to avoid bloating the payload. - Using
customfileuploadwhen the file must be pushed to an external endpoint — useexternalfileuploadinstead.
Checklist
-
keyisUPPER_SNAKE_CASEand unique across the entire form -
props.labelis present, unique, and correctly cased - Field is nested at the correct depth:
sections > formly-group > block > customfileupload -
required: falseis set (nevertrue) -
defaultRequiredis set -
expressions["props.required"]is present with the exact required expression -
allowedFormatsis lowercase only -
maximumUploadSizeis in KB -
validation.messageshasrequired,invalidfileformat, andmaximumUploadSize - Confirmed the file should travel as base64 inline — if not, use
custominternalfileupload