How to Upload Images to a Server in Next.js | Nextjs 13

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello and welcome I'm Dave today we will learn about an easy way to upload images in next JS using the app router and API routes and I'll provide links to all resources in the description below I'll also provide a link for you to join my Discord server where you can discuss web development with other students and you can ask questions that I can answer and receive help from other viewers too I look forward to seeing you there today is all about quickly adding image uploads to your next JS app and we'll be using the app router and API routes you can use an upload button or you can use a drag and drop approach I'll be giving you the code for both let's take a look after we create a new next JS app okay I've got vs code open and I've opened a terminal window so let's type npx create Dash next Dash app at latest and it's going to ask us a series of questions here and the first one is what is the project named I'm going to call this upload because we can actually upload more than just images with it but I'm going to focus on images after that we'll use typescript yes to ESL yes for Tailwind yes for the source directory and yes for the app router and we won't customize the Imports but of course we will use them so that will just have the basic that we're always used to with next.js and this will quickly install and then we'll get started we'll be using upload thing today you can see here in the top left that it's still in beta but they've been adding more documentation and that's a good thing I think it's working well so let's go ahead and apply that to our project today for quick and easy uploads in next JS so first you need to sign up and then sign in if you haven't signed up already I'm going to just sign in because I did already sign up and you can just do that with GitHub it's quick and easy and we should be in here in a basic area here where we can create up to two apps so go ahead and create a new app after you sign up and sign in of course it's free and once you do that you'll just name it so I'm going to name this just test Dash app today and this is optional so you don't need to apply a URL right now it'll go ahead and create that app okay now we have a nice dashboard here for upload thing and let's click this getting started link where it says read more the first thing you need to do is install the packages so you can see we have a line of code right here where we're going to install just a few things you can just click the copy icon now let's head back to vs code back in vs code in our project I'm going to control and backtick to open a terminal window again I'm in Windows it may be different if you're on Mac or Linux but I can just right click and paste that line of code in that I copied from the docs press enter and we'll install these dependencies after the install they'll be listed in your package Json file back in the documentation the Second Step under getting started is to add the environment variables it lists one right here but we're actually going to need a couple also notice this note here if you're not applying through versel you may need need to apply another one which is an upload thing URL so if you're not going to use versel to deploy the use of upload thing make sure you note this as well to get our environment variables let's go to the dashboard link and now that we're at the dashboard link we're going to go into our test app we created then I'm going to click on API keys and they give both that we need right here and you can again just copy those by clicking this now let's go back to vs code back in vs code here at the top level same level we have our package Json we need to create a new file name it dot env.local and here's where we'll go ahead and paste these API Keys now I can press alt Z to wrap this down so the first one's very long now I'm going to delete this project after this tutorial so no trying to use my keys as they won't work however you want to do the same thing that I just did to create your keys in your own.env.local and save that file we're back at the the upload thing website we can close this dashboard where we got our API keys and now we're looking back at the docs which you see the docs do support a dark mode which I'm using the rest of the site does not currently that I've seen that would be nice if they did and let's go ahead and move on to setting up the next JS application and down here is the link and you can use the old version of nexjs with the pages router or you can use the new app router and that's what we're going to do so while we're here it says create your first file route and you see the code here for app slash API slash upload thing slash core dot TS so we're going to need to create this in our project and we can copy all of this code and then we'll go over what it does now let's go back to vs code and start making our project a little more customized with the things we need so we know one of the first things we need is in the app directory we're going to want to create another directory named API and then in the API directory we're going to want an upload thing directory and then inside of this directory the first file we had was core dot TS and this is where I'm pasting the code that we just got from the documentation and we will go back over this but let's go ahead and set up the rest of our project before we head back to the docs so inside the app directory I'm going to create another directory and I'm going to call this upload dash button so we can look at an example of the upload button application and then I'm going to create another one in the same level here I'm going to call this upload Dash DND for drag and drop now that we have both of these directories let's go ahead and create basic Pages inside of each so page.tsx we can RFC and we get our basic application here I just use that shortcut with es7 react Snippets and we could call this upload DND for this component and now when we create a page here for the upload button we'll of course call it upload button so we'll RFC once again and then we'll call this page component upload Button as I think about this component name it may actually conflict with what we get from upload things so instead of just upload button let's call it upload button page just so I don't have a duplicate name in there and now I want to put links to both of these paths in our main page and we'll just use what's provided with the basic project already so let's just scroll down below the image that we'd have here not that for cell logo but this one right here the next JS logo that is 180 wide by 37 for the height let's just create a section to put our links here so I'm going to have a div and I'm going to apply a few classes here so Flex justify Dash evenly and also W Dash full and not put the Tailwind classes on there for me now inside of here we're going to have links which I believe the link was already imported for this example page and let's go ahead and link to both of those routes so this will go to slash upload dash button and we could say upload button here and then let's go ahead and put in one more link and this will go to slash upload Dash DND but upload drag and drop here and it is possible that link is not imported yet as I see the red squiggly here from typescript so let's go to the top and see if we need to import it and yes we do so let's import link comes from next link and now we should be good if we scroll back down and check out those links so these will show up on our page just so we can click and go check each path or use each different feature okay with this much in place let's go ahead and run our app so we can just check it in the browser to make sure everything is working as expected so far so now I'll control click on the localhost 3000 and it should start up the basic project that you get with next JS so here's our basic next JS project and you can see we now have a link to upload button and a link to upload drag and drop so we can check those although there are blank pages that just say page right now but our links are working so we should see anything apply as we go ahead and modify the code for our project back in vs code let's go back to this core.ts that is in our API slash upload thing directory now there's lots of notes they include here lots of comments to go along with this file so let's just work through it quickly they give us a fake auth function but essentially where you would want to apply auth if you were using it or to get that auth data here they're grabbing the authorization ID or the user ID and they're just calling it fake ID so they're going to call that in here in the middleware where you would do that but this really doesn't do anything with this example notice they are importing create upload thing and a type file router and then they are creating an upload thing and just calling it f here probably short for file but let's just go with that now and go into our export const our file router now this creates a file router and it can have more than one route we're going to look at one route first and then I'll show you how you can add others as well and a few examples of that so here's the file router for your app and as it says it can contain multiple file routes Define as many file routes as you would like each with the unique route slug here's the route slug image uploader now notice here it says image and it's giving a Max file size for the images at four Megs now different values can be applied here and I believe it's a literal type so they're specific on what values you can put in here now besides Max file size if you want to be able to oh and here we can see those actually when I hover over Max file size this besides that if you want to be able to select more than one image for example with this image uploader you can also put in a Max file count if not it's going to default to only allow you to select one so let's put in a Max file count here and I'll make that 10. now let's look at the middleware that is changed notice the dot middleware here so it's Chained and this is where they'd put that auth function likewise you can say if you aren't authorized you're throwing an error and then they're just returning that user ID here which once again would be fake ID in this example so that's all they're using this middleware for is to just check the authorization that's going to be important because if you're using some other type of authorization to protect routes you're not going to be able to protect that route for upload thing because it has a callback that their service needs to be able to access as well so you need to leave that open but then you want to make sure that the route is authorized for example so this is the way you would do that now here's the on upload complete and this runs on your server after the upload so right now it's just going to log to the console upload complete for user ID note which console we're talking about here this runs on the server so you're going to see this in your terminal like you would for node.js not in your browser console and then they're going to console log the file URL now we talked about possibly adding more routes to this it says you can add as many as you want as long as they have a unique route slug like we see here with image uploader so let's look at some examples of this in the docs okay we're back in the upload thing docs and I'm going to go to the API reference and click on the server tab down here now let's scroll down to where we see file routes and you can see they have an example file router and it has several different routes here's one called profile picture that only accepts images here's one called message attachment that accepts images and videos as strict image attachment so it has a max file count of one a Max file size of two Megs so it's strict it's only images as well here's a media post so image and video as well so there's several different ones here and we could just take one of these examples so let's just grab this last one that says media post and we'll grab this and put it in our code there is one correction here and I know this just from working with the docs this 200 megabytes value isn't actually allowed so I know it's in their documentation but once we get in our code the types set for that the values that are acceptable it won't accept that one so let's go back to vs code and put this extra route in our file route okay back in vs code we've got the image uploader right here and it's using our upload thing that we created here called f so we come down here and there is a comma and now we can just put in this next route and I can save this but notice we do have an issue with the max file size as I said that size isn't allowed so let's look at what is allowed and it says up to 21 more now we could dive into the types which we could do in the node modules here let's take a quick look we go node modules scroll all the way down to upload thing if you want to see what values they have in there which is good to do especially if something's being developed because you might find some things that aren't documented yet and I did find one or two so now that we're in there let's open the disk folder and we want to go to types let's find that types dot d dot TS oh I believe I need to open up the source directory as well there we go now types.d.ts here we are we found a lot of things now there's a couple of things that we should note here one is let me press alt Z so this code wraps down in the docs it says images video I believe audio and blob are acceptable but also text and PDFs can be uploaded with upload thing that they have in here so here are the different values that we can put in notice 200 is not in there so we could put in maybe 256 in our typescript problem would go away so just highlighting where you can find these types for upload thing in your node modules and that can help you discover a few things like we just did about a couple of other file types that are acceptable and maybe some values that we could add to use here instead of 200 Megs so let's go ahead and say 256 megabytes and now no red squiggly no error here so just change that note as well here in the comment and now we've added a second route to our file router so we have our image uploader and we also have a media post and we could refer to either one where it's needed and I'll show you how that's used very shortly back in the documentation we kind of detoured to the API reference to look at this example but let's go back to the app router setup let's scroll down to where we were we've created the core.ts and reviewed that and now we need our route.ts it's very simple overall and we can once again just copy this code so let's copy this and we'll go back and create the route.ts back in vs code we want to create route.ts in this same spot here so API slash upload thing and then we'll create it right beside our core.ts file here so route dot TS and now let's paste in that code we got from the docs and you can see we're importing create next route Handler from upload thing slash next and then we're importing that file router that we created in our core.ts file and then we're just saying hey use the file router we created here in this route now back in the docs for this route TS file we really want to emphasize here this is the only file where the path really matters so it's specifically has to be right there in the API slash upload thing slash route.ts also make sure you don't block that with your auth because it's going to need to be able to use that web Hook and the Callback so their service needs access to that file and remember you can call auth in your middleware but you can't block the path to the file now let's scroll down and it says use the file router in your app and it gives an example here of a client component using the upload button and that's right here we can also get this example of course this is the end of this page we could also get this example in the API reference here under react and they show an upload button here so there is no copy here I guess let's just go back and let's copy the code that they gave us at the bottom of this page there's the copy so we're using that and let's go back to vs code and put this on our upload button page we're back in vs code let's make sure to click the page under upload dash button for that path and now let's go ahead and just select all and we'll rename the component again here so I'm going to paste everything in that we got from the docs press alt Z to wrap any code down and now let's make a couple of changes and so this isn't going to be the home component let's once again call this upload button page and now let's look at any other issues we have and one is an import here so we don't quite have the right path for the import we actually need to go up one directory and that means we need a second dot right there after we do that the file router imp Port is just fine notice we're also importing some styles from upload thing here to help style the button that they're giving us for this page we're importing their upload Button as well and now as we come down here they've also provided a few Tailwind classes already so everything's pretty much in place and we might make some changes to this let's go ahead and save it and check out our app in the browser we're back in the browser I'm going to click the upload button link from the home page and now we have our upload button and notice it took the settings already and it says images up to four Megs Max of 10 meaning Max of 10 images so it also displays those restrictions we've put on our upload button so now we can choose a file so let's just look at the basic behavior from their example I'm going to choose the Zod logo here and click open it instantly gives us a spinner it's uploading the images and then gives us an alert when it is complete and that's all we get so let's make a couple of chain changes to make this look a little nicer we'll keep them simple though back in vs code let's scroll to the top of our upload button page we're going to bring in a couple of more Imports here so I'm going to import use state from react and I was hoping to find it there but let's go ahead and start with the curly braces use State and that will come from react and then I also need to import link from next.js and that comes from next link okay after both of those are imported let's scroll down just a little bit and use State here inside the component so I'm going to say const and here we're just going to do images so I'll say images and comma and here I'll say set images let's set this equal to use State now we're going to need to put a type on this here eventually as well and it's going to be an array now let's scroll down into our upload button component here and let's look at this response what is it supposed to be or what type do we have so here we have an object with a file URL and a file key and it's in an array or undefined so let's go ahead and expect this response here through the array and we'll copy that and now where we have you state let's go ahead and put that type here so inside of our less than greater than symbols we will put the type in there and show that is an object that has file URL and file key but I shouldn't have copied this res right here let me just get rid of that and it should be happy there now we have the exact type of our state let's also change one class here from the classes they gave us for Tailwind instead of justify between let's make this justify start so we just put everything towards the top of the page and now let's go ahead and create just a little bit of content to put on the page that we can show as well so first I'm going to have a title I'm going to set this equal to checking our state which is images dot length now we know we have an empty array so we can at least call length either way even if we don't have anything in that and we'll make a ternary here so I'll use parentheses I'll use a react fragment here and inside of this fragment I'm going to have a paragraph and say upload delete and then one more line and here we'll put another paragraph and we'll give it a class name of a margin top Dash 2 just a little bit of space there and we'll put in the images dot length essentially showing how many files we have and putting files after that so that'll just be at the top after the button after we've uploaded some images now here we can say if there is no length we can just return null okay after our ternary let's go ahead and create our list so we'll list the files that are uploaded after it's successful so I'll call this image list and here we'll put some parentheses so we can break this down to other lines and the first thing I'm going to do is put a react fragment again and then inside the fragment we'll start with the title we just defined above and after the title we'll need an unordered list and then inside the unordered list let's map over the images so we'll have images.map then each image and we'll come here and use another parentheses now inside of this let's go ahead and put our list item and let's give it a class of margin top Dash 2 as well we're also going to need to provide a key here so let's make the key equal to the image.file URL that we should receive so each one of those should be unique also now inside of the list item we're going to provide a link that we already imported from next.js and let's set this href where it links to to the image dot file you are not fire file URL and then after that let's give the target equal to underscore blank so we open up a new tab so we're not really getting rid of our app when we go navigate to view the image either and now let's look at the image.file URL here for display as well so not only are we linking to it we're displaying the URL as the link and then finally let's just take this image list and we'll display it it's created underneath everything else so in still in the main element here inside of the main element but after the upload button we'll put in our image list and now before we try to check results in the browser we need to take advantage of using State because we haven't set our state yet here inside of the functions so let's do that let's check to make sure we have a response first so we need to say if then we'll say if res then we're going to take action here so let's go ahead and put this do something with the response part inside of here because we'll only do something with it if it exists there let's go ahead and comment out this alert because that's going to be displayed on the page as well but I'll leave it in here for you so you can see it in the course resources and then let's go ahead and do a couple of other things we need to set the state so we'll set images two res and then let's also Define some Json because that's really what I want to see inside of the console if we log to the console so I'm going to say Json stringify and here I'm going to pass in the response and then where it says files and res we'll just delete that and we'll just log the Json right there okay with these changes in place I think we're ready to check it all out in the browser I'm back in the browser and we're on the upload button page let's reload just to be safe probably not necessary but I like to do that just to make sure I've got my changes there now let's go ahead and choose files to upload I'm going to choose Kansas Cities and lasso I'll open those up let's see what we get on the page if the upload is successful so we've got our upload complete it says there were two files and it lists both files so here's the URL for both we can click one of them and then it opens up the image hey The Big Lebowski as applied to Kansas so we see the image here on its own URL we can come back to the app as well now let's do the same for our drag and drop page but it won't take nearly as long we are back in vs code I'm just going to copy everything on our upload button page with control C after I use Ctrl a to select all and then go to the upload DND path which is drag and drop here I'm going to select all once again with Ctrl a and then use Ctrl V to paste everything in I'll scroll up here and rename the component once again so I'll call this upload d and d and then we're just going to change a couple of things on this page to use the Drop Zone instead of the button so instead of upload button this is going to be upload drop zone that we get from upload thing slash react and now we can scroll down here and where we previously had upload button we're just going to change this to upload Drop Zone and that's just about all the changes we need to make now I do want to highlight one thing that I didn't mention as we created the previous page here's the endpoint image uploader so that's where the slug goes so if we wanted to change to our other slug that we put in our other endpoint in our file router this is where that name would go so maybe you would create an upload for PDFs and text files and you could have a different route for that and you would have a different name for that so with this saved let's go back to the browser and check out our Drop Zone back in the browser I'm going to go to the home page first so I'll just go to localhost 3000 now let's click the upload drag and drop link and here's our drag and drop area and it says you can also choose files so I'm going to click choose files notice it opens up here to our folder where I could do this I'm going to try to just drag one over to our drag and drop area Let It Go and I can close this it says upload one file and of course we could put more here it says Max up to 10. I'm going to click upload one file and let's see the the result after the file uploads and yes it says upload complete one files I guess I could change that so it would just say one file if there was only one but here's the link to that file let's go ahead and click and it's a huge image of Ted lasso and Coach beard so there we go we've applied both okay we're back in the upload thing dashboard for the test app that we created so we're already inside of the application and this is the dashboard notice it says four files all time and four files uploaded in the past month we're only using just a little over seven Megs of a free two gigs of storage so this could hold quite a few and it gives the list of the largest files and recent uploads here as well so a useful dashboard we can click over here to files and we could look at our files and say we have a duplicate that we want to delete you can delete the files right here now there are some other features in upload thing that you could read about in the docs including if you know the IDS right now you could send them those IDs or those file Keys essentially to delete files from an app if you wanted to as well but it's very easy here in the dashboard and overall very useful do note that the files are not compressed they're just as big as what I'd originally sent up so I said that lasso file was the biggest it was three Megs it took just a little bit longer so no compression is applied so the big question overall after we've applied this and I hope it's useful in your applications I do like it but is it an S3 killer that's what Theo said when they came out with this and you might have been joking a little bit but I don't think so I think he's saying hey this is something I needed S3 is difficult to work with and we wanted to make something simple I think goal achieved it's pretty good for any kind of small usage and it's free as it currently is they haven't figured out a charging process yet maybe they will in the future so let's talk about this how does it compare to using an S3 bucket what I'm talking about S3 that's Amazon storage and where you would store images or files in the cloud they're on Amazon if you're not familiar anyway one of the major projects I created for a job in the last few years was an image management application and it used S3 and it was definitely more difficult I really like how you can easily add upload thing to an app quickly that said there's some features that S3 provides in its SDK that aren't here yet maybe they wouldn't be here as a free app and the biggest missing feature for me is really just a get all Edition they have some server utilities if we look back at the docs and you can go to server scroll down I talked about being able to delete files so here's their delete files here's the get file URLs so you need to have a file key essentially or a file name to get some of this information in return it would be nice to not need those and just be able to request all of them or if you had say hundreds of files maybe you would get a paginated response as well something like that and I can do that with S3 I'm not able to do that out with this right now but really that's a small limitation compared to how easy this is and once again it's free if you're interested in a good breakdown of how upload thing works behind the scenes one thing is they open source all of this already so if you go back to the very home page if we go to upload thing here I'd have to log out probably to see it let me sign out and now it says announcing our open source release so you can check that out also there's a great video by Josh tries coding where he broke this down and created his own version so maybe you want to really dive in and see how it works behind the scenes and in the future I may very well be revisiting the upload topic and creating something from scratch as well remember to keep striving for Progress over Perfection and a little progress every day will go a very long way please give this video a like if it's helped you and thank you for watching and subscribing you're helping my channel grow have a great day and let's write more code together very soon
Info
Channel: Dave Gray
Views: 31,289
Rating: undefined out of 5
Keywords: how to upload images to a server in next.js, upload images, uploading images, upload images to a server, next.js, nextjs, next.js 13, nextjs 13, next.js with app router, next.js app router image upload, next.js image upload, nextjs image upload, uploading images with next.js, uploading images with nextjs, upload images to a server with next.js, upload images to a server with nextjs, upload images with next.js, upload images with nextjs, image uploads in next.js, image uploads, js
Id: OyxDGWgNJMc
Channel Id: undefined
Length: 31min 3sec (1863 seconds)
Published: Fri Jun 09 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.