It’s lightweight, doesn’t depend on any other library (like jQuery) and is highly customizable .

Try it out! Drop files here or click to upload.

(This is just a demo dropzone. Selected files are not actually uploaded.)

News Dropzone 5.7.2, July 23rd 2020 Lots of minor fixes in this small release. Please check the CHANGELOG to see a summary of the changes. I know that most of you are unhappy that I can’t fix all bugs and implement all feature requests immediately, but I have a job and I’m doing my best to maintain this library for over eight years now. Please stay respectful and patient. I’m doing my best to keep this alive and maintained in my free time without getting paid for it. Well crafted merge requests are the fastest way to get your feature into Dropzone!

If you want to support me or thank me for the work I’ve put into Dropzone, check out my latest music video and leave a like if you feel like it: And don’t forget: don’t be an asshole! ❤️

Installation You probably only need to look at the simple example (source) to get started. Continue reading for step by step instructions and different installation approaches. Download the standalone dropzone.js and include it like this: < script src = "./path/to/dropzone.js" ></ script > Dropzone is now activated and available as window.Dropzone . Dropzone does not handle your file uploads on the server. You have to implement the code to receive and store the file yourself. See the section Server side implementation for more information. This is all you need to get dropzone up and running, but if you want it to look like the dropzone on this page, you’ll need to use the dropzone.css in the dist folder. With RequireJS Dropzone is also available as an AMD module for RequireJS. You can find the dropzone-amd-module in the dist folder.

Events Dropzone triggers events when processing files, to which you can register easily, by calling .on(eventName, callbackFunction) on your instance. Since listening to events can only be done on instances of Dropzone, the best place to setup your event listeners, is in the init function: // The recommended way from within the init configuration: Dropzone . options . myAwesomeDropzone = { init : function () { this . on ( "addedfile" , function ( file ) { alert ( "Added file." ); }); } }; If you create your Dropzones programmatically, you can setup your event listeners on your instances, like this: // This example uses jQuery so it creates the Dropzone, only when the DOM has // loaded. // Disabling autoDiscover, otherwise Dropzone will try to attach twice. Dropzone . autoDiscover = false ; // or disable for specific dropzone: // Dropzone.options.myDropzone = false; $ ( function () { // Now that the DOM is fully loaded, create the dropzone, and setup the // event listeners var myDropzone = new Dropzone ( "#my-dropzone" ); myDropzone . on ( "addedfile" , function ( file ) { /* Maybe display some more file information on your page */ }); }) This is a bit more complex, and not necessary unless you have a good reason to instantiate Dropzones programmatically. Dropzone itself relies heavily on events. Everything that’s visual is created by listening to them. Those event listeners are setup in the default configuration of every Dropzone and can be overwritten, thus replacing the default behavior with your own event callback. You should only do this when you really know how Dropzone works, and when you want to completely theme your Dropzone Event List Event list Do not overwrite those as configuration options, unless you know what you're doing. Parameter Description All of these receive the event as first parameter: drop The user dropped something onto the dropzone dragstart The user started to drag anywhere dragend Dragging has ended dragenter The user dragged a file onto the Dropzone dragover The user is dragging a file over the Dropzone dragleave The user dragged a file out of the Dropzone All of these receive the file as first parameter: addedfile When a file is added to the list removedfile Called whenever a file is removed from the list. You can listen to this and delete the file from your server if you want to. thumbnail When the thumbnail has been generated. Receives the dataUrl as second parameter. error An error occured. Receives the errorMessage as second parameter and if the error was due to the XMLHttpRequest the xhr object as third. processing When a file gets processed (since there is a queue not all files are processed immediately). This event was called processingfile previously. uploadprogress Gets called periodically whenever the file upload progress changes.

Gets the progress parameter as second parameter which is a percentage (0-100) and the bytesSent parameter as third which is the number of the bytes that have been sent to the server.

When an upload finishes dropzone ensures that uploadprogress will be called with a percentage of 100 at least once.

Warning: This function can potentially be called with the same progress multiple times. sending Called just before each file is sent. Gets the xhr object and the formData objects as second and third parameters, so you can modify them (for example to add a CSRF token) or add additional data. success The file has been uploaded successfully. Gets the server response as second argument. (This event was called finished previously) complete Called when the upload was either successful or erroneous. canceled Called when a file upload gets canceled. maxfilesreached Called when the number of files accepted reaches the maxFiles limit. maxfilesexceeded Called for each file that has been rejected because the number of files exceeds the maxFiles limit. All of these receive a list of files as first parameter: addedfiles See addedfile for description. All of these receive a list of files as first parameter and are only called if the uploadMultiple option is true: processingmultiple See processing for description. sendingmultiple See sending for description. successmultiple See success for description. errormultiple See error for description. completemultiple See complete for description. canceledmultiple See canceled for description. Special events: totaluploadprogress Called with the total uploadProgress (0-100), the totalBytes and the totalBytesSent . This event can be used to show the overall upload progress of all files. reset Called when all files in the list are removed and the dropzone is reset to initial state. queuecomplete Called when all files in the queue finish uploading. Theming If you want to theme your Dropzone to look fully customized, in most cases you can simply replace the preview HTML template, adapt your CSS, and maybe create a few additional event listeners. You will go very far with this approach. As an example, I created an example where I made Dropzone look and feel exactly the way jQuery File Uploader does with a few lines of configuration code. Check it out! As you can see, the biggest change is the previewTemplate . I then added a few additional event listeners to make it look exactly like the reference. You can however, implement your UI completely from scratch. Dropzone itself sets up a lot of event listeners when a Dropzone is created, that handle all your UI. They do stuff like: create a new HTML element, add the <img> element when provided with image data (with the thumbnail event), update the progress bar when the uploadprogress event fires, show a checkmark when the success event fires, etc… Everything visual is done in those event handlers. If you would overwrite all of them with empty functions, Dropzone would still be fully functional, but wouldn’t display the dropped files anymore. If you like the default look of Dropzone, but would just like to add a few bells and whistles here and there, you should just add additional event listeners instead. Overwriting the default event listeners, and creating your own, custom Dropzone, would look something like this: // This is an example of completely disabling Dropzone's default behavior. // Do *not* use this unless you really know what you are doing. Dropzone . myDropzone . options = { previewTemplate : document . querySelector ( '#template-container' ). innerHTML , // Specifing an event as an configuration option overwrites the default // `addedfile` event handler. addedfile : function ( file ) { file . previewElement = Dropzone . createElement ( this . options . previewTemplate ); // Now attach this new element some where in your page }, thumbnail : function ( file , dataUrl ) { // Display the image in your file.previewElement }, uploadprogress : function ( file , progress , bytesSent ) { // Display the progress } // etc... }; Obviously this lacks the actual implementation. Look at the source to see how Dropzone does it internally. You should use this option if you don’t need any of the default Dropzone UI, but are only interested in Dropzone for it’s event handlers, file upload and drag’n’drop functionality.

Tips If you do not want the default message at all (»Drop files to upload (or click)«), you can put an element inside your dropzone element with the class dz-message and dropzone will not create the message for you. Dropzone will submit any hidden fields you have in your dropzone form. So this is an easy way to submit additional data. You can also use the params option. Dropzone adds data to the file object you can use when events fire. You can access file.width and file.height if it’s an image, as well as file.upload which is an object containing: progress (0-100), total (the total bytes) and bytesSent . If you want to add additional data to the file upload that has to be specific for each file, you can register for the sending event: myDropzone . on ( "sending" , function ( file , xhr , formData ) { // Will send the filesize along with the file as POST data. formData . append ( "filesize" , file . size ); }); To access the preview html of a file, you can access file.previewElement . For example: myDropzone . on ( "addedfile" , function ( file ) { file . previewElement . addEventListener ( "click" , function () { myDropzone . removeFile ( file ); }); }); If you want the whole body to be a Dropzone and display the files somewhere else you can simply instantiate a Dropzone object for the body, and define the previewsContainer option. The previewsContainer should have the dropzone-previews or dropzone class to properly display the file previews. new Dropzone ( document . body , { previewsContainer : ".dropzone-previews" , // You probably don't want the whole body // to be clickable to select files clickable : false }); Look at the gitlab wiki for more examples. If you have any problems using Dropzone, please try to find help on stackoverflow.com by using the dropzone.js tag. Only create an issue on GitLab when you think you found a bug or want to suggest a new feature.

Compatibility This section describes compatibility with browsers and older versions of Dropzone. Browser Support Chrome 7+

Firefox 4+

IE 10+

Opera 12+ (Version 12 for MacOS is disabled because their API is buggy)

Safari 6+ For all the other browsers, dropzone provides an oldschool file input fallback. There is no workaround for drag’n’drop in older browsers – it simply isn’t supported. The same goes for image previews, etc… But using dropzone, your users using an old browser will be able to upload files. It just won’t look and feel great. But hey, that’s their fault. Version 5.0 Starting with version 5.2, dropzone is no longer written in CoffeeScript, but in EcmaScript6. To still work in older browsers, the code is still compiled with babel. Version 4.0 This is not a changelog. Only compatibility problems are listed. Changed the default previewTemplate . Check out the new one in the layout section.

. Check out the new one in the layout section. Using an already included SVG instead of a PNG spritemap (the CSS file is now the only additional file that you need to include) Version 3.0 This is not a changelog. Only compatibility problems are listed. All classes are prefixed with dz- now to prevent clashing with other CSS definitions

now to prevent clashing with other CSS definitions The way previewTemplate is defined has changed. You have to provide data-dz-* elements now

is defined has changed. You have to provide elements now If the server returns JSON, it will be parsed for error messages as well

There’s a dict* option for all of the visible messages

option for all of the visible messages Lots of minor fixes and changes Version 2.0 This is not a changelog. Only compatibility problems are listed. Starting with version 2.0, Dropzone no longer depends on jQuery, but Dropzone still registers itself as a jQuery module if available. That means that creating your Dropzones like this still works: $ ( "#my-dropzone" ). dropzone ({ /* options */ }); If you create your Dropzones with the normal constructor though, you have to pass either the raw HTMLElement, or a selector string. So those versions all work: // With jQuery new Dropzone ( $ ( "#my-dropzone" ). get ( 0 )); // Without jQuery new Dropzone ( "#my-dropzone" ); new Dropzone ( document . querySelector ( "#my-dropzone" )); Another thing that changed, is that Dropzone no longer stores its instances inside the element’s data property. So to get a dropzone for an element do this now: // DEPRECATED, do not use: $ ( "#my-dropzone" ). data ( "dropzone" ); // won't work anymore // Do this now: Dropzone . forElement ( element ); // Providing a raw HTMLElement // or Dropzone . forElement ( "#my-dropzone" ); // Providing a selector string.