Build a contact form and send an email with React + Next.js (End-To-End!)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
do you ever wonder what those contact forms on websites actually do today we're gonna build a contact form like you'd see on a bunch of other websites end to end you're gonna build the front end and react next.js you're going to handle the API side with the next JS API Handler and then finally we're actually going to go ahead and send an email once we've built the basic thing we're going to make it look good that's part of our refinement and so it's actually going to be user friendly and then finally at the end we're going to go ahead and see how we can gold plate it a little bit add a little bit extra so let's dive in and get started first what are we actually building before you start coding anything think about the requirements make sure you spend just a little bit of time could be a couple of minutes and make sure you understand what you're trying to build so here if we have our browser window let's say we're not going to worry about the rest of the website right you can drop this into any website that you want we're just going to make the very simple and kind of assume that there's already website built around it right we're building the contact form partless so we're going to have something that asks for your name we're going to ask for your email address and this is just so we can respond later right and then lastly we're going to have some sort of message um message that you want to send and this will be probably a little larger so if this is an input and this is an input this will be a text area and all of this together is your form and this is then going to fire off let's move this kind of over here this is going to fire off an API request right so now we have the server server and this is going to receive the incoming message and do something with it now the reason we need to have the server side of this is everything we have over here in the client this is all going to be public information right someone can look at the code inspect the elements and they can see what our form is doing so what our form is doing is not secret what is secret is whatever is happening on the server we don't want to expose where the message is going or any underlying sort of issues or we don't want to expose basically the secrets of the server right and so we keep all that stuff server-side and the form simply sends it to that and then we'll use generally cross origin access controls cores so people can't just make requests to our server right from their websites that's built in to next.js so then we'll be relatively secure you could make this more secure with a cross-site forgering forgery key cross site forgery access key um but we're not going to go through we're not going to do that so we're just going to assume that this is like a relatively basic contact form we're going to fire it off to the server so that being said we are going to build this so we're going to create next app but I'm going to do something new Dash e is example and I've created a little um let's see GitHub um Ethan Mech do this over here because I don't know what's going to pop up I've created for myself a little Repository next app starter so this is public so I've created a next app starter which will allow me to simply fire this off and it'll use this as a template for our next.js project now this simply installs next uses the app directory and we're going to call it contact form and it will also install and configure Tailwind for us so that way we can just jump right into coding now this does use the app directory in nexjs because the app directory is awesome server components are very cool so if you're going to learn a little bit about that if you haven't played around with them yet so as this loads up and starts fire off visual studio code while we're ready all right so see the contact form and we will launch the yarn Dev in a second so now all right so now you're in visual studio and you can see we already have Tailwind here it's already installed it's already configured so we are ready to go we've also already cleaned up the app directory so we can now double check that we're running everything correctly on localhost 3000 not whatever that was um need to start the dev server fire this off all right and refresh it's always good when you're going through and developing make sure you're incrementally building testing end to end what you're doing so if something's not working correctly you can catch it as soon as possible so or wait a couple seconds for this to go and voila we know it's working even though I deleted all the contents because we can jump over to visual studio and here we can just do hello save and allow that and now we have hello here all right so we need to have a form and the form is going to use the on submit action to capture the input and send it to our API now that is an event handler so we need to make this a client component so we're not even going to worry about too much of the server right now we're just going to go ahead and make this form so export cons we'll just call it contact form um and fire this off I'm also going to turn copilot off here just so we um don't cheat too much right so we're going to return we can do our jsx first here um come on so we're going to return to our jsx first here return the form and we're going to have we said an input this is type text and we'll just do placeholders for right now to make this quick name same thing here this is going to be email and email and then a text area and this will be your message so save and now on the page where you want to include this so it's just going to pull in oh we've needed a contact form that automatically for us save go back to Chrome refresh all right so we have a name here an email and a text area these are all the elements we created not really pretty as of right now but that's okay we know it's working so once again in this contact form we're looking for Pure functionality to start right don't go crazy on making it pretty until you have it working so we're going to have state now there's two ways we can do the state we can either have state stored in one object or we can have three different states for each one um I'm gonna do three different states for each one just to start and we'll see kind of how it looks so here we have name set name equals use state so here we have names that name you state and we can just change this to email correct that and let's just call this message right so set email set message make sure we're importing that and now for each one of these we're going to add in the bindings right so value equals name um value equals email value equals message and then the on change Handler right so here e we're gonna let prettier do all the hard work for us set name e Target value copy that paste it here except this is set email and lastly for the text area on change e set message e Target value same thing all right so now we have all of our data bound up and now we can do const on submit to test this entire thing from working right so this is our form on submit Handler and so we're just going to console.log all the information um it's called Data do name email message and then on submit on submit save go back to Chrome refresh up we need to make mark this as a client component I said that in the beginning and then didn't do it classic always gets me even now so we have our console so if we do enter it will submit update it did not so we need a button here um button submit type submit all right so now we're getting the data which is none so Ethan Ethan test.com hello and then of course we need to prevent the default here so this is a form event so e um run default all right refresh just for good measure get rid of all that okay so Ethan test this should yell at me because it's not a real test email and hello so now we have the form that we've created and we are good to go so the next thing that we want to do is we want to send this to an API so that's going to be in Pages API that's where we're going we're just going to cue a new endpoint and we will call it let's just call it contact and here we're going to dump in um the let's do next.js docs typescript API there's a very specific um their API route their Handler they have a typescript here we go we want that right know where you can copy and paste all the code because that is insanely useful all right so now we're going to respond if we hit this up let's just do the important thing here is to know what data we got right so sending something back doesn't really matter so we'll just keep that for now so console.log data on the server side this is going to be request Dot uh body is the name of it so now from our form we can hit slash API slash contact and send the data and so that's what we're going to do in the event handler so here we're going to mark this as an async method try catch error any and then fetch we'll just do a const res equals this so now we can hit up API contact and for the body we're going to send our content here's a Json object so we're going to just do name email message and that should be sufficient and then the headers we will mark this as um content type application Json so it's a Json request and then we'll wait on it we don't really care what this is and just in case anything goes wrong it's always a good idea to make sure you have this and we will simply record the error so we can debug faster now this is of course going to be on the server right so make sure you're watching those server logs as well so do a hard refresh make sure it's working Ethan test.test.com hello now we submit here um oops we forgot to do method post it is a post request this will Fast refresh you can just try it again all right it worked even though it doesn't look like it here's our contact payload we sent this information and the response we got was that sponsor API server and now when you look at here this is our server data right data you can see that we successfully got it so we're so close we have our contact form which is now sending information we have our API route which is handling that information lastly we need to do something with this information now you can do a lot with the contact form you don't just have to send an email if you don't want to you can send it to slack you can fire off a message into your Discord you can turn it into a text message and send it to your best friend you can make it a phone call and spam your spouse like whatever you want to do you now have control of it now that it's reached the server side you can do whatever you want with this data right just because they entered it in like in this contact form doesn't mean you have to send an email now saying all that we're going to send an email because that's kind of like you know the whole shebang end to end here so how do we send an email we don't really want to connect to an email server ourself we don't really want to muck with SMTP we don't really want to do all that stuff instead we want a email API right this is what we want we want to be able to send an email with an API so send grid is a fine example mailgun is a fine example don't know what that is um mailjet I vaguely heard of any of these are probably fine twilio apparently has an email API you're going to have to sign up for these services and you're going to have to make an account because they are very careful about spam protection and if you are sending spam emails that's something that they're not going to allow right so all of these Services need some sort of an account so saying that I already have an account with mail gun actually so we're going to use that now you don't have to use mailgun I'm just using it because I already have my account right so don't don't feel like you need to use this particular one um at all oh well it's a new browser session so we're going to log in probably could have waited a little bit longer there all right so this is our so this is the mailgun dashboard you can see I have a couple of random domains and stuff but the mg.ethemic.com this is the thing that is already set up to send emails it's the mail gun subdomain that I have to send some emails so we're going to go ahead and use that so I'm going to pop this over here and take a look now what we really need here is the API key and that's what we're going to need to send emails and otherwise we're just going to kind of look at their documentation and use that as their starting point so mail gun send email Docs documentation mail gun I guess we'll do quick start guide sending an email seems perfect this is what we want and they already have different libraries up here we're using node.js so we're just going to fire off this particular thing and jump in so send via API again this is exactly what we want we're going to literally copy and paste this entire thing and dump it in here and then we're going to change it to make it what we need to do so all of this can go up here now they have us add two libraries one is form data so we should need to stop this yarn add save exact form data and the other is their mail gun API itself so we'll go ahead and just fire that off and then we're going to want to import these using the new es6 Imports so import form data from form data import mail gun from mail gun so we don't need these anymore we're going to keep that just in case so now just going to toss update that form data form data we have our mail gun client username API and the API key so this is going to be process.environment mail gun API key because it's not prefixed with next public it's not going to be a public environment variable and then the domain will do the same thing process.environment mail gun domain you have to set these in the environments that you're in and then you'll be able to fire this off so this is going to complain because these can be undefined so we'll just default them to empty strings just in case they don't exist we'll still get an error when we try and fire this off so from contact form and let's call this because let's call it contact um right at M G ethanmec.com that's the domain that we're probably going to use two now this is who we're going to send it to right so here we can just do whoever you want but we'll do my email don't spam me subject new contact form exclamation mark and then this is going to be well the request dot body Dot message so as you remember in our right we have a name we have an email we have a message now we want to send all so long so what we're going to do here is we're going to say hello you have a new um form entry from and this is going to be let's just go over here cons name email message equals request dot body I like to kind of move this stuff around so like it's kind of like that um so from name and then we'll just do a space and then dollar sign email and then we'll just put in the actual message here great so now is our message data and then client messages it's going to create it and then the promise is going to resolve it'll log it otherwise it'll catch it and then we're going to send this off so we're going to do this a little differently we're going to do a uh promise a weight which means we need to make this an async Handler whoops an async Handler um and this is the email response and because it's going to explode most likely catch error any console error error sending email oops Cheese Louise all right so we don't really need this response um you can log it if you want or just kind of keep track of it but we'll just log it for now and then delete it later just so we can kind of see what's happening and then we're going to change this actually to be submitted true just something simple so our API knows what it is great so we need to add a mailgun API and a mail gun domain to our environment so I'm going to create a new environment dot local file at the top level um and this will have this and this will have this so mg ethernmic.com and then we will toss in a sending API key I don't have one for this domain we're going to bring this over here and we're going to save it in here and now fire this off once again let's see if this works end to end so we're going to hard refresh make sure we have the latest of everything latest and greatest this is Ethan we're gonna pretend test.test.com hello world fired off all right well enter didn't work but here we go submitted true and now new contact form boom in your inbox new email from name was not there test.test.com fantastic so the name was blank oh did I just not type a name [Laughter] update I just didn't type A Name all right great now we have that working so end to end we have built a contact form in react and next.js this form accepts three different inputs the name the email and the message you made an API request which accepts it and then it allows you and then it takes that and it sends it off as an actual email to an email you configured we used mail gun as our API provider and that's how you can build this end to end it works but it ain't pretty so let's go ahead and do some refinement so to refine what we've done here we need to really work on our user experience we need to make sure that our user can really go through and use this now I don't have a final image in mind right but I know that it needs to look a lot better and so what we're going to do is we're going to go ahead and say um Tailwind CSS libraries right we want something that plays nicely with Tailwind let's try Daisy UI I've never actually tried this at all right but what we need is we need an input component okay so let's go to data input we need text input what do I look like looks like this there's a border they have labels labels are good primary color primary color seems pretty good accent color this isn't my favorite Library kind of looking at it and it's it's all right but I've never played with it before text area looks something similar so let's go ahead and give it a go again this is what this channel is all about right building stuff experimenting trying it out so let's go ahead and yarn add save exact Daisy UI and then it wants us to add a plug-in in our Tailwind um Tailwind configuration plugins all right Daisy UI so that's the installation then it has a bunch of looks like examples so let's go to use once you've installed it you can use component classes so instead of making a button using the utilities you can just do buttons so now we're like right back to bootstrap right people remember bootstrap you this this was it you you did it this way uh which feels a little bit like a step backwards I'm not gonna lie it's a little interesting um but you know what we're gonna try it out so configuration what do we got here this is our Tailwind style true theme space utils um we're just gonna go with the defaults for now let's see so BG secondary benefits so looks like primary you can use these color names they already have a primary Prime Focus and a secondary and a theme okay how to use Daisy themes let's just see what the default theme is I guess we can keep this up and we'll go from there so we're gonna fire off our Dev server once again we are going to go back into our contacts uh form here and we're gonna go down to this so instead of doing an input right we're gonna just check out the docs this is what you should be doing all the time when you're building something with a third-party Library go text input and we're going to see what the jsx looks like here all right so they just say class name input and then full width to make sure it is good so because let's just go and toss it in here and see what we get input full width okay this is the text area you don't need to worry too much about that we probably want it to be primary to make it a little nicer right so let's do um let's see input bordered input primary looks like kind of what we're looking for here okay it's working not my favorite but it's working um with that let's just go ahead and kind of wrap this all up and put it together so we're gonna do the same thing here um this is probably my guess is text area question mark text area border right any good API is going to be pretty consistent refresh refresh refresh looks like that last one is not it so text area primary jsx text area and text area primary all right well that is correct I just oh yeah okay uh text area primary all right this needs a ton more spacing so we're going to do class name so we're gonna do flex and then Flex column and then we're going to do Gap 8 to give it a lot of spacing between each of these now starting to look like a form we're gonna go to the page and on the main form here we're going to we want it to be centered and we want it to not be right against the top right so margin top let's just pick something big to bump it down the page and then we're going to do MX Auto to make sure this block is put into the middle and we're going to give it a Max width of like I don't know 4 XL all right now we're starting to talk we want labels on this right labels are great for accessibility they're great to show the user what they should be doing and the placeholder shouldn't necessarily be the label the placeholder should show the type of content you want them to add so going back to our form and jumping back over to our input API we want something with a label so they have just a label as their separate thing and they also did a form control label out here so they do label and label alts we're just going to do this around our input so we want a container which is going to wrap all this we're going to ties this in we don't want this label text we're going to keep this simple we'll just say full name and then we'll take this input here and move it up here and now take a look what does it look like all right it's inherited our flexing which we don't want it to do in a bad way so for this we'll do class Flex Flex call because we want them stacked on top of each other and that did not do at all what I expected so this label oh the input sorry we put the input inside the label whoops so we want that Here and Now don't forget to like delete things all right full name boom there you go this didn't really do any styling on the label itself which is kind of like meh um you kind of want this to be let's just do font semi bold full name and then we can do instead of name here for this we can do um I don't even know what a great example name would be me I'm a great example name all right perfect so now we can do the same thing down here right div pull in the div grab the label pull this in same thing and we then want the input inside the div toss it here save go back full name full name perfect except this is email and then the placeholder can be something more useful such as name at example.com all right and then lastly we'll do the same thing for our text area surround it in a div drop in the label take the text area drop it in your message we're not going to have any uh placeholder here was going to let them type whatever message they want and then lastly we want a button that is not quite so unfriendly and so our button here let's do a primary button I suppose seems like a good option button button primary here and we're just gonna add that as the class name button button primary all right so once again we can do my full name Ethan at Ethan pick.com go ahead and email me message hello this is a great form thanks for sharing subscribe all right and then make sure we're watching the network submit 200 okay and our latest email over here fantastic so now we've kind of gone through and refined this really nicely so we you know started with our very basic it worked but basic functionality some of the key things we did was to make sure it wasn't full width this wouldn't probably be full with on a website anyways but anywhere where the content doesn't have to be quite so wide you can just shrink it down and have it take up the center of the page and it'll grab the user's attention and make sure they're focusing on the middle thing and it won't just appear way too wide it's also really nice because then it's easy to adapt to mobile if you're going to do that and we used a brand new library haven't used this before Daisy UI and finally we have kind of run through and created the full form so that is all I would do for refinement on this and you could probably go ahead and send this and ship it and it would be a great contact form but it's not a perfect contact form right like if we really wanted to be a little extra if we really wanted to gold plate the out of this there is definitely one thing I would add what this needs is this needs a thank you page it needs to say yes you submitted we got it we need to give the user the feedback now the simplest way to do this right could be an alert it could just be like a little pop-up it could also be um you could just clear the form and be like well the default action here is you submitted it successfully so we're going to reset the form right but that's that's we can do better okay we can have more fun with this so the important thing is making sure the user understands that their form was actually submitted so we're gonna have a new piece of State here right and we're going to do const um is submitted and then set submitted use state and we're going to set this to false to start right and so now we can set submitted only on if res dot status is 200 . well we'll set this to be true right if it was successful we'll set it to be true so this means that we're going to finish the network request and make sure it was successful before triggering this actual event and now we can add in a catch so here we go what we're going to say is is submitted if that's true then do this otherwise show the form now we need something here so let's go ahead and just add something real quick let's just call it success right we're not going to give them a way to go back because we don't want them to go back we don't want them to submit multiple entries so now we're going to say okay test and test.test.com and test we don't care and submit boom now we have a success page so the success page let's say we want it to be big and bold so Tech Center font semi bold and text let's do obnoxiously big 3XL thank you for your message so now once it's been submitted it says congrats thank you for your message you've gotten um you know we'll take it from here right we can even add something like you know we'll be we'll try and respond to you or we read every message or something to you like that or something cute you want this needs this needs confetti this needs some confetti so let's go ahead I haven't used this library either I swear to guard yarn add save exact react confetti let's see how we want to use this uh we're gonna do react confetti here we're going to say so they have used Windows size but I don't think we actually need to do that right it the recommended but it's going to use the default height that's fine this is already a client component so it's only running on the client right so let's just toss in confetti and then we're going to start this again and then we're going to go back to our lovely little form now we need to refresh the page because we stopped the dev server right so it hasn't picked up any changes but what we want to have happen is we want to have the user to go my great name email at example.com thank you this has been so cool and then they're gonna submit it thank you thank you very much thank you for your message confetti for everybody I guess it just keeps doing this confetti forever which is a lot of confetti um but on the flip side it's exactly the kind of gold-plating shenanigans we're going to be doing on this channel so there you have it end to end we built a form using react next.js we sent an email with nail gun we made it look pretty and then we gold-plated the out of it which is just absolutely fantastic so if you enjoyed this go ahead and give it a thumbs up if you got this far I'm very impressed and feel free to write in the comments anything you would like to see me build or send me an email I wrote it like 13 times in this video so I'm sure you can find it until next time happy coding
Info
Channel: Build SaaS with Ethan
Views: 7,701
Rating: undefined out of 5
Keywords: react, next.js, mailgun, mailgun.js, contact, contact form, email, gold-plate, software, coding, technology
Id: Te4ESNxq_xU
Channel Id: undefined
Length: 43min 37sec (2617 seconds)
Published: Wed Feb 08 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.