In this post we will be discussing about uploading images to Digital Ocean Spaces using React.js. Digital Ocean Spaces allows you to store and vast amount of contents be it images, video or audio. It's S3 compatible object storage which has built in CDN that makes scaling easy, reliable and affordable. The pricing starts from $5 in which you will get 250 GB of storage, 1 TB of outbound transfer and unlimited uploads.
We will be using DO Spaces API, which provides RESTful XML API for pro-grammatically managing the data. The API is inter-operable with Amazon's AWS S3 API that means it allows you to interact with the service while using the tools you already know.
To work with this tutorial you need to have a DigitalOcean Space, along with an access key and secret key to your account. Learn here how to set up the Digital Ocean Space along with access key and secret key. Also you need to install aws-sdk in you application using npm : npm install --save aws-sdk
At first we will be creating a file named DigitalOcean.js and add the following code to it
In the above code we are connecting to the DigitalOcean Spaces API. At first you need to see which region your spaces is located and the spacesEndPoint will point to that location, in our case it is nyc3. You need to add the ACCESS_KEY_ID and ACCESS_SECRET_KEY in the environment variable.
We will also be creating a config.js file which will have the bucket name and DO Spaces full url as shown below :
On the front-end we will be adding a input tag of type file which will always accept an image type as shown below :
Then we will have a prop which will send the data to the Digital Ocean Spaces using the S3.putObject function as shown below :
Do note that x-amz-acl is only needed if you want to allow the public to have an access to your images otherwise you can remove that line.
We will be using DO Spaces API, which provides RESTful XML API for pro-grammatically managing the data. The API is inter-operable with Amazon's AWS S3 API that means it allows you to interact with the service while using the tools you already know.
Prerequistes
To work with this tutorial you need to have a DigitalOcean Space, along with an access key and secret key to your account. Learn here how to set up the Digital Ocean Space along with access key and secret key. Also you need to install aws-sdk in you application using npm : npm install --save aws-sdk
Code
At first we will be creating a file named DigitalOcean.js and add the following code to it
import AWS from 'aws-sdk'; /** * Digital Ocean Spaces Connection */ const spacesEndpoint = new AWS.Endpoint('nyc3.digitaloceanspaces.com'); const s3 = new AWS.S3({ endpoint: spacesEndpoint, accessKeyId: process.env.ACCESS_KEY_ID, secretAccessKey: process.env.ACCESS_SECRET_KEY }); export default s3;
In the above code we are connecting to the DigitalOcean Spaces API. At first you need to see which region your spaces is located and the spacesEndPoint will point to that location, in our case it is nyc3. You need to add the ACCESS_KEY_ID and ACCESS_SECRET_KEY in the environment variable.
We will also be creating a config.js file which will have the bucket name and DO Spaces full url as shown below :
export default { digitalOceanSpaces: 'https://myBucketName.nyc3.digitaloceanspaces.com/', bucketName: 'myBucketName' };
On the front-end we will be adding a input tag of type file which will always accept an image type as shown below :
<input type="file" id="inputfile" accept="image/*" onChange={this.handleImageChange} />
Then we will have a prop which will send the data to the Digital Ocean Spaces using the S3.putObject function as shown below :
handleImageChange = (e) => { if (e.target.files && e.target.files[0]) { const blob = e.target.files[0]; const params = { Body: blob, Bucket: `${Config.bucketName}`, Key: blob.name}; // Sending the file to the Spaces S3.putObject(params) .on('build', request => { request.httpRequest.headers.Host = `${Config.digitalOceanSpaces}`; request.httpRequest.headers['Content-Length'] = blob.size; request.httpRequest.headers['Content-Type'] = blob.type; request.httpRequest.headers['x-amz-acl'] = 'public-read'; }) .send((err) => { if (err) errorCallback(); else { // If there is no error updating the editor with the imageUrl const imageUrl = `${Config.digitalOceanSpaces}` + blob.name callback(imageUrl, blob.name) } }); } };
Do note that x-amz-acl is only needed if you want to allow the public to have an access to your images otherwise you can remove that line.
There is a typo in code. add "const" before blob.
ReplyDeleteFixed, thanks :)
Deletehow to with react native, i have react native app and want to upload images direct from my react native app to Spaces .. will this work or need something else ???
ReplyDeleteThis will work in React Native too.
Deleteit doesn't work in react native :( !
DeleteAfter uploading, how can I retrieve the url of the image stored in digital ocean spaces using GET and show that on the front end of my app?
ReplyDeleteThis is the image url stored in digital ocean spaces
Deleteconst imageUrl = `${Config.digitalOceanSpaces}` + blob.name
Hey man, I'm learning how to upload files to DO and use them as profile images. However, I already have a component where I'm showing the upload section to edit the profile photo. e.g.: "/client/src/profile/profile.js"
ReplyDeleteIn that case, where should I upload the config.js and digitalocean.js files? And how do I connect them to my component?
I'm utterly confused because most DigitalOcean tutorials don't explain this. I followed this one: https://www.digitalocean.com/community/tutorials/how-to-upload-a-file-to-object-storage-with-node-js#create-the-front-end-of-the-application - but I got stuck at making it work with a component within the app.
Hey man! Thanks for this tutorial. It's a little different from the official DO: https://www.digitalocean.com/community/tutorials/how-to-upload-a-file-to-object-storage-with-node-js#create-the-front-end-of-the-application
ReplyDeleteAnyway, I started following the one above, but I couldn't find a way to make this upload-image component work. Why? Because I already have an app working with the component file not in the index.html.
Let's say the component where I want to add the upload function is in "client/src/profile/profile-form" - where should I put the config.js and the digitalocean.js files? And how do I use them (with a standard import function?)?
Hi There, it worked on my Mobile App but now i am working on React/Next.js web app but CORS missing allow origin error .. any setting from DigitalOcean spaces side ??? currently my domain name is localhost as its in development
ReplyDeleteYou can look at https://www.digitalocean.com/community/questions/why-can-i-use-http-localhost-port-with-cors-in-spaces to handle CORS issue in localhost
DeleteHi, first of all thanks for the post, it's really helpful but, is this secure? The Secret gets exposed in the front, right?
ReplyDeleteYes its secure, the secret does not expose in the frontend. You can make it more secure by encrypting the secret or loading it from some file from your file system.
DeleteThank you!
ReplyDeleteWelcome
Deletehow to delete the uploaded image ?
ReplyDelete