Uploader

File Upload Widget for Web Apps,
with Integrated Cloud Storage.

Fork on GitHub
Select a framework:
Cropping an image

Built-in Image Cropper

Uploader can be used as both an image uploader and a file uploader. When used as an image uploader, the UI can be configured to prompt users to crop images using a predefined aspect ratio, a freeform aspect ratio, or no image cropping at all.

Uploader supports both circular and rectangular crops.

Dragging a file to upload

Drag-and-Drop File Uploads

Uploader provides drag-and-drop file upload support through an integrated dropzone which wraps the entire UI. The drag-and-drop area supports single and multiple file uploads, and can be configured to render as a popup or as an inline file uploader.

Uploading multiple files

Multiple File Uploads

Uploader supports single and multiple file upload modes:

  • In single file upload mode, Uploader serves perfectly as a profile picker, product image selector, document uploader, etc.
  • In multiple file upload mode, Uploader supports batch-uploads of 100+ files per batch, and can be used for image galleries, photo albums, and more.
Custom color scheme

Themeable UI

Uploader offers a themeable file upload UI that makes color changes and font size changes easy to accomplish with a single line of code. Deep CSS customization is also supported for complete re-skins.

Upload Dashboard screenshot

Integrated Storage & CDN

Uploader comes pre-integrated with cloud-based file storage, purpose-built for high-demand, low-latency file uploading.

  • Scalable File Storage & Hosting (300-Point CDN)
  • Powerful Rules Engine (Rate & Traffic Limiting, etc.)
  • File Transformations (Image Resizing, Cropping, etc.)

Get Started

Upload.io's file upload widget — named "Uploader" — only takes a few seconds to integrate as your site's file and image uploader:

Installation

Install Uploader using one of the following packages:

Note: You do not need to install uploader if installing a framework package (e.g. react-uploader).

Core JavaScript Uploader

npm install uploader
yarn add uploader
<script src="https://js.upload.io/uploader/v3"></script>

React Uploader

npm install react-uploader
yarn add react-uploader
<script src="https://js.upload.io/react-uploader/v3"></script>

Vue Uploader

npm install @upload-io/vue-uploader
yarn add @upload-io/vue-uploader
<script src="https://js.upload.io/vue-uploader/v3"></script>

Angular Uploader

npm install uploader angular-uploader
yarn add uploader angular-uploader

jQuery Uploader

npm install jquery @upload-io/jquery-uploader
yarn add jquery @upload-io/jquery-uploader
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://js.upload.io/jquery-uploader/v3"></script>

Usage

To display the file upload widget:

Plain JavaScript

// Ignore if installed via a <script> tag.
import { Uploader } from "uploader";
// Get production API keys from Upload.io
const uploader = Uploader({
apiKey: "free"
});
// Customize the file upload UI (see "customization" below):
const options = { multi: true }
// Display the file upload widget:
uploader.open(options).then(files => {
if (files.length === 0) {
console.log('No files selected.')
} else {
console.log('Files uploaded:');
console.log(files.map(f => f.fileUrl));
}
}).catch(err => {
console.error(err);
});

React File Upload Component

Use the UploadButton component to implement a file upload button in React:

import { Uploader } from "uploader";
import { UploadButton } from "react-uploader";
// Get production API keys from Upload.io
const uploader = Uploader({
apiKey: "free"
});
// Customize the file upload UI (see "customization"):
const options = { multi: true }
// Render the file upload button:
const MyButtonComponent = () =>
<UploadButton uploader={uploader} // Required.
options={options} // Optional.
onComplete={files => { // Optional.
if (files.length === 0) {
console.log('No files selected.')
} else {
console.log('Files uploaded:');
console.log(files.map(f => f.fileUrl));
}
}}>
{({onClick}) =>
<button onClick={onClick}>
Upload a file...
</button>
}
</UploadButton>

Or, use the UploadDropzone component to implement drag-and-drop file uploads in React:

import { Uploader } from "uploader";
import { UploadDropzone } from "react-uploader";
// Get production API keys from Upload.io
const uploader = Uploader({
apiKey: "free"
});
// Customize the dropzone UI (see "customization"):
const options = { multi: true }
// Render the file upload dropzone:
const MyDropzoneComponent = () =>
<UploadDropzone uploader={uploader} // Required.
options={options} // Optional.
width="600px" // Optional.
height="375px" // Optional.
onUpdate={files => { // Optional.
if (files.length === 0) {
console.log('No files selected.')
} else {
console.log('Files uploaded:');
console.log(files.map(f => f.fileUrl));
}
}} />

Vue File Upload Component

Use the openUploadModal helper method to implement a file upload button in Vue:

<template>
<button @click="uploadFile">Upload a file...</button>
</template>
<script>
import { Uploader } from "uploader";
import { openUploadModal } from "@upload-io/vue-uploader";
// Create one instance per app.
const uploader = Uploader({
apiKey: "free"
});
// Customize the file upload UI (see "customization"):
const options = {
multi: true
};
export default {
name: "App",
methods: {
uploadFile(event) {
openUploadModal({
event,
uploader,
options,
onComplete: (files) => {
if (files.length === 0) {
console.log("No files selected.");
} else {
console.log("Files uploaded:");
console.log(files.map(f => f.fileUrl));
}
}
})
}
}
};
</script>

Or, use the UploadDropzone component to implement drag-and-drop file uploads in Vue:

<template>
<UploadDropzone :uploader="uploader"
:options="options"
:on-update="onFileUploaded"
width="600px"
height="375px" />
</template>
<script>
import { Uploader } from "uploader";
import { UploadDropzone } from "@upload-io/vue-uploader";
// Create one instance per app.
const uploader = Uploader({ apiKey: "free" });
// Customize the dropzone UI (see "customization"):
const options = {
multi: true
};
export default {
name: "App",
components: {
UploadDropzone
},
data() {
return {
uploader,
options
};
},
methods: {
onFileUploaded: (files) => {
if (files.length === 0) {
console.log("No files selected.");
} else {
console.log("Files uploaded:");
console.log(files.map(f => f.fileUrl));
}
}
}
};
</script>

Angular File Upload Component

To start uploading files in an Angular app, first add the UploaderModule:

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { UploaderModule } from "angular-uploader";
import { AppComponent } from "./app.component";
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
UploaderModule // <-- Add the Uploader module here.
],
bootstrap: [AppComponent]
})
export class AppModule {}

Then use one of these options to display the file upload widget:

Option 1 — Use the uploadButton directive to implement a file upload button in Angular:

import { Component } from "@angular/core";
import { Uploader, UploaderOptions, UploaderResult } from "uploader";
@Component({
selector: "app-root",
template: `
<button uploadButton
[uploader]="uploader"
[uploadOptions]="uploadOptions"
[uploadComplete]="uploadComplete">
Upload a file...
</button>
`
})
export class AppComponent {
uploader = Uploader({
apiKey: "free"
});
uploadOptions: UploaderOptions = {
multi: false
};
uploadComplete = (files: UploaderResult[]) => {
console.log(files.map(x => x.fileUrl));
};
}

Option 2 — Use the upload-dropzone component to implement drag-and-drop file uploads in Angular:

import { Component } from "@angular/core";
import { Uploader, UploaderOptions, UploaderResult } from "uploader";
@Component({
selector: "app-root",
template: `
<upload-dropzone [uploader]="uploader"
[options]="options"
[onUpdate]="onUpdate"
[width]="width"
[height]="height">
</upload-dropzone>
`
})
export class AppComponent {
uploader = Uploader({
apiKey: "free"
});
options: UploaderOptions = {
multi: false
};
// 'onUpdate' explained:
// - Dropzones are non-terminal by default (i.e. they don't have an
// end state), so we use 'onUpdate' instead of 'onComplete'.
// - To create a terminal dropzone, add 'showFinishButton: true' in
// the options above, and use the 'onComplete' callback instead.
onUpdate = (files: UploaderResult[]) => {
console.log(files.map(x => x.fileUrl));
};
width = "600px";
height = "375px";
}

jQuery File Upload Plugin

The jquery-uploader plugin provides a simple way to implement a jQuery AJAX file upload — without any server-side code or infrastructure.

Step 1 — Initialize the plugin once at the start of your app:

$.uploader.init({
apiKey: "free"
});

Step 2 — To perform a simple jQuery file upload:

$(function() {
$("button").uploader({
onComplete: files => {
if (files.length === 0) {
console.log('No files selected.');
} else {
console.log('File uploaded:');
console.log(file[0].fileUrl);
}
}
});
});

By default, the file upload UI is displayed as a modal (on click) and accepts a single file upload only.

You can customize this behaviour through the options object.

For example, a jQuery multiple file upload:

$(function() {
$("button").uploader({
// Enables multiple file uploads.
multi: true,
onComplete: files => {
if (files.length === 0) {
console.log('No files selected.');
} else {
console.log('Files uploaded:');
console.log(files.map(f => f.fileUrl));
}
}
});
});

You can also use the dropzone parameter to create inline drag-and-drop file upload areas.

For example, a drag-and-drop file upload in jQuery:

$(function() {
$("#my-div").uploader({
// Renders the file uploader UI inside #my-div (instead of in a popup on click).
dropzone: {
width: "600px",
height: "375px"
},
// Note: we use 'onUpdate' instead of 'onComplete'.
// This is because dropzones don't have an 'end state' by default.
onUpdate: files => {
if (files.length === 0) {
console.log('No files selected.');
} else {
console.log('Files uploaded:');
console.log(files.map(f => f.fileUrl));
}
}
});
});

Customization (optional)

Optional step: use the options object to customize the file upload UI and behaviour — all fields are optional:

const options = {
// ---------------------
// Colors & Font Size
// ---------------------
styles: {
colors: {
primary: "#377dff", // Primary buttons & links
active: "#528fff", // Primary buttons & links (hover). Inferred if undefined.
error: "#d23f4d", // Error messages
shade100: "#333", // Standard text
shade200: "#7a7a7a", // Secondary button text
shade300: "#999", // Secondary button text (hover)
shade400: "#a5a6a8", // Welcome text
shade500: "#d3d3d3", // Modal close button
shade600: "#dddddd", // Border
shade700: "#f0f0f0", // Progress indicator background
shade800: "#f8f8f8", // File item background
shade900: "#fff" // Various (draggable crop buttons, etc.)
},
fontFamilies: {
base: "-apple-system, blinkmacsystemfont, Segoe UI, helvetica, arial, sans-serif"
},
fontSizes: {
base: 16
}
},
// ---------------------
// Image Editor
// ---------------------
editor: {
images: {
preview: true, // True by default if cropping is enabled. Supports videos & PDFs too.
crop: true, // True by default. False disables the image editor / cropper.
cropRatio: 4 / 3,
cropShape: "rect" // "rect" | "circ"
}
},
// ---------------------
// Accepted Files
// ---------------------
maxFileCount: 10,
maxFileSizeBytes: 5 * 1024 * 1024,
mimeTypes: ["image/jpeg"],
multi: true,
// ---------------------
// File Upload Behaviour
// ---------------------
path: { // Optional: can be a string (full file path) or an object like so:
fileName: "Example.jpg", // Each supports path variables (e.g. {ORIGINAL_FILE_EXT}). See your
folderPath: "/uploads" // API key's config in the Upload Dashboard for all path variables.
},
metadata: {}, // Arbitrary JSON object (to save against the file).
tags: [], // Array of strings (to save against the file).
// ---------------------
// Other UI Behaviour
// ---------------------
layout: "modal", // "modal" | "inline" (i.e. to create a dropzone)
container: "body", // Parent element to render the widget in.
locale: myCustomLocale,
onUpdate: files => {},
onValidate: async file => { /* Return a string to display a custom error. */ },
showFinishButton: true,
showRemoveButton: true
}
Time to grab a coffee!

Your web app now has a functioning
file upload widget!

Releasing to production?

Use the API key "free" to experiment with Uploader without creating an account. When you're ready, create an Upload account to get permanent file storage.

✓ No credit card required. Try free for 14 days.

No hidden fees
Storage & CDN, built-in.

Uploader comes pre-integrated with cloud-based file storage, file hosting, and a worldwide 450-point CDN.

Learn More
Start your integration
Zero infrastructure.

No need to configure servers, buckets, security policies or roles: all you need is Upload.js and an API key.

Get an API Key

You are using an outdated browser.

This website requires a modern web browser -- the latest versions of these browsers are supported: