X Enterprises
Composables

useXFileUpload

File upload composable with progress tracking, MIME/size validation, preview URLs, and drag-and-drop state.

useXFileUpload

Handles all client-side file upload concerns: drag-and-drop event wiring, file validation (type, size), upload progress, and preview URL generation. Works with a native <input type="file"> or the XAFileUpload and XADocumentUpload components that consume it internally.

Usage

const {
  files,
  previews,
  progress,
  uploading,
  error,
  isDragging,
  add,
  remove,
  upload,
  reset,
  onDragOver,
  onDrop,
} = useXFileUpload({ accept: ["image/*"], maxSizeMb: 5 })

Returns

KeyTypeDescription
filesRef<File[]>Currently queued files awaiting upload.
previewsRef<string[]>Object URL previews corresponding to each queued file.
progressRef<number>Upload progress 0–100.
uploadingRef<boolean>true while an upload is in progress.
errorRef<string | null>Validation or upload error message.
isDraggingRef<boolean>true when a drag is active over the drop zone.
add(fileList: FileList | File[]) => voidValidates and adds files to the queue.
remove(index: number) => voidRemoves a queued file by index and revokes its preview URL.
upload(endpoint: string) => Promise<unknown>POSTs queued files as multipart/form-data to the given endpoint.
reset() => voidClears the queue, previews, progress, and error.
onDragOver(event: DragEvent) => voidDrag-over handler to attach to the drop zone element.
onDrop(event: DragEvent) => voidDrop handler that extracts files from the drag event and calls add.

Example

const { files, previews, uploading, progress, add, upload, onDragOver, onDrop } =
  useXFileUpload({ accept: ["image/png", "image/jpeg"], maxSizeMb: 10 })

async function handleSubmit() {
  await upload("/api/avatars")
}
<div
  :class="{ 'ring-2 ring-primary': isDragging }"
  @dragover.prevent="onDragOver"
  @drop.prevent="onDrop"
>
  <img v-for="(src, i) in previews" :key="i" :src="src" />
  <UButton :loading="uploading" @click="handleSubmit">Upload</UButton>
  <UProgress v-if="uploading" :value="progress" />
</div>

AI Context

composable: useXFileUpload
package: "@xenterprises/nuxt-x-app"
use-when: >
  Any surface requiring file selection or drag-and-drop upload — avatar pickers,
  document attachments, bulk import flows. Handles validation, previewing, and
  multipart submission so the component stays thin.
pairs-with: XAFileUpload, XADocumentUpload, XAAvatarUpload, XAFormFileUpload
Copyright © 2026