---
title: "MazDropzone"
description: "MazDropzone is a powerful and flexible file upload component with drag & drop support, progress tracking, and customizable UI. Perfect for handling single or multiple file uploads in your Vue applications."
package: "maz-ui"
url: "https://maz-ui.com/components/maz-dropzone"
---

# MazDropzone

> MazDropzone is a powerful and flexible file upload component with drag & drop support, progress tracking, and customizable UI. Perfect for handling single or multiple file uploads in your Vue applications.

- Package: `maz-ui`
- Import: `import MazDropzone from 'maz-ui/components/MazDropzone'`
- Nuxt: auto-imported by `@maz-ui/nuxt`, no import needed in a Nuxt app
- Web: https://maz-ui.com/components/maz-dropzone

> Before use it, you should install the MazUi plugin in your project, follow instructions in [Getting Started](../guide/getting-started.md)

**Tip:**

This component can be translated globally using the [MazUi](https://maz-ui.com/ecosystem/translations.md) plugin.

## Key Features

- 🎯 Drag & drop support
- 📁 Single or multiple file uploads
- 🖼️ Image preview thumbnails
- 🚀 Auto upload support
- ⚡ Async file processing
- 🎨 Fully customizable UI
- 🌐 Support for various file types
- ⚙️ Extensive configuration options
- 🔒 File validation (size, type, count)
- 🌍 Internationalization support

## Error codes

| Error Code                   | Description                              | Trigger                                                                                  |
| ---------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------- |
| `FILE_SIZE_EXCEEDED`         | File size exceeds the allowed limit      | When a file is larger than `maxFileSize` (in MB)                                         |
| `FILE_SIZE_TOO_SMALL`        | File size is below the minimum limit     | When a file is smaller than `minFileSize` (in MB)                                        |
| `MAX_FILES_EXCEEDED`         | Maximum number of allowed files exceeded | When trying to add more files than `maxFiles` or more than 1 file if `multiple=false`    |
| `FILE_TYPE_NOT_ALLOWED`      | File type is not allowed                 | When the file's MIME type doesn't match the specified `dataTypes`                        |
| `FILE_DUPLICATED`            | An identical file already exists         | When `allowDuplicates=false` and a file with the same name, size and type already exists |
| `NO_FILES_TO_UPLOAD`         | No files to upload                       | When starting upload but there are no files in the dropzone                              |
| `FILE_UPLOAD_ERROR`          | Error during individual file upload      | When uploading a specific file fails (`single` mode)                                     |
| `FILE_UPLOAD_ERROR_MULTIPLE` | Error during batch upload                | When uploading multiple files fails (`multiple` mode)                                    |
| `NO_URL`                     | No upload URL configured                 | When attempting auto-upload without defining the `url` prop                              |

### Error handling example

**Details: View code**

```vue
<script setup>
function handleError({ code, files }) {
  switch (code) {
    case 'FILE_SIZE_EXCEEDED':
      console.log('File too large:', files[0].name)
      break
    case 'FILE_TYPE_NOT_ALLOWED':
      console.log('File type not allowed:', files[0].type)
      break
    case 'MAX_FILES_EXCEEDED':
      console.log('Too many files selected')
      break
      // ...
  }
}
</script>

<template>
  <MazDropzone
    :max-file-size="5"
    :max-files="3"
    :data-types="['image/*', 'application/pdf']"
    :allow-duplicates="false"
    @error="handleError"
  />
</template>
```

## Basic Usage

```vue
<script setup lang="ts">
import { useToast } from 'maz-ui/composables'
import { ref } from 'vue'

const toast = useToast()

const files = ref<File[]>([])
const dropzone = ref<InstanceType<typeof MazDropzone>>()

function onUploadSuccess({ file, response }) {
  console.log('Upload success:', file, response)
  toast.success(`File ${file.name} uploaded successfully`)
}

function onUploadError({ file, code, error }) {
  console.error('Upload failed:', file, code, error)
  toast.error(`File ${file.name} upload failed: ${code} - ${error}`)
}

function onError({ files, event, code }) {
  console.error('Error:', files, event, code)
  toast.error(`${files?.length} files upload failed: ${code} - ${files?.map(file => file.name).join(', ')}`)
}
</script>

<template>
  <MazDropzone
    v-model="files"
    :data-types="['image/*', '.zip', '.strings', '.json', '.stringsdict']"
    :max-file-size="3"
    :max-files="5"
    :max-concurrent-uploads="5"
    url="https://httpbin.org/post"
    :request-options="{
      headers: { 'My-Awesome-Header': 'header value' },
    }"
    @upload-success="onUploadSuccess"
    @upload-error="onUploadError"
    @error="onError"
  />

  <MazBtn :loading="dropzone?.isUploading" @click="dropzone?.uploadFiles()">
    Upload Files
  </MazBtn>
</template>
```

## File Type Restrictions

You can restrict allowed file types using the `data-types` prop:

```vue
<script lang="ts" setup>
const acceptedFormats = [
  '.strings',
  '.stringsdict',
  '.plist',
  '.xliff',
  '.xlf',
  '.xml',
  '.json',
  '.yaml',
  '.yml',
  '.po',
  '.pot',
  '.mo',
  '.properties',
  '.arb',
  '.csv',
  '.tsv',
  '.txt',
  'text/*',
  'application/json',
  'text/xml',
  'application/xml',
  'text/yaml',
  'text/html',
  'image/svg+xml',
  'video/mp4',
  'video/quicktime',
  'video/mpeg',
  'video/ogg',
  'video/webm',
  'audio/*',
]
</script>

<template>
  <MazDropzone
    v-model="files"
    :data-types="acceptedFormats"
    :max-file-size="5"
    :max-files="5"
    @error="onError"
  />
</template>
```

## Auto Upload

Enable automatic file upload using the `auto-upload` prop. Files can be uploaded individually (`single`) in separate requests or all at once (`multiple`) in a single request:

```html
<MazDropzone
  v-model="files"
  auto-upload="single"
  url="https://your-upload-endpoint.com/upload"
  @upload-success="onUploadSuccess"
  @upload-error="onUploadError"
  @error="onError"
/>
```

You can also upload all files at once using `multiple`:

**Tip:**

Multiple upload is allowed:

- when `max-files` is greater than 1
- when `auto-upload` is set to `multiple`
- when `multiple` prop is set to `true`

[Link to the source code](https://github.com/maz-ui/maz-ui/blob/main/components/MazDropzone.vue#L219)

```html
<template>
  <MazDropzone
    v-model="files"
    auto-upload="multiple"
    url="https://your-upload-endpoint.com/upload"
    @upload-success-multiple="onUploadSuccessMultiple"
    @upload-error-multiple="onUploadErrorMultiple"
    @error="onError"
  />
</template>

<script setup lang="ts">
  import { ref } from 'vue'
  import { useToast } from 'maz-ui/composables'

  const files = ref<File[]>([])

  const toast = useToast()

  const onUploadSuccessMultiple = ({ files, response }) => {
    console.log('Upload multiple success:', files, response)
    toast.success(`${files.length} files uploaded successfully`)
  }

  const onUploadErrorMultiple = ({ files, code, error }) => {
    console.error('Upload mulitple failed:', files, code, error)
    toast.error(`${files.length} files upload failed: ${code} - ${error}`)
  }
</script>
```

## Custom Upload Area

Customize the upload area using slots:

```html
<MazDropzone v-model="files" @error="onError">
  <template #no-files-area="{ handleFileInputClick }">
    <div class="flex flex-col items-center gap-4">
      <MazIcon icon="/arrow-up-on-square.svg" class="text-4xl" />
      <p>Drop your files here or click to browse</p>
      <MazBtn @click="handleFileInputClick"> Select Files </MazBtn>
    </div>
  </template>
</MazDropzone>
```

## Custom Translations

### Using `translations` prop

Customize text messages using the `translations` prop:

```html
<MazDropzone
  v-model="files"
  :translations="{
    dragAndDrop: 'Drag files here',
    selectFile: 'browse files',
    fileInfos: 'Accepted files: Images up to 5MB'
  }"
  @error="onError"
/>
```

### Using `MazUi` plugin

You can also use the `MazUi` plugin to customize the translations:

**Details: View code**

```ts
import { MazUi } from 'maz-ui/plugins/maz-ui'

app.use(MazUi, {
  translations: {
    locale: 'en',
    messages: {
      en: {
        dropzone: {
          dragAndDrop: 'Drag files here',
          selectFile: 'select files',
          divider: 'or',
          fileMaxCount: 'Maximum {count} files',
          fileMaxSize: 'Maximum {size} MB',
          fileTypes: 'Allowed file types: {types}',
        },
      },
    },
  },
})
```

## Custom Upload Request

Customize the upload request using `uploadUrl`, `requestOptions` and `transformBody`:

```html
<MazDropzone
  v-model="files"
  url="/api/upload"
  :request-options="{
    method: 'POST',
    headers: {
      'Authorization': 'Bearer token123'
    },
  }"
  :transform-body="(formData, files) => {
    // Add additional data to FormData
    formData.append('userId', '123')
    formData.append('fileCount', files.length.toString())
    return formData
  }"
  @error="onError"
/>
```

## MazDropzone API

`import MazDropzone from 'maz-ui/components/MazDropzone'`

### Props

- `id` (`string`): The id of the dropzone.
- `multiple` (`boolean`, default: `false`): Allow multiple files to be uploaded.
- `data-types` (`string[]`, default: `['*\/*']`): Allowed data types/MIME types for files (e.g. ['application/json']).
- `prevent-default-for-unhandled` (`boolean`, default: `true`): Prevent default behavior for unhandled drag & drop events.
- `max-file-size` (`number`): Maximum file size in MB.
- `max-files` (`number`): Maximum number of files allowed.
- `disabled` (`boolean`, default: `false`): Disable the dropzone.
- `preview` (`boolean`, default: `true`): Show file preview.
- `min-file-size` (`number`): Minimum file size in MB.
- `allow-duplicates` (`boolean`, default: `false`): Allow duplicates.
- `translations` (`{ dragAndDrop?: string | undefined; selectFile?: string | undefined; divider?: string | undefined; fileMaxCount?: string | undefined; fileMaxSize?: string | undefined; fileTypes?: string | undefined; types?: { image?: string | undefined;...`): Translations - Custom translations for the component.
- `color` (`"primary" | "secondary" | "accent" | "info" | "success" | "warning" | "destructive" | "contrast" | "transparent"`, default: `"primary"`): Main color of the component.
- `remove-file-btn-props` (`MazBtnProps`, default: `{}`): MazBtn props [MazBtn props](./maz-btn.md#props).
- `spinner-props` (`MazSpinnerProps`, default: `{}`): MazSpinner props [MazSpinner props](./maz-spinner.md#props).
- `auto-upload` (`false | "multiple" | "single"`, default: `false`): Auto upload files - If set to `multiple`, all files will be uploaded at once in a single request. If set to `single`, files will be uploaded one by one in separate requests. If set to `false`, no upload will be done automatically.
- `url` (`string`): Upload URL - If set, files will be uploaded to the given URL.
- `request-options` (`RequestInit`): Request options - Request options to be used for the upload (using fetch) [Request options](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options).
- `transform-body` (`((formData: FormData) => BodyInit | null | undefined)`): Transform the body of the request.
- `max-concurrent-uploads` (`number`, default: `5`): Maximum number of concurrent uploads - Limit the number of files uploaded simultaneously to avoid overwhelming the server.
- `model-value` (`MazDropzoneFileData[]`, default: `[]`, `v-model`): The files data.

### Events

- `@add` (payload: `value: File`): Event emitted when a file is added to the dropzone
- `@error` (payload: `values: { files: File[] | null; event: DragEvent | null; code: MazDropzoneErrorCode; }`): Event emitted when an error occurs
- `@drop` (payload: `values: { files: File[] | null; event: DragEvent; }`): Event emitted when files are dropped in the dropzone
- `@update:modelValue` (payload: `value: MazDropzoneFileData[]`)
- `@enter` (payload: `values: { files: File[] | null; event: DragEvent; }`): Event emitted when dragged files enter the dropzone
- `@leave` (payload: `values: { files: File[] | null; event: DragEvent; }`): Event emitted when dragged files leave the dropzone
- `@over` (payload: `values: { files: File[] | null; event: DragEvent; }`): Event emitted when dragged files are over the dropzone
- `@remove` (payload: `value: File`): Event emitted when a file is removed from the dropzone
- `@upload-error` (payload: `values: { file: File; code: MazDropzoneErrorCode; error: unknown; }`): Event emitted when an error occurs during file upload
- `@upload-error-multiple` (payload: `values: { files: File[]; code: MazDropzoneErrorCode; error: unknown; }`): Event emitted when an error occurs during multiple files upload
- `@upload-success` (payload: `values: { file: File; response?: Response | undefined; }`): Event emitted when a file is successfully uploaded
- `@upload-success-multiple` (payload: `values: { files: File[]; response?: Response | undefined; }`): Event emitted when multiple files are successfully uploaded

### Slots

- `#files-area`: Slot to customize the files area Bindings: `filesData: MazDropzoneFileData[]` (The files data).
- `#file-item`: Slot to customize the file item Bindings: `file: MazDropzoneFileData` (The drop file data).
- `#no-files-area`: Slot to customize the no files area Bindings: `selectFile: () => void` (The function to select the file).
- `#upload-icon`: Slot to customize the upload icon

### Exposed (template ref)

- `uploadFiles`: Upload files
- `uploadFilesMultiple`: Upload multiple files
- `getFormData`: Get form data
- `getFormDataMultiple`: Get form data multiple
- `reset`: Reset the files
- `isUploading`: Check if the files are uploading
- `addFile`: Add a file to the dropzone
- `removeFile`: Remove a file from the dropzone
