All the following examples assume that you have installed the client-library and have a file input somewhere in your HTML code. For example:
<input id="file-input" type="file"/>
Before you can upload files, you must initialize the client library with your API key
// NPM users onlyimport UploadClient from "@betterstack/upload-client";​// Init upload clientconst UC = new UploadClient({apiKey: "<YOUR_API_KEY>",});​// Change API key if neededUC.setApiKey("<YOUR_API_KEY>");
The simplest way to use the library is to initialize it and upload a file using the promise interface
const file = document.getElementById("file-input").files[0];// Create upload taskconst task = UC.upload({providerId: "<YOUR_PROVIDER_ID>",files: [{ file: file }]});​// Start upload with promisetask.start().then((uploaded) => {const uploadedFile = uploaded[0];console.log(uploadedFile.key); // Uploaded pathconsole.log(uploadedFile.file); // Uploaded file}).catch((e) => {console.log(e.code); // Error codeconsole.log(e.message); // Error message// See all errors on 'Error Handling' page});
Using the async / await syntax allows you to write much more readable code that's ultimately easier to manage. The remainder of the code examples will use this method instead of promises directly.
async function uploadFile() {​const file = document.getElementById("file-input").files[0];const task = UC.upload({providerId: "<YOUR_PROVIDER_ID>",files: [{ file: file }]});​try {const uploaded = await task.start();const uploadedFile = uploaded[0];console.log(uploadedFile.key); // Uploaded pathconsole.log(uploadedFile.file); // Uploaded file}catch (e) {console.log(e.code); // Error codeconsole.log(e.message); // Error message}}
// Somewhere in your HTML// <form id="form">// <input id="file-input" type="file"/>// </form>​const form = document.getElementById("form");​form.addEventListener("submit", async (e) => {​e.preventDefault();const file = document.getElementById("file-input")[0];const task = UC.upload({providerId: "<YOUR_PROVIDER_ID>",files: [{ file: file }]});try {const uploaded = await task.start();const uploadedFile = uploaded[0];console.log(uploadedFile.key); // Uploaded pathconsole.log(uploadedFile.file); // Uploaded file}catch (e) {console.log(e.code); // Error codeconsole.log(e.message); // Error message}});
This example shows a simple component that will automatically upload files when selected by a user
import React from "react";​class UploadInput extends React.Component {​state = { progress: 0 }​change = async (e) => {​// Get files in inputconst files = e.target.files;// Verify file has been selectedif (files.length === 0) return;​// Create upload taskconst task = UC.upload({providerId: "<YOUR_PROVIDER_ID>",files: [{ file: file }]});// Track upload progresstask.onProgress((e) => {this.setState({ progress: Math.round(e.loadedPercent) });});​// Start uploadtry {const uploaded = await task.start();const uploadedFile = uploaded[0];console.log(uploadedFile.key); // Uploaded pathconsole.log(uploadedFile.file); // Uploaded file}catch (e) {console.log(e.code); // Error codeconsole.log(e.message); // Error message}​}​render() {return (<div><input type="file" onChange={this.change}/><p>Upload progress: {this.state.progress}%</p></div>);}​}
async function uploadFile() {​// <input id="file-input" type="file" multiple/>const inputFiles = document.getElementById("file-input");const files = [];for (let i = 0; i < inputFiles.length; i++) {files[i] = { file: inputFiles[i] };}const task = UC.upload({providerId: "<YOUR_PROVIDER_ID>",files: files,});​try {const uploaded = await task.start();uploaded.forEach((item) => {console.log(item.key); // Uploaded pathconsole.log(item.file); // Uploaded file});}catch (e) {console.log(e.code); // Error codeconsole.log(e.message); // Error message}}
const file = document.getElementById("file-input")[0];​const task = UC.upload({providerId: "<YOUR_PROVIDER_ID>",files: [{ file: file }]});task.onProgress((e) => {// Total loaded % from 0 - 100console.log(e.loadedPercent);// Total bytes to upload and total bytes uploadedconsole.log(e.totalBytes, e.loadedBytes);// Array of total bytes for each file + uploaded bytes and % of each fileconsole.log(e.filesBytes, e.filesLoadedBytes, e.filesLoadedPercent);});
By default, if you do not supply a key for the uploaded file, it will be placed in your base storage folder with the current file name. You can modify the base storage folder by editing your storage provider's "Upload Path Prefix" setting. It's recommend that you set a path prefix to prevent malicious clients from uploading files anywhere in your storage bucket.
Supplying an upload key as shown in the example below will result in it being added onto your base storage folder. For example if you set your "Upload Path Prefix" to images/
and you supplied a key of logos/main.png
, the final upload path would be images/logos/main.png
.
const file = document.getElementById("file-input")[0];​const task = UC.upload({providerId: "<YOUR_PROVIDER_ID>",files: [{file: file,key: "logos/main.png",}]});
Upload permissions are controlled by an ACL which is essentially a pre-defined set of permissions. See the list of ACL values available for AWS S3. Digitalocean spaces supports only 2 ACL values, private
and public-read
. By default, an upload is private if no ACL value is supplied.
You can set a default ACL value by editing your storage provider settings and supplying a value for the "Upload ACL" setting. Supplying an ACL value in your code as shown above will override your default provider ACL value.
const file = document.getElementById("file-input")[0];​const task = UC.upload({providerId: "<YOUR_PROVIDER_ID>",files: [{file: file,acl: "public-read",}]});
When uploading multiple files at once, each file is uploaded separately. By default, if any file fails to upload, the entire upload operation will throw an error. This may result in some files being uploaded already. This behaviour can be disabled so that no errors are thrown and after you can verify which files have been successfully uploaded.
async function uploadFiles() {​// <input id="file-input" type="file" multiple/>const inputFiles = document.getElementById("file-input");const files = [];for (let i = 0; i < inputFiles.length; i++) {files[i] = { file: inputFiles[i] };}const task = UC.upload({files: files,providerId: "<YOUR_PROVIDER_ID>",throwUploadError: false, // Prevent upload errors});​try {const uploaded = await task.start();const uploadedFile = uploaded[0];// Check if the file uploaded successfullyif (uploadedFile.responseCode === 200) {// File uploaded successfullyconsole.log(uploadedFile.key); // Uploaded pathconsole.log(uploadedFile.file); // Uploaded file}else {// File failed to uploadconsole.log(uploadedFile.errorCode);}}catch (e) {// Errors not related to the HTTP upload request will need to be caughtconsole.log(e.code); // Error codeconsole.log(e.message); // Error message}}