Components

File upload

Help users select and upload a file.

See the GOV.UK Design System documentation on file uploads for more information on when to use this component.

<gv-file-upload label="Upload a file"/>

Using v-model with file upload

If you bind a ref with v-model, that ref will be updated to contain a FileList of the selected files whenever the user changes their selection.

You can then use a FileReader to read the file metadata and contents - for example, if you want to upload the file immediately via fetch() or show a preview of the file.

Note that you can't update the model to change the list of files selected. However, you can set the model to null to deselect all files.

For example, a .jpg or .png file
Your selected image will appear here
<script setup lang="ts">
import { ref, watch } from 'vue'

const files = ref(null)
const fileDataUrl = ref('')

watch(files, () => {
  if (files.value && files.value.length > 0) {
    const file = files.value[0]
    let reader = new FileReader()

    reader.readAsDataURL(file)

    reader.onload = () => {
      fileDataUrl.value = reader.result
    }
  } else {
    fileDataUrl.value = null;
  }
})

function resetFileInput() {
  files.value = null;
}
</script>
<template>
  <gv-file-upload
  label="Upload an image"
  hint="For example, a .jpg or .png file"
  v-model="files"
  accept="image/png, image/jpeg"
  />
  <gv-inset-text aria-live="polite">
    <template v-if="fileDataUrl">
      <p class="govuk-body">Your image:</p>
      <p class="govuk-body">
        <img :src="fileDataUrl" style="max-width: 100%" alt="The image you uploaded"/>
      </p>
      <gv-button @click="resetFileInput">Reset file input</gv-button>
    </template>
    <template v-else>
      Your selected image will appear here
    </template>
  </gv-inset-text>
</template>

Props

NameTypeDescription
modelValue null
Will be set to a FileList containing the selected files when the user changes their selection. In most cases you should use v-model instead of setting this prop directly.
id string
The ID of the input. If you don't provide an ID, one will be generated automatically.
name string
The name of the input, which is submitted with the form data.
describedBy string
One or more element IDs to add to the aria-describedby attribute, used to provide additional descriptive information for screenreader users.
accept string
A comma-separated list of filetypes to accept. See the accept attribute on MDN.
multiple boolean
If true, the user will be allowed to select multiple files

Defaults to false.
formGroupClass string|array|object
Classes to add to the form group. You can bind a string, an array or an object, as with normal Vue class bindings.
label string
Text to use within the label. If content is provided in the label slot, this prop will be ignored.
labelIsPageHeading boolean
Whether the label also acts as the heading for the page.

Defaults to false.
labelClass string|array|object
Classes to add to the label tag. You can bind a string, an array or an object, as with normal Vue class bindings.
hint string
Text to use within the hint. If content is provided in the hint slot, this prop will be ignored.
hintClass string|array|object
Classes to add to the hint span tag. You can bind a string, an array or an object, as with normal Vue class bindings.
errorMessage string
Text to use within the error message. If content is provided in the error-message slot, this prop will be ignored.
errorMessageClass string|array|object
Classes to add to the error message <p> tag. You can bind a string, an array or an object, as with normal Vue class bindings.
errorMessageVisuallyHiddenText string
A visually hidden prefix used before the error message. Defaults to 'Error'.

Slots

NameDescription
label
The content of the label. If content is provided in this slot, the label prop will be ignored.
hint
The content of the hint. If content is provided in this slot, the hint prop will be ignored.
error-message
The content of the error message. If content is provided in this slot, the errorMessage prop will be ignored.