File upload
Lets users attach a file, such as a supporting document.
On this page
Preview
import { useState } from 'react';
import { FileUpload } from '@govtech-bb/react';
const [files, setFiles] = useState<File[]>([]);
<FileUpload
label="Proof of address"
description="This could be a recent utility bill or bank statement"
name="proof-of-address"
subtitle="Attach a .pdf, .docx, or .png file"
maxSize="Maximum size: 25MB"
onChange={(event) => setFiles(Array.from(event.currentTarget.files ?? []))}
files={files.map((file, index) => ({
name: file.name,
onRemove: () =>
setFiles((current) =>
current.filter((_, itemIndex) => itemIndex !== index),
),
}))}
/>;<div class="govbb-form-group">
<label class="govbb-label" id="proof-of-address-label" for="proof-of-address"
>Proof of address</label
>
<span class="govbb-hint" id="proof-of-address-description">
This could be a recent utility bill or bank statement
</span>
<div class="govbb-file-upload" data-govbb-module="file-upload">
<label class="govbb-file-upload__dropzone" for="proof-of-address">
<span class="govbb-file-upload__info">
<span class="govbb-file-upload__title">Upload a file</span>
<span class="govbb-file-upload__subtitle"
>Attach a .pdf, .docx, or .png file</span
>
</span>
<input
class="govbb-file-upload__input govbb-visually-hidden"
id="proof-of-address"
name="proof-of-address"
type="file"
aria-labelledby="proof-of-address-label"
aria-describedby="proof-of-address-description"
/>
<span class="govbb-file-upload__action">
<span class="govbb-button govbb-button--tertiary" aria-hidden="true"
>Choose file</span
>
<span class="govbb-file-upload__max-size">Maximum size: 25MB</span>
</span>
</label>
<ul class="govbb-file-upload__list">
<li class="govbb-file-upload__item">
<span class="govbb-file-upload__name">proof-of-address.pdf</span>
<button
type="button"
class="govbb-button govbb-button--text govbb-button--negative"
aria-label="Remove proof-of-address.pdf"
>
Remove
</button>
</li>
</ul>
</div>
</div>The File Upload component lets users attach a file, such as a supporting document or a photo of an ID. The whole dropzone acts as the label, so clicking anywhere inside it opens the file picker, and uploaded files stay visible in a list so users can confirm what they attached.
Usage
When to use
- Use file upload only when a document is necessary to complete the service.
- Use it for evidence that cannot be entered, declared or verified another way.
When not to use
- Do not request optional documents “just in case”.
- Do not require a file format or size that creates unnecessary software, connectivity or data costs.
Best practices
Explain restrictions before users choose a file
State the accepted file types, maximum size and whether more than one file is
allowed in hint text. Use the accept attribute to narrow the system file
picker, but validate the file again on the server.
Prefer one document per input
One clearly labelled input per document is easier to understand than a single multi-file picker. Let users see what they selected, remove the wrong file and reuse an upload within the same journey where it is safe to do so.
Guidance
State the accepted file types and the maximum size up front, in the subtitle and
the .govbb-file-upload__max-size text: users should not have to guess and
fail. Keep uploaded files visible in the list (.govbb-file-upload__list) so
users can confirm what they attached, and give each one a Remove action so
they can correct a mistake without starting over.
Pair the dropzone with a .govbb-form-group, a visible .govbb-label naming
what to upload, and a .govbb-hint giving an example, such as “This could be a
recent utility bill or bank statement”.
Errors
When an upload fails or a file is rejected, set aria-invalid="true" on the
input and show an error message (.govbb-error-message) with role="alert",
linked to the input with aria-describedby. Keep the message specific, such as
“Select a file” or “The file must be smaller than 25MB”.
import { FileUpload } from '@govtech-bb/react';
<FileUpload
label="Proof of address"
error="Select a file"
name="proof-of-address"
subtitle="Attach a .pdf, .docx, or .png file"
maxSize="Maximum size: 25MB"
/>;<div class="govbb-form-group">
<label class="govbb-label" id="proof-of-address-label" for="proof-of-address"
>Proof of address</label
>
<span class="govbb-error-message" id="proof-of-address-error" role="alert">
Select a file
</span>
<div class="govbb-file-upload" data-govbb-module="file-upload">
<label class="govbb-file-upload__dropzone" for="proof-of-address">
<span class="govbb-file-upload__info">
<span class="govbb-file-upload__title">Upload a file</span>
<span class="govbb-file-upload__subtitle"
>Attach a .pdf, .docx, or .png file</span
>
</span>
<input
class="govbb-file-upload__input govbb-visually-hidden"
id="proof-of-address"
name="proof-of-address"
type="file"
aria-invalid="true"
aria-labelledby="proof-of-address-label"
aria-describedby="proof-of-address-error"
/>
<span class="govbb-file-upload__action">
<span class="govbb-button govbb-button--tertiary" aria-hidden="true"
>Choose file</span
>
<span class="govbb-file-upload__max-size">Maximum size: 25MB</span>
</span>
</label>
</div>
</div>