Image Uploads to Cloudinary in React with Drag & Drop

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey how's it going everyone it's lee halliday and in this video i am going to create um an image uploader using drop zone uh react drop zone and we're going to upload directly from the browser to cloudanary cloudnary is a great um image hosting solution that you can use and often you'll find yourself landing in the free tier so you don't even need to necessarily pay for for all that it gives you but what it allows you to do is basically upload an image in whatever size the user gives it to you as and then you can just resize it on the fly on demand by just changing some query parameters in the url thank you to quest forms for partnering with me on this video quest forms is a developer focused form service ideal for web agencies and they've just released version two of their product and i wanted to mention one of my favorite features if you head on over to their documentation they have a section about emails and what they do is provide you an easy way to send emails both as a notification to you as the sort of form creator and also a confirmation to the user who submitted the form and it's all easily editable in markdown which is something us as developers love for a limited time only quest forms is giving 50 off any annual plan for one year if you use the coupon code lee 50. so head on over to quest.io check them out and let's get back to the video so let's get started with react drop zone i've got it open and it gives you a nice simple usage guide and when i was learning how to use this this is definitely where i started and we're going to actually copy a couple lines of code to avoid having to type these out and for me to have to memorize the order that they go in but i'm going to explain what they do so we're going over into our next.js application i've already committed at a starting point for anyone that wants to follow along and i'll link to that in the description and i've already installed the different packages we need we're going to use a couple different ones from cloud and airy and we'll go into what they actually do later but right now we're working with react drop zone so we're inside next gs but we're going to be spending most of our time in this one file the index.js page which is the home component so i'm going to paste in those lines of code and then we'll go over what they do so the first one uses the use callback hook so we need to uncomment out this line here and what we're defining is an on drop callback function and what use callback hook does is it basically the function you pass in it will declare that function once and sort of memoize it so unless the parameters you pass here change which in our case they don't because there are none you're going to get the same function back every time it won't be regenerated giving you a new function and we're going to pass this on drop function to use drop zone hook and that gives us a few things back that we're going to use down here inside of our return code so we're going to pass a couple other things we're going to pass accepts i believe it is and accepts what it does is it tells you to say i only want to accept image slash star so basically any type type of image and we'll say multiple false because we just want to accept one image at a time so if we convert our div here this is drop zone into something that actually uses drop zone and we need to uh first uncomment out this hook so that it actually um it actually works um there we go so now it's working correctly so the first thing we're going to do is pass in these get root props function call which will splat out a number of different props from this function here and inside of our div we're going to put an input and on our input we're going to do the same thing with get input props function call to to splat out all of those uh different input props and then why don't we add a class to this because right now if we were to look at what it looks like nobody would know that this is a drop zone so inside of the styles that i'm going to import i've just got a couple styles declared one for drop zone another when it's active and another that i'm actually not using so let's delete that so drop zone i'm going to add that here so we're going to say class name as a backticks so i can embed styles.drop zone drop zone so there we go we have a nice orange drop zone so now the users know when or where they can drop a file in and what i also wanted to do was use this is drag active so what i can do is say is drag active ternary if it is we'll say use the active class otherwise so now when i um open this up i've got this beautiful hairless dog so when i drag it over it changes the drop zone to purple to sort of indicate that uh it's active we can sort of do whatever we want there to to indicate to the user that they've they're dropping something in so what i want to do is play around with this on drop callback that gives me some accepted files so why don't we just start by console.logging them uh so these are the accepted files and we'll just take a look at what it gives us so we'll drop the hairless dog on so it gives us an array of type file and this is actually what we want to now upload to cloud and airy so this is the actual javascript representation of a file and it gives us the mime type image slash jpeg the name the size all of that stuff so this is where we are going to start to work and upload the file to um to cloudnary and the first thing we need to do in cloudanary is get a url and this url it comes from some of these account details up here so the first one is the cloud name and also the base url that has your cloud name in it i always forget what it looks like so i put it in this nice readme here so that i don't forget so i'm going to copy and paste that paste this in so this is the url i'm going to post to except i'm not going to use this.context.cloudname i need to get my cloud name from somewhere because you need that built into the url that you're going to be posting the data to so i have put all of my environment variables in local and i've got a combination of keys that i want public so i've prefixed them with next underscore public to basically include them in the public webpack build of this next.js app and then i've got another one without that that's secret and it's going to be on the server side only so i need this cloud name here so we'll go back here and we'll say process dot end dot next public cloudinary cloud name and we're going to make a fetch request to send this some data to this url so because we want it to be fetched we're going to have to make this an async function so that we can say const responses await a call to fetch and we're going to fetch this url and we need to say that we're going to be posting data and we need to tell it what the body is so here i'm going to create something called form data and we'll put it into a variable up here so const form data so there's an object that comes in javascript built into the browser called form data and basically we just create it like this and now we can say form data dot append and then it's sort of key value pair so the first one is the name of this so we're going to say this is the file and then whatever the value is so right here we've got multiple files accepted files so that tells me we actually need to put this into a loop so why don't we say accepted files dot for each so this is going to be the async function that gives me the accepted file and we can move all of this inside of the function so i don't need this to be async anymore because my inner one here is and the rest should stay as as is we don't need to redeclare the url every time because it's not changing and we need to actually pass the accepted file in so another thing we need to pass when we're doing what's called an unsigned image upload directly to cloudanary is pass something called the something preset let's go back to my notes it's called the upload preset upload preset so there's two ways you can upload data to cloud and airy they're signed and unsigned and if you're going to do unsigned you don't need any back end at all but it's a little bit insecure and that's why you have to go into the cloudinary dashboard and enable it because it's not enabled by default so if we click this little settings button and go into upload we can come down here this big enable unsigned uploading so if we just click that it's going to create us this um something called an upload preset and it's going to give us this name so i'm going to copy this here but what this will allow us to do is upload using this upload preset in an unsigned way so i'm going to go to this end.local update this uh next public cloudinary upload preset in my environment variable and i just need to reboot my next app so that it picks up the changes to the environment file you can see here loaded and from the file that i'm looking at and now we can go back and pass this upload preset oh boy this is the one i want process dot n dot like this so here's the form data we're going to be posting to the server it's going to give us a response back why don't we convert that response to data so we'll say await response json because it's a it's another promise and then why don't we just console.log this data out to see what it looks like so if we come back here let's go to our dashboard so that we can see the image when it uploads we'll come to our app and we'll drag and drop that beautiful dog in so the hairless dog and what it gives us back is the data that comes from the response of sending that information unsigned using the upload preset we just created to cloudanary and so it gives us a number of a bunch of information back um the asset id and there should be one here called the public id so this is the important uh thing that you would want to save and if you want to save this to a database you'd want to basically send this to your back end and store it in your database or or wherever you're storing information i'm not dealing with the database in this demo so what i'm going to actually do to just make this demo work i'm going to go here and copy the response that we got back from cloud and airy and i'm going to put it in some state that i create so i'm going to create some new state here and we'll call it uploaded files and then set uploaded files and this is equal to use state hook that would normally start out as empty but i'm going to paste in this file that i've just uploaded so it's got some information like the public id that i mentioned what type of image it is the width and the height etc so you're more than welcome to save all of this information to your database but the only thing you truly need is this public id so now that i have this into state i'm just going to quickly display it on the screen so i'm going to come down here below my div and just put a ul and then iterate over the uploaded images sorry the uploaded files using map so that would give us a file and we want to return a list item that has a key so we can just use the file.public id as the key here and for now why don't we just um output that onto the screen public id so this is a representation of the image we just uploaded if we come back to our cloudinary dashboard we should see the hairless dog in here so it is in our cloudinary account beautiful but now i want to display this user this image to the user on the screen so there's actually a cloudinary react library that i have um already installed and it has something you can import a component called image so down here in the setup it gives you a little example of what it looks like and why don't we copy and paste this so that we can change it to be used inside of our demo so this is the way i do development i typically go to the docs or the the github repository page and i look at their example and that's how i learned how to use all these tools so me going in like copying and paste stuff that's sort of exactly how i do um my development to start and then you'd go into the actual documentation when you need like the readal details of all the options and how to configure this and and use it so i'm just going to uncomment this image component here and we'll come down and basically put this image component inside of our list item so we need the cloud name so i already had that in my environment variable so i can say this is process dot n dot cloud name so we need the public id this would be file.public id and then this is the beauty of cloudanary really you can start to pass all of these different transformations and it does on the fly sort of on-demand transformations of your images so we're giving this a width of 300 with a crop of scaling it so it will scale it down to fit inside of this width so if we come back here there's our beautiful beautiful dog on the screen so why don't we add another file but before i do that i'm just going to come and instead of just console.logging the data why don't i save the data into this state that i've got so i can call set uploaded files and we'll do the function callback approach so this will give us the old data and we want to return a copy of that plus the new data so we just got this data here so why don't we drag and drop a different image let's see what i've got here's uh this nasa space image so i'll drag and drop this and once it's done uploading it will add it to my state and re-render and show it below here so again this is obviously not saving the data anywhere it's it's still just in the browser so we would want to allow the user to submit that public id back to the server so we can save it in postgres using prisma or mongodb using mongoose or something like that to actually persist this data somewhere so i mentioned these were unsigned meaning any you don't have to be authenticated any user could sort of come here and upload data to our cloudinary account that may not be what we want so the solution to that is to have a signed approach but that involves a little bit more work on the back end so because we're next gs and nextgs comes with a back end we can actually implement a little cloud function in here in our api page i set up called sign and here is where we can basically generate signatures that the front end will use to submit uploads and what you can do here is you could guard this saying only authenticated users can make requests to create a signature for an upload but uh why don't we get started in terms of generating a signature so the first thing we're going to use is this cloudinary package and it's we're using v2 of this and what this will give us is a little function that allows us to generate a signature so i've got some no i don't have copy and paste here what's happening to me perfect so i'm going to link to to how i learned sort of how to generate this so we're going to be very much using this demo here from what they call signed upload video tutorial but it doesn't have to just be for a video can be for sort of anything so we've already got an instance of the cloudinary package and we're going to be using a utility function called api sign request so i'm just going to copy this and then we'll tweak it to make it uh exactly what we need so we'll go inside of our our function our server list function and um this receives two things it receives information about the request and then the response that we're going to send back down to the browser so we haven't actually called this yet from the browser but we're going to do that after we finish creating it so the first thing they want us to do is get a timestamp i'm going to pop this over to const instead we don't need the console.logit and then the next thing we're going to use is this cloudnary package to create a signed request and what we need to pass in are definitely the timestamp and then there's another a bunch of other options you can pass in if you want if you want to eagerly resize the image so that by the time the user requests this it's already been done you can do that we're not going to and you can give it a public id if you want so if you want to predetermine what the file name should be called you can do that we're going to leave that blank but we need to pass in our api secret for cloudinary so where you find this is on here on the dashboard so you can just say copy to to clipboard i've already put it in our dot inf.local file so we're just going to copy that i'll have to change mine after because now the world knows what my cloudinary secret is but coming back here we can paste this in so basically here's all of the options that we want to sign and our secret what this will give us back is a signature and then we need to pass that signature back from the response so that our client can use this as it's going to directly upload to cloud and air so signature we can just get rid of this timestamp get rid of this and because we have these variables defined here that's what it's going to return so going back to the client specifically the place where we're sort of generating the form data that we are going to upload from the browser to cloud and airy we need to get access to this signature and timestamp so what we're going to do here is we're going to say const signature and timestamp is equal to a weight um get signature so that's a function we're going to go and declare just down here below our component so it will be async function get signature and in here we're going to make a request to our own next.js backend this api slash sign path so what we can do is we can say const response equals a weight a fetch to slash api sign and then we'll get the data from that so we'll await the response dot json and then we'll put it into signature and timestamp variables so that we can return signature and timestamp so this was sort of you don't have to do this because that's what is returning to us from the server so you could just say return data here um you could even just say return this but just to sort of be explicit so that the next user what did i do i missed something const data equals a weight response.json just so that the next user who looks at this code knows what the server is returning and then what we're returning from the function i'm going to be overly explicit here and just return it like this so this get signature is being used up here as we're iterating over each of our dropped files into the drop zone that will give us a signature and a timestamp and what we can do now is we can we don't need the upload preset anymore but we can go and we can add the signature so we can pass that up in our request we can add the timestamp timestamp like that in our request and we also have to pass up the uh what is the api key let's yeah api key so we'll append this to our form as well api key so this would come from process dot end dot next public cloud and area key just like this so instead of sending up this preset we're basically saying here's the signature of all of my parameters that are signed here's the timestamp that i'm uploading this as and here's my api key as well so api key is a public thing so you don't have to feel too bad about exposing this on the client it's sort of the only way to do it what you don't want to expose is your secret here like i am so coming back here we should be able to try this again and hopefully we'll upload to our server this time using a signed request rather than these unsigned presets above here we didn't have to change anything here below so we'll come back here refresh the page so that removes our space from state so what we can do is come and uh let's find a new a new image so here's where i normally work in in my apartment so we'll drag this here and wait for it to finish processing and there is the desk so just to go over the requests that were made it first made a request to our own next.js app to generate this signature and this is secure because the only way you can generate the signatures with the secret key that isn't available publicly inside of this next.js app it's only on the server side which is actually secret so here we could guard if we wanted to and only make this available to authenticated users so what we could do here inside of sign is sort of check to make sure authenticated so basically only allow them to get this signature if they're an authenticated user we'll put the old the old to do here so that uh future lee remembers to do that and so that gives us the signature and the time stamp and then we make that upload request posting the actual image to cloudanary and as a response back it gives us all of this information including the public id that allows us to render out this on the screen and a cool thing as i mentioned we can use these transforms in real time so if i just change this to say a 100 width now it's showing us a different version of the image that was generated dynamically so this isn't just a massive image rescaled it's actually a 100 pixel image so if i were to copy this and paste it here that's the actual size of the image and if we were to go into the network request and let's close this we can see just how big they are they're basically one kilobyte so that's the beauty of using smaller images to sort of match the actual size that's needed you're only dealing with one kilobyte size of image versus the bigger ones which were um just say double double or triple the size it's showing a cash version there we go about 10 kilobytes so it's quite a bit smaller for the scaled image so that's all i wanted to cover in this video basically we went and we implemented the drop zone to drag and drop files using this react drop zone with that in place we worked and did an unsigned upload to cloudanary so we first went in here and we created that preset and presets can be can be customized so we can say do we want to um do we want to allow different things like do we want it to generate the different colors in the image for us automatically do we want to include a quality analysis background removal what sort of image manipulations do we want to allow so we can do a whole bunch of customization on this preload up upload preset but that allows us to upload directly from the browser to cloudenary without any sort of backend at all but it comes with some security risks basically anybody can upload images and content to our cloudinary which could cost us money so the solution to that is basically to change to assigned uh passing up a signature rather than these upload presets but for that you need a back end so we created our own signature generator using the sign back end sort of function serverless function that will come with next gs and that will use our cloudinary secret along with the timestamp to generate a signal signature for us we could guard it to make sure that the user is authenticated so that you have to sign up first before being able to upload content but with our little function here that gets the signature we can now upload this image and file to um to cloudanary without using the upload preset and then when we get this back we're basically just putting it into our state and this is where you would when the user clicked save you would upload this to some other backend where you can persist this information about the image to your database so that you can you can uh show it when they refresh the page and whatnot you can see that we're just losing stuff here because we're just storing it in state temporarily hope you enjoyed the video take care bye
Info
Channel: Leigh Halliday
Views: 5,697
Rating: undefined out of 5
Keywords: react tutorial, react image upload, cloudinary, react drag and drop, cloudinary signed upload, cloudinary unsigned upload
Id: V8w7K1HdrFo
Channel Id: undefined
Length: 29min 32sec (1772 seconds)
Published: Tue Oct 20 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.