Build and Deploy a Modern Full Stack ECommerce React Application with Stripe

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi there and welcome to a project video where you'll build and deploy a fully responsive modern full stack e-commerce application with payments we're talking modern design animations the ability to add and edit products on the go using a content management system all advanced card functionalities and most importantly complete integration with stripe so you can cover real payments this is the best ecommerce website project that you can currently find on youtube in this video you'll learn advanced react best practices such as folder and file structure hooks and refs advance state management of the entire application using react context api nextgs best practices such as file based routing data fetching that allows server-side rendering and static generation which makes your websites incredibly optimized and you'll also learn how to use nextgs as a back-end endpoint next you'll learn how to integrate stripe to manage payments products shipping rates and the entire checkout process and most importantly you'll learn how to manage the entire content of your app using sanity sanity is the unified content platform that will make the making of our entire app possible through sanity you or your clients will be able to change the store's home page and more importantly the details of all the products in the store instantly and on the go sanity allows us to focus on developing the application without having to worry about the content file storage and databases they'll cover all the dirty work for us and allow us to build scalable and modern e-commerce web applications extremely easily if this video reaches 15 000 likes i'll create more videos just like this one subscribe like and let me know what you'd like to see in the next one in the comments in the end we'll also deploy the app so that you can share it with your friends put it on your portfolio and get a job you can also turn it into a real e-commerce and sell your products or even better start building many e-commerce stores for your clients and earn money [Music] before we dive into the development let me give you a really quick demo of the entire application this is our store's home page we have a big banner indicating our featured product then we have a list of all of our best selling product with a nice on hover animation and finally we have a beautiful sail banner at the bottom right here and as i promised the best of all is that everything you can see on this page can be dynamically modified and that is only possible because of sanity let me show you how it works live we can modify the content for our banner as well as all of our products for example let's go into products and let's go into these headphones right here as you can see we can add or change the images the product's name the unique slug the price and the product details the same thing goes for changing every single little detail in our banner component as you can see right here in this course you'll learn how to use sanity from scratch so that you can use it in all of your future projects going back to our app clicking on a specific product will open its product details page here you can see the product title as well as the number of reviews description and price you can also hover over the thumbnails to see the images in more detail there's also the animated you may also like section where you'll get the recommended products for the item you're currently viewing hovering over it will stop the animation and you can select another product you can change the quantity and add the product to the cart so let's go ahead and add a few products let's go for these headphones as well and let's click buy now by opening the cart you can modify the quantities of each individual item as you can see right here and you can also remove them from the cart finally when you're ready to purchase you can click the pay with stripe button that'll lead you to a special stripe checkout where we have a nice overview of our order here you can enter your payment details choose your shipping method and finally complete the purchase and once you're done with the purchase you'll be redirected to a special success page and of course the entire website is completely mobile responsive so as you can see as we scroll you'll notice that it feels like a native mobile application everything is fully mobile responsive so that's it how do you like it it's a phenomenal full-fledged e-commerce application i hope you're hyped so without any further ado let's get straight into it to start off with creating our amazing ecommerce application we're going to start from scratch we are on our desktop have an empty visual studio code window open and we're going to right click and create a new folder called e-commerce there we go the only thing you have to do is simply drag and drop it into your empty visual studio code window of course feel free to use your own code editor of choice in this case we're using visual studio code as it is the most popular code editor out there it also has a great integrated terminal so you can go to view and then terminal we can clear it and in here we can run all the necessary commands to initialize our application in this video we'll be using next.js it's going to make our react application even quicker and the website with all the products is going to load incredibly quickly nexgs allows us to statically render all of our websites making them incredibly efficient so all that we have to do to initialize a nexus application is to run the command mpx create dash next dash app and that's it run it it's going to ask you to install the create next app package so just press y there and press enter you'll have to enter the name of your project in this case i'm going to type e commerce and the process of installation is going to begin and we should be able to see all of our code in just a minute i'm gonna pause this video and i'll be right back as soon as it is done as soon as our app is initialized we can open up our explorer and see that we have a new folder right here with some more files and folders this is a next.js structure the most important thing here is the pages folder where we'll be creating our components and pages as we go along we're going to add a few more folders to keep a nice and a consistent folder and file structure before we spin up our application let's first install all of the necessary dependencies and packages that we're going to use in our project right now we only have next react and react dom down in the description there's going to be a github gist file containing all of the code that i'm going to reference in this video the first thing in there are going to be all of the necessary dependencies so just hover over these lines and override them with all the dependencies that we have to install the dependencies include sanity and sanity image url of course we're going to use this to dynamically change all of the content of our banners and our products we're gonna also use stripe which is one of the most popular payment gateways allowing us to process real transactions right inside of our application we're gonna also use a confetti package that's going to show that nice confetti once the order is fulfilled we're going to use the next sanity image to process images and stripe itself we're going to also use react hot toast to provide that nice banner as soon as something happens like a notification and finally react icons for all of the great icons the only thing we have to do is first cd into the folder that next.js created for us in my case that's going to be e-commerce you can check that right here that we are inside of a new folder created for us by nexjs so now we moved into it and then you can run mpm install dash dash legacy dash beer dash deps this is going to make sure to install exactly the same versions of packages so that whenever you're watching this video be it after a year or two years you'll always be able to replicate exactly what i have in this video run this command let's wait about a minute and i'll be right back and there we go once all of your dependencies install we can finally spin up our application on localhost 3000 by running the mpm run dev command immediately you can control click or command click the localhost 3000 and it's going to open up the demo page right on your localhost that means that we are ready to configure sanity which is going to allow us to so much more easily manage the data for our entire e-commerce store throughout our entire application development so let's go ahead and set it up right away to start off you can click the link in the description sanity team was kind enough to provide you with double the free monthly usage and that includes 200 000 api requests 1 million api cdn requests and 20 gigabytes of bandwidth that's going to be more than enough for 99.9 of people myself included and that's great because it means that we'll be able to build our ecommerce application from scratch to finish and deployment completely for free using the newest and most modern technologies sanity is of course going to be of great help here because they're a platform for structured data that lets us build better digital experiences essentially all of the data for our products and banners on our store are going to be managed by sanity you'll soon see the amazing benefits that sanity offers so to get started let's simply copy this to our clipboard let's open up our terminal by pressing ctrl and then backtick or going to view and then terminal let's stop it from running by pressing ctrl c and then y and we can clear the console finally we can paste what we copied this is first going to install sanity cli globally and then you need to press enter one more time to initialize sanity and to apply a javascript mastery coupon now there might have been some additional prompts that i didn't see right now because i have already used sanity before if you haven't you'll most likely just have to say yes to install sanity and that's about it as soon as you're done with that we'll have to log in to our sanity account and for that i'm gonna use google so simply press enter and there we go login successful back in our terminal we can immediately enter our project name i'm going to say e-commerce we're also asked if we want to use the default data set configuration and to that i'm going to simply say yes or why the data set is being created as we speak we're fine with the project output path so i'm simply going to press enter and we can choose a template for our project there is a movie project an e-commerce project a blog and a clean project with no schemas we are building an e-commerce site so an e-commerce template would make a lot of sense but as you already know here in javascript mastery i always take you one step at a time and one step further so we're going to start with a clean project with no predefined schemas so that i can teach you exactly how you can use sanity and how you can use it on all of your future projects there we go creating default project files and resolving dependencies and there we go the setup has been successful before we can check out all the great things that we can explore with sanity we can notice that git is tracking all of our active changes and there's more than ten thousand so what you can do is go to dot get ignore and then instead of just forward slash node modules we want to simply say node modules without the forward slash that's going to make sure to include the node modules inside of the ecommerce sanity project as well with that simple change you can go to your git and then click right here to reload it and you should be able to see only 21 changes great with that said we can now explore our terminal and see that there are many commands that we can test out to explore what sanity has to offer we can start with the first command which is sanity docs this is going to open up the documentation right inside of your browser and you can use the search to really learn about anything you need now we can explore the sanity manage command this is going to open up your sanity manager and from there you'll be able to choose your current project we'll have to get back to this page later on to give us all the permissions we need to properly set up our application and to finally get access to our content we can cd into e-commerce this time we're into sanity e-commerce i know this is getting quite repetitive i didn't really anticipate to have this many e-commerce projects but the original e-commerce one is our nexus application and then the inner one is going to be our sanity studio so it might be a good idea to rename it so i'm going to simply rename and that's going to be sanity underscore e-commerce so now we can cd and then we can cd into sanity e-commerce inside of there you can run the sanity start command and this is going to spin up the content studio on localhost 3333. if we go there you'll have to log in and as soon as you do you'll be able to see that now we have an empty schema right here not much to see right but as soon as we adding our schemas inside of our code this sanity desk is going to start looking much more appealing and feature full and that brings us to the next task and that is actually accessing the files and folders that were created for us automatically most importantly the schemas folder right here for now we just have one schema as you can see right here but soon enough we're going to add the schema for our projects as well so i'm going to teach you how to do that from scratch right away so to create your own custom schema you can right click the schemas folder and create a new file let's call it product.js inside of the product the only thing you have to do is say export default and then export an object this is all that it is you don't have to use any special syntax you simply export your schema as a basic javascript object a sanity schema needs to have a name and in this case that's going to be product the title is going to be product with a capital p and then we also need a type and a type of this is going to be document finally the most important thing is to provide the fields for our schema the fields are going to be object-based so we can create inner objects inside of the fields array and the first field is going to be our image so we can say name is equal to image the title is going to be an image with a capital i and then we also need a type and this is going to be array so we can have an array of images and check this out see how i said that an array of images so what sanity did is created an off property and we can say array of type is equal to image almost like talking in plain english an array of images and we're going to also provide an additional options object right here where we can say hotspot is equal to true and if you don't know what that means what you can do is go to sanity docs and search for hot spot there we go you can immediately see that this is a property on the image tab let's search for hotspot and let's see what does it mean enables the user interface for selecting what areas of an image should be cropped what areas should never be cropped and the center of the area to crop when resizing essentially just helps us to better position the image we upload and you can see that it is a boolean so whatever you want to do it is incredibly easy to search the docs for it and then implement it on your own now we can go to the next field which is going to be below this object this one is going to be a bit simpler name is going to be name the product name the title is also going to be name with a capital n and finally the type is going to be string nothing extra we have to pass right here next we're going to have a slug a slug is like a url like a unique string so the name is actually going to be slug then the title is going to be slug as well with the capital s and type is going to be slug so as you can see sanity has built a custom type for unique identifiers we can also provide the options and we can set the source of our slug which is going to be name so it's going to automatically generate a unique slug based on our name property we can also provide a max length property which is going to be set to 90 characters that should be more than enough finally every single product of course needs to have a price so we can say name of a new field is price and also title is going to be price as well the type is going to be number and the last thing we can add is going to be another field where the name is going to be set to details and finally title is going to be set to details as well and the type of details is going to be string as straightforward as that we've just created our product schema there is going to be just one more additional schema for this entire ecommerce application and that is going to be our banner.js file since we've just explored the way to do schemas and the ways in which you can create fields arrays of fields options and more to save your time down in the description in that github gist file there's going to be the banner js file right here you can find the schema for our banner as you can see there isn't any logic happening here we're just again setting some of the similar fields that we had before just some strings names products descriptions and so on everything is right here so again i just wanted to save your time go down in the description copy it paste it here and we should be good to go we are therefore ready to use those schemas inside of our schema.js file first of all let's remove all these comments just to have the easier view right here because i'm guiding you and then we can import our documents we can do that by saying import product from dot slash product and we can repeat that one more time by saying import that's going to be banner from dot slash banner the last and only thing we have to do is we have to add our documents right here that's going to be product and banner inside of this array that is it now let's go back to our sanity desk that's going to be on our localhost 3333 and as you can see now we have our product and we have our banner let's go ahead and add one demo product so we can create a new product right here we immediately have a nice looking interface where we can enter the product image i've uploaded this great looking image of headphones and if you want to use the same images that i'm using throughout this entire project the link to the assets is also going to be somewhere down below either in the gist file as a zipped folder or somewhere else but you'll definitely be able to find it if you want to replicate exactly what i'm doing in this video so let's close this and let's choose a name i'm going to go with headphones right here and now a cool part here is that the slug can be immediately generated headphones without any extra numbers or letters because this is the first instance of the headphones but if we were to create another one then a unique slug would be automatically generated for us let's go with something like 99 for the price and the details can be great looking and sounding headphones and we can click publish there we go a new document was just published and we can see it right here under product category and under products amazing what they've done just now is basically implemented an entire database think about that we've created a schema and added the ability for users to add new content to that database how crazy is that imagine if we're working on a marin application mongodb express react and node imagine how much time we would have to spend just to come to this point where we're at right now it would take hours to set everything up but we've done it in just a couple of minutes and now that sanity is fully configured and set up our backend is fully done now we can start creating our front-end duplication and then later on we're going to connect the two phenomenal for our front-end we are of course going to use react.js well technically nextgs which is a framework for react it's going to give us access to that beautiful development workflow that react offers but with even faster and more optimized page loads so with that said i hope you're excited so let's get started we can start inside of our pages and inside of our index.js page this is our main page so what we can do is delete everything that we have in here so far let's just make it a clean slate and you know what we can actually remove everything we have in here we can use that shortcut r a f c e react arrow function export component and simply press enter if this didn't work for you that must mean that you don't have the necessary extension installed that is es7 snippet so if you search for that you should be able to find es7 plus react redux react native snippets simply install that go back type rafce and you should be able to see this code output if it didn't work simply type it out by hand but in any case we are ready to start creating our index page of course to be able to see what we're coding in real time we can open up our terminal press ctrl c and then simply cd out of sanity e-commerce and then run npm run dev to run our application on localhost 3000. there you should only be able to see small index right here now i'm going to pull the browser and visual studio code side by side so that we can see everything at once and there we go we are ready to proceed now you might notice that we have this red squiggly line right here cannot find module next babel to easily fix that we can just go inside of the root of our folder ecommerce and we can create a new file called dot babel rc inside of there we can create an object because this is a json file and then we can write presets is going to be an array of one string that's going to say next babel like this and then we also have to go inside of the dot eslintrc.json we're going to switch this extends from a string to an array and then as the first property in that array we're going to say next forward slash babel and then add a comma like this now we made a change here and also a change here make sure that you have the babble inside of the root of this folder not outside of it and then if we go back to our index.js now you can see that problem is entirely fixed and we are ready to proceed with the development we can start by renaming this to home that's going to be a better fitting name there we go and finally we can start with the jsx so we're going to have one div or rather one empty react fragment wrapping everything inside of there we're going to have a hero banner component for now let's simply leave it as a text hero banner below that we're going to have a div and this div is going to have an h2 that's going to say best selling products like this we can also add a p tag below that's going to say speakers of many variations of course feel free to type whatever you prefer here this is going to be that nice looking banner as soon as we implement the styles finally in here we're going to also loop over our products so we can create a div right here and we cannot yet loop over our real products because we haven't fetched them from sanity but let's create an array of for example a string of product one let's also do product 2 and let's simply call a dot map of course this has to be in curly braces how could have i forgotten that and then we get an arrow function we get a product for each one of the elements we're mapping over and then finally we can simply return the product component for now that is simply going to be the actual product name itself so you can see product one product two later on these are going to be real products and finally we're gonna also need a footer at the bottom this is going to be another custom special component which we're going to implement really soon and that's our index page believe it or not of course to keep our code clean and separate more code is going to go into these separate components in just a moment but before we implement those components let's actually get our styles so inside of the styles.js you'll be able to find two different files globals.css and whole module whole module was for that default styles we had so you can simply delete it and then you can go into globals.css and also navigate to the description down below to that same github gist and from there you'll be able to copy the entire style sheet for this project simply copy and paste it right here this is going to save you so much time when developing this project this isn't a beginner project it is already at an intermediate or an advanced level because it is a real e-commerce application with a content management system and also complete payments integration for that reason i want you to focus on things that matter writing real logic and actually creating your own e-commerce application from scratch i didn't want you to spend time writing css so i provided it all for you once again the link is down in the description in a github gist now that we've done that we can close it and we could go to our underscore app.js we can just check that our import is right here which means that our styles are now being used and we can actually check that out if we apply some class names right here let's add a class name to our div something like class name is equal to products dash heading and save it as you can see this is immediately looking so much better we can also give a class name to our products container class name is going to be products dash container and that's just centered it in the middle we're gonna use all of these class names that are inside of that global css once again to speed up our workflow and finally we are ready to set up our basic file and folder structure and set up all of our components that we'll be using throughout this entire project spending a few minutes on that right away is going to save us a lot of time in the future because we're already gonna have all of the components right here so let's do that right away we can start by creating a new components folder inside of the main ecommerce one of course inside of there we can create all of the components that we're going to use throughout this entire course so let's create the first one we can create that hero banner component dot jsx inside of there you can run rafce and that is going to be enough to start with we can repeat this process for all of the other components that we're going to use so let's go ahead the next one is going to be cart dot jsx again run rafce and we've got it then we're gonna also have the footer.jsx run rafce for the footer as well we're gonna also have a footer banner.jsx component we can also run rafc there we're gonna also have the hero banner component so hero banner.jsx we're going to also have a really important layout.jsx component we can run rafce in there for now and finally we're going to have a navbar.jsx again with rafce and finally the last one is going to be product.jsx component once again rvfce now that we have all of these components we can start importing them inside of our pages to do that though we can create one final file inside of the components folder called index.js from this single file we're going to export all of the other components so we can say export in curly braces default as then the name of the component such as footer and then from dot slash footer now we can repeat this for every single component we have the next one is going to be layout then we're going to have our navbar we also are going to have our product we're going to also have our hero banner right here hero banner finally we need our footer banner and finally we need the cart there we go that's going to be coming from cart so now we're exporting all of these components and we can go back to our index.js so i can show you how we'll be importing them into all of our pages now that we created that special index file we can import them in one line by saying import we can specify all of the components here in this case we're going to use product footer banner and finally hero banner and that's going to be coming from dot slash components there we go and we immediately get one error saying that we cannot immediately use the jsx file extension but we can add a babel preset react to the preset section of your babel config so let's go to our babel rc and under preset we can say comma and simply add babel preset react now since we've added this we also have to install it so let's open up our terminal stop it from running and then run npm install dash dash save dash dev and then add babel forward slash preset dash react this should get installed pretty soon and we can go under package.json and under dev dependencies to check that it is properly installed now let's run npm run dev now if we reload our page you can see that the error is still not quite fixed although this seemed like a trivial thing like we just want to be able to use the jsx extension we've ran into quite a few problems here but as you already know here in javascript mastery i don't skip over any bugs i'm going to go through this with you no matter how trivial it is and it looks like i've made just one tiny mistake it looks like this here was supposed to be presets and right here we don't need the initial preset if we're going to use the babel preset react so now if we close this and the re-run r terminal by pressing ctrl c and then y and then npm run dev again we should be able to go back reload the page and see another error this means that we are good to go we can go to our pages and then underscore app.js since we're using a preset react now we'll have to import react from react so we can use the jsx syntax there we go and we are back where we started if you remember correctly we were in our index.js file we just imported our components and we were getting ready to use them instead of this hero banner text we're gonna use a hero banner self-closing component and then under footer we're going to use that as a footer banner and then also a self-closing component so so far nothing has changed but now we can actually go into our hero banner and start implementing it right away to start implementing our hero banner we can start with the outer div this div is going to have a class name equal to hero dash banner dash container inside of there we're gonna have one more div that isn't going to have any classes and inside of there we're gonna start with some text so first we can have a p tag it's going to have a class name equal to beats solo this is going to be for our headphones and right here we're going to pass dynamic data but we haven't yet fetched anything from sanity so what we can do is say small text right here with capital letters this is going to be dynamic soon enough then we're going to have an h3 just below this h3 is going to render the mid text here we go and finally we can have an image right here and we don't yet have the source so i think we can leave the source as an empty string and we're gonna also provide the alt tag equal to headphones and we can also give it a class name equal to hero dash banner dash image once again you cannot see it yet because we're not fetching real data but we will soon below that image we're going to have a div and inside of this div we're going to have a link property a link is like an href but in next.js so right here we can import link from next forward slash link we can use it right here and a link accepts an href property just like an h1 tag does and for now let's point it to forward slash product and then forward slash id this id will of course be dynamic soon enough we're going to wrap our button with this link so right inside of there we're going to have a button component that button is going to have a type equal to button and inside of there we can render the button text which is also going to be dynamic finally below our link we're going to have a div and that div is going to have a class name equal to d e s c as in description so there we can simply render an h5 element that is going to simply say description and below that in a p tag we can render the actual description now of course all of the data that is currently in capitalized letters will be imported straight from sanity so we'll be able to modify this on the go through the sanity platform and now that we've created this banner it might actually be a good idea to connect to sanity right away that way later on we'll be able to pull all the products extremely easily so the question is what do we have to do to connect our application to sanity well first of all we're going to create one additional folder right here called lib as in library inside of there we're going to add a new file called client.js this is going to be for our sanity client so inside of there we can say import sanity client from add sanity forward slash client and we're going to also import image url builder from add sanity forward slash image dash url the only thing we have to do is create something known as a sanity client so cons client and that is equal to sanity client which we call as a function and provide only one parameter which is an object inside of there we have to provide a few properties a project id so that sanity knows which project to connect us with a data set so that we know are we in development or production we also need to pass the api version finally we need to pass the use cdn which can be set to true or false in this case that's going to be set to true and we need to pass our token all of these are values that you might think we don't already have the access to but we do we just have to go back to our sanity manager to do that i'm going to open up a new terminal window i'm going to cd into e-commerce and then cd into sanity e-commerce there we can run sanity manage and as you can see that opened up our project we can first of all copy the project id and paste it right here then we can go to data sets and see that we have one production data set so we can simply say production right here our api version is going to be 2022 this was a time when i was developing this project and finally we have to get our token to get to the token we can expand this go to api tokens and then we can create a new api token let's name it development and we're going to give it read and write access finally let's click save let's copy this token right here and what we have to do is not paste it right here due to security reasons so rather what we're going to do is we're going to create a new dot env file so right inside of our ecommerce we can create a new dot env file and there we can say something like next underscore public underscore sanity underscore token and we can simply paste the token right here now what we can say right here is process dot env dot next underscore public underscore sanity underscore token and we should be good to go when it comes to actually connecting to sanity instead of setting this client to a variable we're going to immediately export it so that we can use it elsewhere so export const sanity client instead of setting this sanity client to a variable we're going to immediately export it by saying export const client is equal to sanity client finally we have to be able to use the sanity images so we can say builder const builder is equal to image url builder and we need to pass in the client we've just created finally sanity is going to give us access to the urls where our images are stored so we have to export const url 4 is equal to callback function or we get the source and then we can simply say builder dot image and we get that source this is something that we're doing just once per project and once we do it we can simply use sanity client at all the times and anywhere in the code so now we can go back to our index.js and right here we can say import in curly braces client from dot slash lib forward slash client there we go now the situation with reactions and next gs is just a bit different in react we would immediately just create a use effect right here which is a life cycle method and then just call the client right there and fetch the data in next.js that is just a bit different in nexjs to fetch data we use something known as get server side props if you export a function called get server-side props for server-side rendering from a page nextgs will pre-render this page on each request using the data returned by get server-side props essentially whenever you're fetching data from an api or from a cms we can use the get server side prop function so just at the bottom right here we can export const get server side props and that is an asynchronous function so we can say async and then open a function block right here we first have to form a sanity query so we can say const query is equal to a string asterisk meaning to fetch all a pair of square brackets underscore type is double equal to and then in double quota strings product so we're essentially saying here let's grab all of the products from our sanity dashboard now that we have that query we can simply say cons products is equal to a weight we use that sanity client dot fetch and then we can pass in the query now we're going to repeat this process to also fetch the data for the banner so we can say banner query right here and instead of fetching the product we're simply going to fetch everything where type is equal to banner and we have to pass the banner query right here and change this to banner data finally remember what we said whatever getserversideprops returns that gets populated into our function so what we can do is say return an object that includes the props object where we're going to pass in the products and banner data that is all that we have to do in nextgs now what happens is inside of our props right here we get the data which we passed right here at the bottom meaning products and also banner data if you remember correctly i think we already had one product created right so what we can do is we can loop over the products right here let's add a question mark dot to make sure that we have some and then we want to return product dot name i think that's going to make sense now if we reload the page we cannot see any changes yet but what we can do is pass the hero banner prop to our hero banner component we could simply pass the banner data and then the first element but first we have to ask ourselves what exactly banner data is and in which format is sanity returning the data to us so i'm going to add a block of code here and say kansa log that's going to be banner data like this let's see what is it made of we can go to the console and you can see that it is an array with zero elements so we have to go to our sanity desk and actually add it there to do that we can go to our terminal and run sanity start which is going to open up the sanity desk on localhost 3333 and there we go once it is open we can go to banner and create a new element let's upload the image as well i've chose the same old headphones image for our button text let's do something like shop now for our product we can simply say headphones description can be something like best headphones on the market we can also go with small text something like let's do beats solo air something like that mid text can be something like summer sale people love sales right and then for large text we can have some random words like fine and smile discount can be something like 20 percent off and then sale time can be let's do 15 november to 7th december there we go and let's click publish now as soon as we do that we can go back to our localhost 3000 and we immediately get an array that now has one object with all the data we just passed in so we now know that we have banner data so now we can pass hero banner is equal to if banner data dot length exists then we want to pass so end end banner data zero because we're going to always pass in that first object right here inside of this array now going back to our hero banner we are accepting a hero banner prop right here and we can actually use it to display dynamic data so right inside of this small text we can say hero banner dot small text and if we save that immediately we get beats solo air for mid text we can do the same thing essentially copy this paste it here and render the mid text right here summer sale below that we also can have one another h1 and inside of this h1 we're gonna render the large text one fine summer sale looking fine and then finally we have to render our image now what we can do is we can import that url4 property so import url4 and that's coming from dot slash lib forward slash client now we can finally say url4 and then hero banner dot image so the url for that is contained right here and now we have our great looking headphones under link we can now navigate to a real url so right here we can put backticks and then inside of there if we wrap this with curly braces inside of there we can say product forward slash dollar sign curly braces hero banner dot product there we go so now we're gonna actually navigate to that product and also inside of the button we can render the hero banner dot and that's going to be button text shop now finally under description we can render hero banner dot d e s c best headphones on the market so now we immediately have this banner but the best thing about this is that we can change it whenever we want whenever there's a new sale we can just go to our sanity studio and simply change the values right here or change the product all of that is immediately going to work but of course we're just getting to the real deal and that is fetching all of the products that we create inside of our sanity studio right here well we're already doing that if you think about it we can see headphones right here and if we go to our content the only product we have are one pair of headphones amazing so far we've done most of the work we connected with our sanity we created the entire backend database all the schemas and structures and we are simply ready to move forward with our index.js the next part of course is the most important part and that is the part where we create the product component to which we pass all of the product data so that is coming right up let's go ahead and make our e-commerce webshop to start with our products we of course have to call our product component so right here instead of just displaying the product name we can go and render or call out our self-closing product component to that component we're going to provide a key which is going to be product dot underscore id and we're going to also provide the entire product object as product there we go so now as you can see if we reload the page we are seeing just the keyword product here because if we control click into product that is the only thing we are rendering but now alongside that we're getting the entire object containing the data about our existing products so what we can do is also import a link right here from next forward slash link we're going to use that to link to the product details page of course and then we also need to import that url for coming from dot slash lib forward slash client we're going to use this to get the url for the image inside of our sanity dashboard so right off the bat we can immediately destructure some of the things from inside of our product that's going to be the image name slug and finally the price we just put it in another pair of curly braces and with that we are ready to return some jsx of course that jsx is not just going to say product we're going to have one div and inside of that div we're going to render a link component that link is going to have an href property which is going to point to a dynamic url of forward slash product and then forward slash slug dot current so it's going to point the slug of that specific product we said that slug is an element that is unique essentially a name but if we have multiple products of the same name then that slug is going to have some extra characters added to it of course we have to add a child element for this link to work so as soon as we add that it's going to be fixed right away and that inner div is going to have a class name equal to product dash card inside of there we can of course render the product image that's going to be a basic img tag that's going to have the source equal to url4 and then we're going to check if we have an image so image and end and if we do we can return the first image because we're going to have multiple images for each one of our products we can also set the width and the height for our image to be around 250 pixels so there we go width and height and finally we can apply a class name equal to product dash image now if we save this you can see our great headphones appear right here with this nice hover effect of course let's also display the name and the price below our image that's going to be a class name equal to product dash name and there we can render out the name which we destructured from the product there we go headphones and we can also duplicate that and render out the product price where we're gonna add the price but we're gonna also add the dollar sign in front 99 bucks there we go of course these headphones look just a bit lonely so what we can do now is we can go to our sanity studio or sanity desk and we can immediately add many more products with ease so let's go here to new product and we can just start adding them as i've promised i'm going to leave a link to a zipped assets folder down below so you should be able to replicate each product in its entirety let's start with this great speaker right here i'll try drag and dropping some images right here there we go we have speaker one two three and four we're going to add a name let's do something like speaker we're not really innovative here and we can automatically generate a slug the price in this case can be something like 56 bucks and we can also add some details i'm going to say immerse in the amazing sound there we go and let's click publish this is going to be our second product we can just keep going through it because it is so easy so let's go ahead and add a few more products i'm going to go with these headphones right here there we go drag and drop these are going to be headphones as well but look at this now if we try to generate a slug it says that the slack is already in use so we have to say something like headphones new or headphones c or whatever you want to use the price can be something like 55 bucks and this is going to be a second pair of headphones and we can publish it let's keep going through it let's add a few more items let's add some of these in-ear headphones right here again drag and drop enter the product name cool in ear headphones slug can be automatically generated as you can see price is going to be something around 40 bucks and the details are gonna be use these while working out there we go and let's publish four products should be enough to start with so let's go back to our localhost 3000 and let's simply reload the page would you look at that we instantly get more products if the initial reload didn't work for you you might have not known about this but you can press ctrl shift and then r this is going to trigger a hard reload which is going to clear the cache as well so one more time if the general reload doesn't work control shift and then r to trigger a hard reload with the cash trigger that also reloads the cache great so now believe it or not we are done with our products we can go back to our index where we just have one thing left to do and that is the footer banner so let's go into the footer banner component so let's first pass some data into the footer banner component we can say something like footer banner is equal to if banner data exists so banner data and end in that case we can pass banner data zero so the first instance now we can go into it we can accept that footer banner right here and we can also import same as before link from next forward slash link and we can also import that url for that we use for images from dot slash lib forward slash client i just wanted to show you a finished version of our application as you can see right here we have this great banner we also have our products and then we have this great looking footer banner this is exactly what we're working on at the moment so let's go back to our localhost and let's implement it right away we can start by adding a class name to this div that class name is going to be footer dash banner dash container inside of there we're going to have one more div and this div is going to have a class name equal to banner dash c as in description and inside of there we're gonna have two more divs the first div is going to have a class name equal to left and the second one right here i guess you can guess it is going to have a class name equal to right if we save that you can see this red color appear right here that is coming from the footer banner container and inside of the left we can render ap tag that's going to render the footer banner dot discount there we go you can see 20 off below this discount we're gonna have an h3 element so let's change this to h3 and there we're gonna render the large text one fine there we go we can duplicate that and render the large text to find smile and finally we're going to render one last p tag where we're going to render the sale time there we go so as you can see we have this nice text with some words right here again just basic placeholder we have the percentage off and we have the sale time great but as you can see we are repeating ourselves quite a lot here so it might be a good idea to destructure all the properties from our footer banner we can do that by saying colon and then a pair of curly braces and we can take all of the values outside of it discount large text 1 large text to sale time small text is also going to be here as well as the mid text finally the product the button text and last but not least we're gonna have our product image there we go so now we don't have to reference the footer banner each time we can simply use the actual text elements there we go looking much better now inside of the right we're going to have another p tag that's going to render the small text like this there we go we want to go below with another h3 that is going to render the mid text this time there we go and finally we're gonna have one more p tag that's going to render the desc or a description i don't think we've taken that out from the footer so let's take it out right here below that b tag we're going to have our link as we already know each link has an href tag that is dynamic in this case and we're going to point out to product forward slash dollar sign curly braces product that's going to be the link to our specific product and inside of that link we want to render a button component that button is going to be of a type is equal to button and also we're going to render the button text right inside of it there we go shop now this is looking great now below this div of class name right we're going to add our image our image is going to have the src property equal to url4 and then simply we're gonna pass in the image we're going to also provide a class name equal to that's going to be footer dash banner dash image and let's save it there we go this is going to make our headphones float on top of this banner but as you can see something still doesn't feel right our banner is at the top we are missing our navigation bar and our footer banner is also going all the way from left edge to right edge so let's go ahead and fix that by working on the layout component a really important component in every application we can go to our layout component and start implementing it right away our layout is going to import a special component called head from next forward slash head head is the same thing as head is in html that head element that appears above the body that gives you some metadata about your website in nextgs you just have to import it like this inside of the layout what we can do is render out a div and that div is going to have a class name right here equal to layout inside of there we're going to have a head element right here and to that head element we're gonna add a title of our store name let's do js mastery store there we go if you save this now you won't see changes yet because we're not yet using this layout component but we will soon again feel free to use your own name right here below our head we're gonna call the html5 semantic header tag and inside of there we want to render the navbar component this is of course component that we are going to create on our own what you can do to instantly import it is press ctrl space and then click right here that's going to import navbar straight from dot slash navbar so once again that's a cool little trick that i recently found out about double click the word and then control space and then it's going to suggest the import if it didn't work automatically for you no worries just manually import it right here below our header we're gonna have our main section which is going to have a class name equal to main dash container and inside of there for now i'm simply going to say empty you're going to see later on what we want to put inside of here and finally of course we need to have a footer so inside of that footer we're going to render a footer component again ctrl space and click right here to import it from the dot slash footer now if we do that you still won't see any changes because we're not using this layout component anywhere where we need to use it though is the underscore app.js right now right here we're just returning a single component but that component doesn't have a footer doesn't have a navbar it doesn't essentially have anything so what we can do right here is import in curly braces layout from dot slash components and now we can wrap this entire component and by the way this component means the component that we're currently on so if we're on a product details page that's going to be this component if you're in the home page that's going to be this component right here so what we want to do is we want to wrap our current component or current page with the layout component as soon as we do this and press save you're going to notice that now we have navbar footer and then empty now how do we make this component actually appear inside of our layout well a special trick in react is whatever you pass to inside of your component you get access to that through a prop called children so we're gonna get access to this component through props call children and we can render those children right here right away and now we get back to our beautiful website we've created but now we actually have this navigation bar at the top although it's not yet styled we have some space and margin between the left and right side from our banner and also the same thing is happening at the bottom and we have our footer right here so what we can do is collapse this back again and we can start implementing the navbar and the footer component these are going to be really straightforward so don't worry about that trust me soon enough we'll be doing the stripe integration where we'll be able to buy all of these products for real so let's start with the navigation bar you can control click into it and we're gonna start with importing a few necessary things these are going to be of course link coming from next forward slash link and we're going to also import ai outline shopping from react dash icons forward slash ai that's just a simple shopping icon this is going to be all that we're going to need for now so what we can do is we can start implementing this jsx we're going to have a div and that div is going to have a class name equal to navbar dash container inside of there we're going to have a p tag and that p tag is going to contain a link and that link is simply going to have an href to forward slash in here we can enter the name of our store i'm going to say jsm headphones since that's what we're selling right here there we go and we can also give a class name to this b tag which is going to be logo that's just going to make it a bit grayer and add some space below this p tag we can also add a button that button is going to have a type which is equal to button and it's also going to have a class name equal to cart dash icon that button is going to open up the cart so later on we're going to add an on click functionality here for now i'm going to let that be empty inside of that button we're gonna have the ai outline shopping icon and we're gonna also have a span element that's going to say class name cart dash item dash qty which stands for quantity and there we want to render the total quantity of the item for now let's simply hard code it to something like 1. and there we go you can see this shopping cart icon appear on the top right and it says one right here that is going to be all that we're going to implement for now because later on we're going to implement the context in our entire application and then we'll be able to change this quantity dynamically so far we're going to leave it static and that is completely fine because we're definitely going to come back to this component now we can go back to the layout and transition to our footer component which also shouldn't be that hard actually it is so much simpler we can first import a few icons by saying import ai fill instagram and also ai outline twitter and that's coming from react dash icons forward slash ai inside of here we can add a class name to our div and that class name is going to be footer dash container inside of there we're going to have a p tag and there we can simply say something like 2022 and then jsm headphones and then as you know all rights reserved just to make it seem a bit more official now if you scroll down you can see that right here we can also add another p tag that's going to have a class name equal to icons and in there we can render the ai fill instagram and also ai fill twitter there we go render it looks like i forgot something that was ai outline twitter there we go and you can see those icons appear right here so now we kind of pointed out that this is the end of the website we have this great looking footer at the bottom this phenomenal looking banner with floating headphones we have our best selling products as you can see right here we have our summer sale product right here and the navigation bar that has the number of items in our cart everything is looking great so far the next thing we're gonna do is implement the product details page as you can see if we go to product and then speaker now you're gonna see that we're gonna get a 404. this page could not be found so what we're gonna do now is we're gonna implement it fetch all the data about the product all of its images and everything else that belongs to it we're gonna also add some scroll for the recommended products and i'm going to make it really exciting for you guys so let's collapse this let's close all of our currently open files by going to visual studio code and then holding control and pressing w a few times we always want to have a clean working environment so let's go to e-commerce let's go to pages and the next step is to implement that product details page in next.js you can do it like this we can right-click pages we can create a new folder called product and then we can create a new file inside of that product folder and you can use square brackets inside of there you can say slug remember slug is that unique identifier that belongs to each product and we say dot js so we're going to create a slug.js file inside of the product folder the fact that it is inside of square brackets means that it is going to be dynamic so for example we can go to product and then speaker or product forward slash headphones it's going to dynamically render it we can of course start with that rafce to quickly implement it but of course the component is going to be called product details right here and made to export the product details for now inside of there let's simply say product like this and let's save it now as you can see we no longer have a 404 rather if we click on a specific product like headphones we can see the product right here which means that we're successfully rendering the product details page and that is the beauty of file based routing in xgs we didn't have to implement any kind of library like react router we just created a new folder with a specific file name and we can immediately start creating the jsx and the logic for that component isn't that great let's start with implementing our product details component we're going to have one root div inside of which we're going to have one more div and that div is going to have a class name equal to product dash detail dash container that product details container is going to have one more div inside of it and inside of that interactive we're gonna have believe it or not yet another final div this is going to be the div that's going to contain the image so we can give it a class name equal to image dash container inside of there we can render our image tag by creating the img closing it and then referencing its source of course we can get the source by using that url from coming from sanity so we can import both the client and the url for from dot slash dot slash lib forward slash client but now of course the question is how are we going to get the image of this specific product how is nexjs or sanity going to know if we clicked on this speaker right here or on these headphones right here well we can get it by of course making an api call to get this specific product and if you think about it we've done something like that before if we go to our index.js and scroll down we have this git server side props function where we're fetching all the products we're going to copy this entire get server side props go back to slug and paste it right here but this time opposed to using the get server side props we're gonna use the get static props which is another special nexjs function if we quickly google it we're gonna see that git static props is a function that is used when we want to pre-render the page at build time using the props returned so when should we use it well we should use get static props if the data required to render the page is available at build time ahead of user's request and if the data comes from a headless cms that is exactly what we're trying to do so think about it if we're on the home page the user can click on any of these pages so we should have the data already stored so that when we click here everything is going to be populated instantly that's the whole goal with get static props get static props also has one benefit instead of here we can destructure params and then from outside of the params we can get access to the actual url query remember these square brackets and then the slide in between well as i've told you that slug is going to be dynamic that means that we're going to get access to whatever that slack is in this case that's going to be headphones underscore new and we absolutely need that because we need to know which product are we fetching the data for so what we can do is we can modify this query by first making it a template string using backticks and then we're trying to get the product but we're going to say end end slug dot current is equal to and then in single quoted strings dollar sign curly braces slug and then we close it go outside of the entire square brackets and then say zero because we only want to fetch the first product that matches this query so this is going to be used to fetch product details from the product page that we are on on the other hand we'll also want to fetch all similar products so to do that we can write another query const products query is equal to that's going to be a string where we have asterisk square brackets underscore type is equal to product and that's it we're going to fetch all of the products so now that we have that we can actually say const product is equal to a weight client.fetch query to get the individual product and then we can also say cost products is equal to await client.fetch and that's going to be products query with that we have everything we need so we can simply return products and also the product great and as with the get server side props all of these values are going to be delivered straight for us right here inside of the props so we're going to get product and also products great with that we can immediately destructure the values from the product by saying const image name details and price is equal to product that way we don't have to repeat ourselves product.image product.name and so on we can immediately get them and remember we wanted to render our image so what we can do is we can say source url4 and then if there is an image so image and end then we want to get image under the specific index this index is going to be changed every time because we'll be able to traverse through multiple images but for now let's simply try to get the image zero and as soon as we've saved that we get an error cannot destructure image of product as it is undefined let's see if we're properly passing it back here we have return props and then an object that returns products and a single product what we can do is we can console.log the actual product right here to see if we're getting any data back and finally nextgs gave us a beautiful and really descriptive error get static paths is required for dynamic server side generation pages and is missing for product slug you can read more here this is really interesting essentially it's saying that when we use get static props we also need to add one extra special next.js function called get static paths so if we go right here and search for get static paths we can learn more about it if a page has dynamic routes and uses get static props it needs to define a list of pads to be statically generated again think about it if we are at our localhost 3000 right here we need to already know that user can click here here here and here and for our page to be incredibly optimized nextgs immediately needs to know that all of these pages can be clicked on then it's going to immediately show us the data but now since we're going to have multiple other links in the product details page like the ability to visit additional products that we might like then we need to also repeat the process for them so that nextgs can prepare all of that data and deliver it as quickly as possible so to fix that we can say export const get static pads is equal to an async function right here and there we also have to write the query we can say const query is equal to a template string get everything where underscore type is equal to product so we're trying to get all of the products and then we can go into a new line we can open up a pair of curly braces right here and we only need to get one thing just get the slug more specifically just get the current property of a slug of each one of these products so again sanity's language is incredibly easy to understand it is similar to graphql but it is an optimized version of it so we're saying give me all the products but don't return all of the data for all the products just returned the current slug property that's it based on that query we can say cons products is equal to a weight client.fetch we pass in that query and then we can generate our paths const paths is equal to products.map we get each individual product which is essentially just a product slug and then we want to instantly return an object so this is not going to be just a curly brace we need to add parentheses and then a pair of curly braces this means that we are instantly returning an object from a function that object is going to have a params object and inside of there we're going to have a slug which we're going to set to be product dot slug dot current great finally what we have to do is return an object that contains the paths and also a fallback that is going to be set to blocking there we go of course if you want to read more about this just go to get static pads and search for blocking it is one of the ways in which you can set the fallback now if we save this you can see that we get our great headphones image and we are ready to continue with the rest of the product details page amazing below the div containing our image we're going to have one more div and this div is going to be for our image carousel so we can say class name small dash images dash container inside of there we can open a dynamic block of code and we can say image question mark dot map we're gonna loop through each individual item we're gonna also get the index and then for each item we of course want to return an img tag that image is going to have a source equal to url4 and then we pass in the item later on we're going to also provide a dynamic class name here as well as on mouse enter property this is going to allow us to select an image as you can see right here on hover and make it visible on this bigger display that way everything is going to seem fluent and it's going to allow users to better see what products are you selling we're going to leave this functionality empty for now while we implement the rest of the layout and then we're going to go back to it for now we can comment out this entire div because we don't need two of the same images below this div containing both of our images we're going to have one more div and this div is going to have a class name equal to product dash details dash d e s c as in description of course inside of there we're going to render an h1 tag this h1 is going to render the product's name so we can simply say name right here as we have already destructured it before headphones great we also want to render some kind of reviews right so below this h1 we can render a div that's going to have a class name equal to reviews inside of there we can render a single div that's going to have a few icons so let's go ahead and import the icons right away we're gonna import ai outline minus ai outline plus ai fill star ai outline star and all these icons are coming from react dash icons forward slash ai now we can go back and right here we can render let's do five of these ai fill star self-closing component and let's repeat it four more times let's save it there we go the last one can be let's do ai outline star because maybe some people didn't like these headphones so they're gonna have four stars below this div we're gonna have a p tag that's going to have the number 20 in parentheses this is going to be the number of reviews finally we're going to go below this div and we're going to render an h4 element that's going to say details under that h4 we can render a p tag that's going to dynamically render all of the details about our headphones great looking and sounding headphones of course what would an e-commerce store be without the price so we can say class name is going to be price on the speed tag and there we can render a dollar sign and then render the item's price 99 bucks great below that p tag we're going to render a div that's going to have a class name equal to quantity inside of there we're going to render an h3 element and that h3 is going to say quantity and right below we can render ap tag now this p tag is going to have a few span elements inside of it and it's also going to have a class name equal to quantity dash description or d e s c inside of there we can render a few span elements the first one is going to have a class name equal to minus and it's also going to have an on click property which is now going to be an empty string we're going to implement it soon enough there we can render the ai outline minus icon here we go as you can see we have this great minus right here which we cannot yet click now we're going to duplicate this two more times the second class name is going to say num as in number and it's going to render the actual quantity for now let's say it's zero and finally the last one is going to say plus and it's going to render the ai outline plus icon and there we go we have this great looking rectangle which is not yet functional but will be soon and it looks like our actual rectangle is expanding a bit too much we're definitely going to fix this soon but before that let's implement our add to cart and buy now buttons we can do that just below our quantity we're gonna add a div and this div is going to have a class name which is going to be equal to buttons there we can render the initial button which is of course going to be of a type is equal to button and it's going to have a class name equal to add dash to dash cart we're gonna also add the non-click which is going to be equal to an empty string for now and inside of there we can say add to cart there we go we have this nice add to cart button and we're going to duplicate it just below the second one is going to be the buy now button so let's say class name by dash now and we're going to also change the text to be buy now there we go now we have these two great looking buttons as you can see right here finally let's fix this quantity right here as well as the spacing between the details and the quantity and to fix that spacing we have to go up and change the class name from the outer div being product details description to product dash detail description that's going to immediately change this and everything will be looking great as we have this nice rectangle with minus plus also the price and two buttons right here now we can also implement the recommended items or you may also like section that is nicely scrolling around here to do that we can go back to our code and go all the way down below our buttons we're going to go a few divs down so one div down two divs and then the third div below this we're going to implement another div this div is going to have a class name equal to may like dash products dash wrapper inside of there we're gonna add an h2 that's going to say you may also like there we go and there we're going to render a div that's going to have a class name equal to marquee like this marquee essentially stands for a scrolling part most often referred to as a list of scrolling divs and inside of that div we're going to have one more div that's going to have a class name equal to may like dash products dash container and inside of there we're going to open a dynamic block of code we're going to take all of our products and map over them we're going to get our individual item and for each item we want to return well a self-closing product component remember this product is a component that we have already created so we can import it right at the top right here we can say import in curly braces product which is coming from dot slash dot slash components there we go and as soon as we do that it looks like we get another error can it read properties of undefined reading image well let's just finish adding our product component right here product and the only thing we have to do is pass in a key which is going to be item dot underscore and then that's going to be id and we also need to provide the product itself which is going to be equal to item and as you can see once we do that and reload the page we have these great products listed right here and to make these products move around we have to add just one extra class which is track as soon as we do that you'll notice that these products will start moving around and once you actually find the one you're interested in you can just simply hover over with your mouse and you can select it isn't this great with that we are almost done with our product details component the last thing we have to do is to implement the larger image functionality so the small image carousel and then once we actually hover over it we want to be able to see it in more detail so to implement that we'll have to add a state to our application we can import use state from react and we can create a new state field const index and set index is equal to use state and at the start we want to look at the image under the index of zero so now we can replace this static zero with the index right here and nothing should change once we've done that we can bring into play our carousel div right here now we can notice that we have a few images and something started breaking immediately this is not looking great but what we can do is we can add a function on mouse enter which is going to be equal to a callback function where we set index to be equal to and then we get the individual index of the item we are looking after finally based on that index we can provide a dynamic class name so we can say if i meaning the current index is equal to the index we want to see in detail then we can provide a small dash image and also selected dash image class names else we're simply going to provide the small image now if we save that you're going to notice that this one is currently selected and if we hover over it you're going to notice that different ones get selected but all of these images are of a different size so something kind of seems to be jumping around and it doesn't look good let's go ahead and fix that right away the last thing we have to do is apply a class name to our image which is going to be product dash detail dash image now we're not talking about smaller carousel images we're talking about our main product detail image now it is nicely structured and if we hover over them they'll all be of the same size this is looking great as you can see we can also move through different products and this is actually working right off the bat because we have implemented that routing also notice how quick that is if i click right here it opens it up and we can immediately see our application in its full glory all of these details are changing dynamically you can see speakers details the price that's all being pulled straight from sanity one thing that is currently not dynamic here would be the reviews but again feel free to modify it however you'd like you can make everything absolutely 100 dynamic using sanity you can even go a step further and to each product not just show all of the products just show the ones related to that one or create similar products or create products that work well together and say hey add this one you might like it as well so there's really a lot of possibilities that you can deal with sanity and especially in the e-commerce field this is already looking great we have our basic homepage fully done as well as the navbar footer all of these banners and finally also the product details page this is looking great and would you agree that now is a time that we start implementing real logic i'm talking adding items to the cart buying them right away changing quantities updating the number of items in the cart and actually displaying the card component as well all of that is coming right up because we're going to implement react context a single source of data for our entire application so managing the react state using react context coming right up stay tuned you're gonna learn a lot and we're really going to make our application dynamic to start working on our context and our logic we can go to our e-commerce folder and create a new folder right here it's going to be called context inside of that context folder we're going to create a new file called state context because in here we're going to manage the entire state of our application state context.js inside of here we can immediately import some things such as react and we're going to use quite a lot of hooks in curly braces create context use context use state and use effect all of that is coming from react so as you can see we're gonna definitely deal with a lot of logic here we're going to also import in curly braces a toast from react dash hot dash toast this is going to be that little pop-up notification that's going to appear whenever we add something to the cart remove it or finish the order now that we have our imports we can say cons context is equal to create context and we call that as a hook and below our context we're going to create our context functional component by saying export const state context is equal to and then a regular arrow function inside of here we're getting one really important prop which is called children this means that whenever we call our state context like this whatever we pass into it is going to be considered children and we can render it out so now we can continue with it and what are we going to have in our context well first of all there's going to be a lot of different states so let's start with that we can create our first use state by using the use date snippet and it's going to be called show cart so at the start that is going to be set to false are we currently showing the card or are we not we need to manage that state we're going to do the same thing so use state snippet for cart items and set card items we always need to know what items do we have in our cart and at the start we're going to leave it empty because soon enough we're going to fill it with the data coming from local storage so that's another thing i forgot to mention we are even including local storage so if a user exits the page and comes back all of his data will remain in exactly the state it was before they left we also need to keep track of the total price so let's create a new use state snippet total price like this and it's also going to be empty at the start we need to keep it going because we have quite a lot of states then we're going to have total quantities we need to know what are the quantities of all items that we work with and finally we need to have one last final state that's going to be qty which stands for quantity and at the start that's going to be set to 1 because we can change the quantity for each individual item finally we can create our context provider by specifying a return statement right here and then what we can return is going to be context dot provider and then inside of there we're gonna pass in our children so what this means is that we're essentially not rendering anything we're just gonna wrap everything with our context provider and a really important thing is that we're gonna pass some values to it so we can say value and then that's going to be an object of values that we want to pass across our entire application let's start by passing all of our state fields so that's going to be show cart as well as cart items we also have the total price total quantities and finally qty soon enough we'll be able to access all of these values right away from absolutely any single one of our components of course to make that happen we have to go into our pages and then underscore app.js inside of here we have to wrap our entire application with the state context and we can do that right here by saying import in curly braces state context from dot slash context forward slash state context we can simply call it as a function right here and as we discussed we need to wrap our entire layout and our component with the state context this means that nothing is going to change we simply want to pass the data from the state context to every single component inside of it another thing we need to do to make our small notification pop up is import something known as a toaster which is coming from react dash hot dash toast and we can put that right here we just need to add it right here above our component inside of the layout as a self-closing component that's it and then all of the other data is going to be managed straight inside of our state context let's implement all of the functionalities that we needed for our product details page such as incrementing the quantities and adding the items to the cart instead of simply passing the set quantity function to all of our components let's create our dynamic quantity update functions right here inside of our state context that way we can provide just the final function to our product details component let's do it like this create a new function const inc qty as an increased quantity and inside of there we're simply going to create a callback function we're going to call the set qty state and there we want to have a callback function because whenever you update the state using the previous version of that same state so previous qty then we have to use a callback function and we can simply say prev qty plus one there we go and essentially we're gonna do a similar thing for the decrease quantity so i'm going to duplicate that change this to dec quantity or decrease quantity and that's going to be previous quantity minus 1 but we have to have one additional check so i'm going to expand this into a new function with a function block like this and we're going to check if pref quantity -1 is lower than 1 then we're going to simply return 1 because we cannot go lower than 1 and if that's not the case we're going to return previous quantity minus 1. so we want to keep decrementing but if we lower the number too much in that case we cannot go lower than one so now we have our two functions and we're gonna also pass these functions to our global state increase quantity and also decrease quantity now we can finally go to our product details so product and then slug and we can for the first time ever start using that global state and its functions that we've created so to do that we can import use state context and this is something that should be coming from dot slash data slash context and then state context but to be completely honest i don't think we've yet exported it if you look at this we don't have a variable called use state context we just have the state context itself but we're going to go even one step further and we're going to create a special function that is going to allow us to more easily grab the state we can say export const use state context is equal to an error function that simply returns the use context and then we provide our own context great that is going to allow us to use our state essentially just like a hook so right here we can say const we can destructure the decreased quantity also increase quantity and finally we can get the quantity itself and that is equal to use state context there we go now we can use these functions right inside of our code so where are we actually decrementing and incrementing it's right here so we have our minus sign and on minus we're simply going to call decrease quantity right here on our plus we're going to call the increase quantity so inc qty and then right here in the middle where we have our number we're simply going to render the qty there we go so now as you can see we have one in the cart and if we keep incrementing this number is going to change and these changes are reflected in our entire application but right now we're not doing anything with it because the add to cart and buy now buttons are not working so we have to create a new function inside of our state context called on add what's going to happen when we add it to the cart so right inside of our state context above our increase and decrease quantity let's create a function called const on add that function is going to accept two different parameters the first one is going to be the product we want to add and the second one is going to be the quantity we want to add so quan t t there we go and inside of there we first have to check if the product that we want to add is already in the cart so let me expand the code since we'll be mostly dealing with logic now that's going to be a bit tougher we have to say const check product in cart so is the product already in cart we can do that by using the cart item state dot find and we loop over all of the card items or we get the individual item and we want to check if the item dot underscore id is triple equal to product dot underscore id remember that product is coming from here so we need to know is the item we're trying to add to cart already in the cart because if that is the case then we simply need to increase the quantity and not add another instance of the same item so we can say if check product in cart in that case we can simply increase the total price so set total price is going to be a callback function where we get the previous total price and we're going to set it to previous total price plus product dot price times quantity so we're adding that new item and we also need to set the total quantities which is another state that we have and there we also need to get the previous total quantities and do the previous total quantities plus the quantity of the new product so that's going to be just quantity like this there we go because we are passing it right as a prop so now that we updated our states we need to update the actual items in the cart so we can say const updated cart items and that's going to be equal to cart items dot map so we want to map over our current cart items we get each individual cart product in there like this and then we need to check if cart product dot underscore id is equal to product dot underscore id so that's the product we are trying to add if it is equal then we can return a new object which is going to spread the cart product but this time it's going to update the quantity of that product to be cart product dot quantity and then of course we're going to increase it by the new quantity we're trying to add i know it's a bit complicated so let me try to bring this back and bring us back to the finished site so that i can explain what we're doing so we currently have four of these headphones let's say that we have just one if i go back and let's say that i want to add another pair of these same headphones as you can see right here now if i add another pair and if i click add to cart we don't want to add another one of these items right here we need to recognize the fact that we already have the same item and we simply want to increase the quantity right here and we want to increase the price or the subtotal rather that's what we're currently trying to do and then later on we're going to implement the functionality to add a different item to the cart and as you can see it appears below so with that in mind we now have our updated cart items and the only thing we have to do is set cart items to be updated card items and we can even show the toast dot success so that's that little success message and what we can say is qty and then product dot name added to the cart there we go so this is gonna happen if we're trying to add an item that already exists in the cart but what if the item doesn't already exist in the cart well in that case we can go inside of an else statement right here and we would also have to update the total price and total quantities so we can either duplicate that here or even better just pull these two states above because we need them to happen both inside of an if and also inside of an else the only thing we have to do if we don't already have the item in the cart is update the product quantity so product dot quantity is going to become our new quantity and then finally we need to set card items but this time we're going to set card items to be an empty array where we spread all of the existing card items and then we add an object where we spread our new product right here so a product with the updated quantity that is it and then again we can render out this toast we can either duplicate it or even smarter we can just pull this below our entire if and else so it's going to happen in any case great and with that we should be able to add the items to the cart so we're going to take this on add and we're going to pass it through the value right here now we can pull it from our use state context right here on add and finally we can use it inside of our add to cart button so right here we have our add to cart and on click i'm going to add a callback function like this and then we want to call the onadd function but we need to provide the current product as the parameter as well as the quantity that we want to add there we go so now if we go back and if we go to our localhost 3000 i'll try to add two of these speakers you're going to see that currently we have an error reading find of cart items so if we go to our state context that's because cart items should at the start be an empty array so if we fix this and add now you can see this little toast a notification appear one speaker added to the cart but that's not really doing anything at the moment because we have no way to look into the cart we haven't yet implemented the cart component so now might be a great time to do that to implement the card component we are going to go into our navigation bar so we can go to components and then nav bar right here we are going to import our cart component so import in curly braces cart from dot slash and what we can do now is we can below this button simply render the self-closing cart component like this as you can see now there's a card there but our cart shouldn't always be visible it's only visible when it is clicked as you can see right here and we can close it so we have to somehow keep track of that global state and if you think about it we are already doing that we have this show cart and set show cart so what we can do is we can pass the set show cart as well through the values and then we can pull these values from our navbar component remember how we've done it before we first need to import use state context from dot slash context forward slash state context and then right here we can say const show cart set show cart and also we're going to need total quantities and that's equal to use state context the total quantities is going to be the number of all items in the cart so however many items we have we need to know what is that number before that was hard coded here but now we can actually pass in a dynamic value there we go so if we go back you can see that we have not a number at the moment but we can switch that to be 0 at the start right here and this is looking good then we're going to also make this button close and open the cart on demand so let's create a callback function right here and we're going to set show cart to be set to true so with this we want to open it and then once we actually click outside of the cart we want to close it and a really important detail we only want to show the cart when the show cart is set to true so we can do show cart and end only then show the card so now if we reload the page you're gonna notice that there is no card but if we click right here the card shows up currently the card is just a piece of text but we're going to fix it right away because we are ready to start implementing our entire card component let's go ahead and get started to start with our cart we can start with first importing a few things because this is going to be a big component we're going to use the use ref hook right here as well as the link component coming from next forward slash link we're going to also import the ai outline minus icon ai outline plus icon ai outline left as well as ai outline shopping and these icons are coming from react dash icons forward slash ai we need one another icon called ti delete outline and this one is coming from react dash icons forward slash ti we're gonna also use that toast so we can say import toast from react hot toast finally our cart is of course gonna use our context so we can say import use state context and that is coming from dot slash context forward slash state context we're going to also use some images so with sanity we have to import the url for coming from dot slash lib forward slash client there we go and i think now we should have almost everything we need we can set up our reference right here to our cart so we can say cons cart ref is equal to use ref and then we leave it empty and we can also get all the data from our context we're going to get the total price like this let's also get the total quantities we can also get the cart items and most importantly set show card so that we can toggle it off and that's going to be it for now that's going to be coming from use state context and we call that as a hook of course this was supposed to be use state context rather than content and now we can start creating the jsx for our cart first we're gonna have one div that's going to be our wrapper so we can give it a class name cart dash wrapper we can also give it a ref equal to cart ref you'll see soon enough why do we have to do that inside of our wrapper we're gonna have another div and that div is going to have a class name equal to cart dash container inside of there we're going to have a button and this button is going to have a type which is equal to of course you know it button it's going to have a class name equal to cart dash heading and then once we click here so on click we want to call a callback function which is going to close our cart so we can say set show cart is going to be set to false there we go and inside of there we can render the ai outline left icon as a self-closing tag and we can render two different span elements the first one is going to say your cart and the second one is going to say in parentheses total quantities and also items so that we know how many items do we have we can also give a class name to our first span which is going to be heading and also we can give a class name to our second span which is going to be cart dash num dash items now if we save this you can see that we already have our great looking cart so i'm going to pull our browser on the side once again so that we can see the cart in its full glory of course now once we click here you can see that it actually closes so we are one step closer on achieving our card look feel and functionality now below our button we want to render of course the cart items so we can say if cart items dot length is lower than one in that case we want to show some kind of a placeholder right that's going to be a div that's going to have a class name equal to empty dash cart inside of there we can render the ai outline but this time that's going to be shopping and the size is going to be 150. there we go and we can also render an h3 right here that h3 is going to say your shopping bag is empty there we go save that looking good and finally we're going to provide a link that's going to have an href to just forward slash and there we want to render a button that's going to have a type is equal to button and it's also going to have an on click which is going to have a callback function and there we also want to set the show cart to be set to false finally we can give it a class name equal to btn and inside of there we can say continue shopping there we go so now if we click here we close the cart and also if we click here we close it and go back to our localhost 3000 or to our stores homepage but now what if we actually do have the items in our cart well we're going to go below right here and we're going to create a new div which is going to be called or rather it's going to have a class name equal to product dash container inside of here we can actually loop through the products so we can say if cart items that length is greater than or equal to one in that case we can render over the cart items by calling the cart items dot map property so we want to have an instant return here so instead of a curly brace we just have a parenthesis and through each iteration of the map we're going to get the item as well as the index and now the question is how is that returned item or product going to look like well it's going to be a div first of all and let's indent it properly that div is going to have a class name equal to product and we're going to also give it an id or rather a key which is going to be index if i'm not mistaken each one of our cart items also has a id property so we can also do a product or rather an item dot underscore id this is going to be even better whenever you have lists it's always a good idea to use custom indexes instead of the ones that simply go from zero to a specific number great so what's going to be inside of our product well first of all an image this image is going to have a source equal to url4 and then item question mark dot image zero so we want to render the first products image and it's going to have a class name equal to cart dash product dash image now if we save that and open up the cart we should be able to see that right here of course we have to add something to the cart first so this is the first time that we're actually checking if this even works so let's add one of these to the cart one speaker added the number changed here you can see that's the beautiful thing about context it is global and whenever you do something here it immediately changes there as well and there we go we can see our speaker image now below our image we're gonna have a div and that div is going to have a class name equal to item dash d e s c as in description inside of there we're going to have another div that's going to have a class name equal to flex space and then top as well inside of there we can render an h5 element and there we can render the item dot name speaker there we go and below that we can render an h4 element right here that's going to be dollar sign and then we can render the item dot price so now we have the speaker and we have the price as well already looking great below this div we're going to have another div that's going to have a class name equal to flex and then bottom there we're gonna render one div that's not going to have a class name but inside of that div we're gonna have a p tag and that p tag is going to have a class name equal to quantity dash desc and if you remember correctly we had something that looked exactly like this not that long ago i think it was in the product details page so in pages product slug there we go quantity and there we have our quantity description so we can copy this entire paragraph right here from slug.js and paste it right here there we go now the problem is that as you can see decrease quantity is first of all not defined but even if it were defined how would we know for which product are we incrementing or decrementing the quantity because on our product page we have only one single product if we go here you can see we have just the the quantity update for the headphones but if we go to our cart we don't really know what's gonna happen are we gonna update the quantity for headphones or for speakers so this is not going to work right out of the box so for now i'm gonna simply remove the on click here by setting it to an empty string and i'm gonna also remove the quantity here rather set it to zero and also do the same thing for the on click on the plus sign if we do that and go back we can add to cart and you can see that we have our great toggle but it is currently not functional we're going to implement the functionality soon enough after we're done with the layout for our product now we can go below the speed tag and below this div and there we can add a button this button is going to have a type is equal to button it's also going to have a class name equal to remove dash item and on click for now is going to be empty but later on we're going to remove the item with this button click so inside of there we simply want to show a ti delete outline now if we save this you can notice this delete icon right here and this is looking great let's try adding a few more items to the cart so if we go to these headphones add to cart there we go we now have two different products let's also add the speakers let's try adding five of them and as you can see this is working great but we don't yet have the subtotal nor the quantities for these items so that's going to be another piece of functionality that we'll have to add but before we do that let's add the subtotal for our cart so we're going to go below these three parentheses and then below one more div right here and there we need to check if cart items dot length is greater than or equal to one in that case we can render our subtotal div so that's going to be a div that's going to have a class name equal to cart dash bottom there we can create a new div element it's going to have a class name equal to total and inside of there we can render an h3 element and that h3 is going to simply say sub total like this and we can render another h3 that's going to render the dollar sign and then the actual total price there we go currently it is not a number but if we go to state context we can set it to 0 at the start and once we add something you can notice that now it is 56 so this is working properly the last thing we're going to do is below this inner div we're going to add one more div and this div is going to have a class name equal to btn dash container inside of there we're going to have a button component and that button is going to have a type equal to button a class name equal to btn and for now the on click is going to be set to an empty string because we're going to implement it soon enough as soon as we're done with updating all of the properties quantities for all of our products inside of that button we can simply say pay with stripe and as you can see we're getting much closer with that actual functionality of connecting the stripe payment gateway with our e-commerce application so that we can process real payments and actually sell our products great but as i promised let's first focus on implementing the quantity updates not only for our product details page but also for our cart items where we can have multiple items in the cart at the same time to do that we're going to go back into our state context so let's go back here and below are on add we're going to create a new function const toggle cart item quantity so we're really trying to be descriptive here that function is going to accept the id and the value of the product we're trying to work with so first of all we have to find the product we are working with we are updating so this is not going to be stored in the state rather it is going to be a special variable or rather should i say just a normal variable that we're going to have access to throughout the state context file so i can say let found product so this is going to be the product that we want to update and we're going to also have the index of the property we want to update so these are two normal variables inside of our functional component we can go back here and then we're going to update that found product so we can say found product is equal to cart items so we want to go through all the card items and find one individual card item so we can say card items dot find item and then if item dot underscore id is equal to product dot underscore id only then do we know that we really found the product that we want to update to find our product we're going to loop over the cart items by saying cart items dot find we need to find something inside of it more specifically we need to find the item like this where the item dot underscore id is equal to the id of the item we're trying to update and which we're passing through props once we have found our item we also need to find the index of that item so we can say index is equal to cart items dot find index and there we're going to get a product where the product dot underscore id is triple equal to id great so this is going to give us an index of that item in the cart items array now that we know these properties we need to know are we incrementing or are we decrementing quantity so we can say if value is equal to ink increment this is going to be a string that's going to be either decrement or increment and based on that we're going to know what to do so if value is increment we're going to also have an elsif so else if value is equal to dec or decrement there we go so if the value is increment we can simply say found product and then dot quantity plus equal to one we simply want to update it right then we want to access the cart items and then we want to access a specific index of these card items and update that with the found product right here but take your time for a second think about the most basic rule of react is this really the best way to approach this problem what is cart items it is an array right but it is also an array that is a state property and what is the most important rule in react it is to never mutate the state and that means that you should never update the state with an equal sign like this we should always use the setter function like set card items to update the state that way so with this you would actually break rules of react and your code would start behaving unexpectedly so what we can do is we can create a new instance of our cart items so let's do something like let new cart items and to do that we're going to create a new array and we're going to spread our current cart items so right here cart items but now we want to add that new product inside of it so what we can do is add a new product which is essentially going to be just an object we want to spread all of the properties of that object right here and then we want to update the quantity of that object to be product dot quantity not context rather quantity but this time plus one because we are incrementing it so what we can do is we can remove this and remove this just keep these new cart items and now we can set cart items to be the new cart items or even simpler we can just take this entire thing and immediately set them right here so we are updating the cart items with the current card items and we're adding one new element to it we're spreading the properties of that product and we are increasing the quantity by one this is the proper way it should be done in react next thing is that we have to set the total price because that changed so we can say total price we're going to get the previous total price by using a callback function so prev total price is going to be pref total price and then plus the found product dot price and in this case i think i've made a mistake we want to work with the found product right here so we can simply update the product right here with found product and found product right here because this is the exact product that we are trying to update great and finally we also want to increase the number of total quantities so that's going to be set total quantities to prev total quantities and then we want to call that prep total quantities and simply say plus one because we just added a new item now for the decrement it's going to be incredibly similar so essentially we can just copy all of the functions right here paste them below first we need to add an if statement and we need to check if found product dot quantity is greater than one because that is the only case where we can actually update it if it's one we cannot lower the quantity because we would go to zero and that's actually what this button does removes the product so in this case we're simply going to set the quantity to -1 set the price to the previous total price minus the new price and set the total quantities to previous total quantities minus 1. i know that this function might have been just a bit complicated but just bear with me if you find this whole logic of this e-commerce store a bit too complicated there's going to be a code for the entire state context so feel free to copy and paste it that way we're sure we won't have any errors and you can just keep watching the video to learn it and absorb it i'm sure it's going to make sense really soon so now we want to pass the toggle cart item quantity and we can actually make use of it inside of the cart so inside of our cart we can now get that item or get that function from the state context toggle cart item quantity of course we have to add a comma right here and what we can do is go back to our increment and decrement and now for the on click if i space this out properly we can add a callback function right here we can call the toggle cart item quantity we can pass the item dot underscore id and the value here is going to be decrement there we go of course this is supposed to be inside of the function call to the second parameter we can also duplicate this on click and paste it for the increment right here but we're just gonna change this to ink as an increment and finally right here we're gonna have the item dot quantity so as you can see now we have one speaker and one pair of headphones and we can click here and as you can see we're adding new items and this is not good this is exactly what we were trying to avoid so we have to see where is the error in our code and why are new items being added so let's focus on that right away if we go back to our state context we might get a clue on why this is happening if you look at our set card items function you can notice that we have an array of all of our current card items and then we are pending a new product to it so we're essentially just adding these items and that is not the correct way to go about it we should actually just update the current cart item product that we are trying to update the currency for and not add new products to the cart well since we're adding the updated item right here it would only make sense to first delete the older not yet updated item and we can do that by using the splice method and then splicing a specific index so we can say const new cart items and that would be equal to cart items dot splice and then we want to splice from the index to one so we want to splice only one element starting from this index right here this is going to remove that item and then instead of spreading the cart items we simply want to spread the new cart items which doesn't include the product we are updating right now and we can actually pull this to the top so that we can use it right here as well when we decrement the items great now let's go back reload the page since we don't have local storage our cart is now going to be empty let's add our headphones let's also add our speaker and let's open up the cart as you can see everything looks great the subtotal is being accounted for and let's try to increment the headphones okay this is a bit closer but now it overrode the last item so this is really interesting as we keep doing it something is still breaking and i wanted to include this part in the video because working with e-commerce is not easy there are a lot of things you have to account for managing different items products updating each individual quantity and so many more things can cause so many more bugs so i'm going to lead you through the bug problem solving together that's exactly what the whole point of this is to teach you how to approach and solve problems and this is actually the most important gotcha in react even though we thought that we are no longer mutating the state ourselves we technically are we're calling a dot splice method on the cart items and a splice method is a mutative method which means that it actually updates the state so it would be better to use a non-mutated method like a filter this is going to give us a proper update of the cart items without mutating the state directly so we want to filter out the cart items to include all of the items right here so we can say item but only not include the one that has the index equal to the index we're looking for so we want to use the filter to keep all of the items besides the one we're currently updating and that's going to be easy we're going to get our item and we can say item dot underscore id is not equal to id which we passed right here so this is going to make sure to keep all of the other ones where the id is not equal to id but only filter out the one where it is and now with this we have new card items right here and here we're not mutating the original state and we should be able to reload our page and see if this is going to work let's add our headphones and our speaker go to the cart and click here okay that's good you can see the speaker updated two three four it is working perfectly looking great but as you can see the order of the element changes the last one we click on updates to the bottom of the list this is definitely an interesting problem to tackle i don't really mind it this much at the moment but if you'd like to fix this i urge you to do so this is a great opportunity for you to learn and potentially do some open source work so if you manage to find a solution feel free to go to the github repository of this project and then make a pull request with your fix i will gladly accept it as soon as you do that with that said we are now properly updating the quantities of all of our items in the cart the last thing we have to do is implement the remove functionality on remove is also going to be in our state context just above the toggle cart item quantity const on remove is equal to a function where we get the product as a parameter we're gonna pass that later on and there we also have to do the same thing we have to know which product are we currently updating so we're going to update the found product variable and then we're going to do the same thing as we've done before we're going to copy the cart items to create a version of the new cart items without the cart item we're currently updating exactly the same thing finally we can call the set total price to be equal to we get the previous total price right here we take that previous total price and we decrement that with found product dot price and we multiply that by the found product dot quantity because we have to know how many products were there of that specific type so if we remove the item speaker 56 we have to multiply that by 5 to get the total actual amount then we also need to update the total quantities currently we have eight items in our list but if we remove this one that's actually going to remove five items so let's create a callback function where we get the current prep total quantities and then we take that number and then we decrement it by foundproduct.quantity and the last thing we want to do is set cart items to be equal to new cart items to update it now if you remove this element you can see that we get func that apply is not a function and of course that makes sense that's because we are yet to pass our honoring move to our value right here and then we have to go to our cart we have to take it from our context and then we have to find our delete outline icon and simply add the on remove but we have to call it as a callback function and right there we have to provide the item as the product we want to delete now just before we save that let's make sure we've done everything correctly on remove pass the item we go back to state context to the on remove function right here and it looks like our product is not being used here so we have to make use of it we're just going to compare it right here we don't have access to the individual id we need to do product dot underscore id and the same thing goes for here product dot underscore id now if we save this and click right here you can see that it got deleted and our cart is now empty everything is functioning as it should we can update the quantity we can remove it and as you can see all the changes are happening globally across our entire application because states are shared using this great context we can update it we can remove the items we can do whatever we want and all of the changes are reflected everywhere let's go through the entire application workflow one more time to check it out before we start implementing the payments functionality let's go to the speakers and let's go ahead and add to cart great let's move to these cool in-ear headphones and let's add four let's say we really like them we can also go to these headphones and let's add one pair there we go and now we have six items in the cart everything is here let's say that one of our friends doesn't want these headphones so we're just gonna decrease that to three and we can also remove the speaker let's say that we don't need it if we have two pairs of headphones everything is working nicely we are left with one of these three of these four items in total and that subtotals to 175 and we are ready to pay with stripe that is great so finally we can start with the stripe payments functionality this is going to be another big part of this video so take a bit of a break if you need to like this video subscribe let me know in the comments what do you think so far i'm really excited to implement the stripe payments functionality so going back to the code we can close all of our currently open files and folders keep the working environment clean and the next step we're going to focus on is going to be implementing stripe so i hope you're excited to start integrating stripe we can go to our e-commerce folder and then we can go inside of pages and now this is a really special thing with nexgs we have a special api folder this api folder essentially serves the entire back end of our application the part that's written inside of the api is going to be our server and that's not going to be rendered on the front end so inside of a next.js app we don't have a need for a special node and express server we can do everything inside of this api folder so right inside of this api folder we're going to create a new file called stripe dot js inside of here we can import stripe with a capital letter from stripe we have that installed as a dependency now we have to create a new instance of stripe by saying cons stripe is equal to new stripe like this but if we hover over it we might get some more information as you can see the first thing that we need is going to be the api key and we don't already have one so how can we get it well let's go to stripe.com as you can see right here they have in my personal opinion one of the cleanest landing pages of all the websites on the internet it is simple clean and i just love it but let's start with integrating stripe to our new e-commerce store we can go ahead and sign in and if you don't already have the account you can sign up right here by clicking this link and create your new stripe account in my case i'm gonna sign in and as soon as you sign in you can turn on the test mode right here and then you're gonna get your publishable key and also secret key right here for the test mode so if you want to work with real transactions you'll just have to switch this test mode to false in this case i'm going to take my publishable key and we need to use it right here but to keep it secure i'm going to go inside of my.env and right here i'm gonna say next underscore public underscore stripe underscore publishable underscore key and that is going to be equal to this key right here i'm gonna also copy my secret key there we go and i'm gonna define that as next underscore public underscore stripe underscore secret and finally underscore key and i can paste it right here so now we have all that we need we can go back into our stripe.js and we can pass that api key straight in so right here we can now pass in the process dot env dot next underscore public underscore stripe underscore secret underscore key there we go and in next gs each file has to have its own handler so we can say export default async function handler and there we have the request and the response the same as we do in express for example that's going to be a function and the way they've done it you can create a new if statement for each different type of the request so we can say if reg that method is triple equal to a string of post then in here we are handling the post request to forward slash stripe because the file is called stripe.js so that is same old file based routing in practice but this time for back end so what do we actually have to do to make this work well first we're going to have a try and catch block because we need to know what happens if something goes right or if something goes wrong well if something goes wrong we can immediately return res.status 500 which means a server error and then json we're going to send back an object where the status code is going to be set to 500 and message is going to be equal to error dot message there we go now of course we're concerned with what happens if everything goes right how do we actually process the payment well i would strongly recommend that you read stripe documentation they have phenomenal docs and essentially you can learn how to do anything with their services in this case we want to accept online payments so just go here and as you can see we can implement a pre-built checkout page or a custom payment flow in this case we're going to go with pre-build checkout page and right here you can see how to handle that they even simplify it to the point where you can just choose your front-end framework like nextgs and based on that they hide all of the other back-end programming languages and assume that they're gonna do everything in next.js so as you can see we have our entire file right here what i would do to be completely honest is just copy this entire part right here so let's go ahead and do that we're going to paste it over what we currently have and it's going to be fairly similar instead of import they use require here and they immediately pass that process.env but in our case that's not stripe secret key as they called it you can see they called it next public stripe publishable key and stripe secret key so they're not actually pushing this to the web we can copy that and if we go to our process.env or just env we can simply enter the stripe secret key and now we should be good to go so we are really following their steps there we go now let's explore the code create checkout sessions from body params so inside of here we have some kind of line items which is an array with different objects where we can specify the quantity and price this is exactly what we want to do but we just have to know which parameters do we want to pass so what i'm going to do now is i'm going to take this object from here and i'm going to call that params and declare it above const params is equal to and then we pulled everything out and now we can simply pass it back in i'm going to expand this code a bit because we're going to be focusing more on the logic now there we go and now our goal is to figure out how to understand which products have the users selected in the application then we have to bring them here and use them as list items first of all there are gonna be some additional properties that we need to pass to programs things such as submit underscore type is going to be equal to pay we want to pay something the mode is going to be set to payment then we're going to have the payment underscore method underscore types which is also going to be set to simply card we have the billing underscore address underscore collection which is going to be set to auto these are some some additional props that i found to work best with simple purchases such as this one we can also provide shipping options this is a really cool thing that i'm going to teach you how to do from scratch so you can create an array of shipping options and each shipping option is going to be a new object that is going to have its own shipping rate but the key thing happens now since you have to create this new shipping rate inside of stripe so let's go back to our stripe commerce and let's go to products under products we have shipping rates let's create our first shipping rate let's say that the amount is going to be completely free so we're going to say free shipping and we don't need to specify the business days and simply save it as you can see we have our free shipping and we get the id of that shipping so we can simply copy it right here and paste it right here and let's add an additional shipping rate for example new that's going to be let's do in usd that's going to be 20 bucks and we're going to say fast shipping so a user can select and this is going to be between 1 to 3 business days let's save it we can again copy that id and we can paste it right here under the second shipping option but now we are at the main point and that is how can we get the list items from our application how are we going to know what has the user added to the cart well once the user clicks this pay with stride button then we have to pass that data to our next js backend let's do that right away we already know that that button right here is under product slug and then we have the buy now button but that's not the same button that is this button right here let's first deal with the one that's inside of the cart so i'm gonna go to our components and then cart dot jsx there we have the pay with stripe button that pay with strike button is going to call a special function called handle checkout and we can define it right here at the top const handle checkout is going to be a basic react arrow function now let's see if stripe docs talk about this special checkout function we are now looking at the pages index.js and let's see we have the use effect right here do we have the purchase button we do this button is going to trigger post method on the api checkout so we have to do something similar to this but they don't really explain it in a way that we would like so what we can do is go back to our code and i'm going to explain everything for you sometimes you have to go around the docs a bit and see what works for you so first of all we'll have to get an instance of a stripe promise to do that we can create a new file inside of the lib folder and we're going to call it get stripe dot js inside of our get stripe we can import load stripe and that's going to be coming from add stripe forward slash stripe dash js then we can declare an empty stripe promise this is a variable that's going to be undefined at the start but then we're going to create a function const get stripe and that is going to be equal to an arrow function inside of there we're going to check if the stripe promise doesn't yet exist then we want to set the stripe promise to be equal to load stripe function and then we call it to it we can provide the process dot env dot next underscore public like this underscore stripe underscore publishable underscore key there we go and finally we're going to return the stripe promise there we go of course we have to export default our function so get stripe now we can go back to our cart and we can actually use that function so right here we can import that's going to be get stripe from dot slash lib forward slash get stripe there we go now what we can do inside of the handle checkout we can say constripe to get that specific instance of stripe is equal to a weight get stripe and we call it as a function now we're going to make an api request to our own next.js backend that is kind of crazy it's really cool that nextgs allowed us to create both a frontend and a back-end application in one package so we can say const response is equal to a weight we're gonna use just a basic fetch although feel free to use axios right here and the first parameter is the api route so that's going to be for slash api and then forward slash stripe because we are under pages api and then stripe right here then the second parameter is going to be an object that's going to contain all the options so we can say the method is going to be post and we already know this because inside of stripe right here we said that the method has to be post on the stripe endpoint then we're going to also provide headers sometimes this is not necessary but it's always better to do so content type is going to be set to application forward slash json and finally the last and most important thing is to pass in the body which is going to be json.stringify so we're going to stringify the data and we want to pass in cart items there we go so we're passing all of our products which are contained inside of card items what we can do is say if response that status code is equal to 500 then we know that something went wrong so we can simply exit this function if that is not the case that must mean that we're going to get the data and that data is going to be equal to a weight response dot json if we have the data we can say toast.loading and we can say redirecting because we will be redirecting to the checkout and finally we can call that stripe instance and say stripe dot redirect to checkout they really made this easy and we can provide the session id which is going to be equal to data dot id so we essentially created one instance of a checkout this specific user is going to be on that specific instance and it's going to be kept in the back end even after they're gone so if they want to return and continue with the purchase they'll be able to do so and that's it so now we are actually making a request to our backend we are accepting it and we are sending in the body with our request so we should be able to get all the products right here if we console log that's going to be rec dot body dot cart items let's see if that is really the case i'm going to go back to our application and i'll try to click pay with stripe and i'm going to open up the console there we go so i'm going to put it right here pay with stripe and we immediately get function.apply is not a function let me just quickly reload the page since we've added many changes there we go we can already see that something is not working and this means that i forgot to add the async keyword to our handle checkout function it's calling a wait a few times here so it definitely needs to be asynchronous there we go let's reload let's add headphones to our cart and let's pay with stripe okay nothing seemed to happen but that's fine let's see if we got a kanza log an interesting thing about this is since this is a real backend we won't be seeing a kanza log right here in the console of the browser's inspect element there is nothing here besides just a few warnings the console logs will be showing up in our terminal so as you can see right here if i collapse this we should be able to get there we go all of our products in this case that is just one product you can see we have a few images and it is a second pair of headphones that means that we can actually use reg.body.cart items to populate these items right here and form our final stripe checkout so what we can do is instead of this static array right here we can loop through our rec dot dot items and we can call a dot map method on it get each item and then create a function block we can add a comma at the end of course the reason why we're doing this is because we have to modify each specific item to provide some additional information like the price quantity and the image first of all there's going to be some gotchas with the images we can say const img is equal to item dot image 0 and then dot acid dot underscore rev if we look at our terminal you can see that we have our images we get the first image and then we have to go under acid and then there's going to be a reference right there but this reference is just that a reference to the image that's deployed on sanity it's not a real image right here so we can do const new image like this is equal to img.replace that reference is going to contain a string that looks like this image dash and we want to replace that with the actual url pointing to our image for that you can write https in a string so https colon forward slash forward slash cdn dot sanity dot io forward slash images forward slash and then we have to enter the id of our project so that's going to be right here you can copy it go to sanity manage and then find your project i'm going to paste it right here and then one more time forward slash production and then forward slash finally we also have to replace so dot replace a string of dash web b with a string dot web p it is possible that you'll have to handle this for other file types as well in this case we're using the web b format it might be a good idea to do jpegs so just slash jpeg or slash png turn it into a dot and this should give us access to that image what we can do is even kansa log this so let's console log the new image and let's provide a string image and then add a comma right here just to see if we're getting something meaningful so let's go back to our application reload the page let's add to cart open up the console right here and let's click pay with stripe as soon as we did that we got back undefined which is usually not a good thing it would be interesting to see where that came from it couldn't be this and it shouldn't really be this as well so let's just keep going with this and potentially we're going to get to something meaningful really soon now that we have our image we want to return an object that is going to represent one of our items first we have to set up the price underscore data there has to be a currency of course so we can say currency is going to be equal to usd we have to provide some additional product underscore data and of course that's going to be the name which is going to be item.name and also images where we're going to provide an array that's going to include just our new image we also have to provide the unit underscore amount and that is going to be item dot price times 100 because the unit amount has to be in cents finally we're gonna say adjustable quantity with an underscore in between and we're going to set that to an object that's going to say enabled is going to be set to true and a minimum is going to be set to 1. finally the starting quantity is going to be equal to item dot quantity there we go so now we've formed each one of our line items great this mode right here which is payment i think we already have it so i can delete it from here and then we have our success url as well as our cancel url and for now we can leave these urls as they are finally once we have all the params we want to say create checkout sessions from body params there we pass all of these params and then at the end we don't want to redirect we simply want to rest that status 200 and then dot json we're gonna send back that session that we have right here now let's save this go back to our application add to cart and click pay with stripe as you can see nothing happened yet let's open up the inspect element to see what's happening inside of the console let's start from scratch warning each child in a list should have a key prop this is happening in product details this is just a warning but i always like to fix these small errors so if we go to product more specifically if we go to product details that's going to be under slug let's try to search for a map it is right here and yes we are missing a key right here so a key in this case is going to be index this map has a key and this map right here also doesn't have a key but this is not a jsx element so we should be good to go warning expected on click to be a function but got a value of string that is fine we just put that as a placeholder same thing for this this this and this so it looks like we are actually fully okay if we click here though we get two errors localhost 3000 api stripe 500 that means that we are going to our stripe and we are being hit with a 500 right here which means that something is going wrong unexpected token c in json at position 0. we have to debug this together let's go back to our cart one more time to see if you're properly making that api request we create a new instance of stripe or rather get the existing one then we create a response that's going to go to forward slash api for slash stripe we set the method to be post the headers to content type application json and then we send back the cart items if the response is 500 then we go outside of the function if the response is not 500 we get back the data a weight responds that json we load it and then we redirected the checkout where we set the session id to be equal to that data id that we returned all of this is looking good to me so a problem must be somewhere inside of our stripe back-end even though stripe docs suggested the user require here i think we're good to go with using a regular import statement so we can say import stripe from stripe there we go and then we can say con stripe is equal to new stripe like this and then we provide dot stripe secret key in this case i was always used to writing next underscore public underscore stripe secret key so let's go back to our process.env and right here rename this to next public stripe secret key now if we go there we can use this process env variable there we go whenever you change variables it is always advisable to simply rerun your development environment there we go so we have our handler we get our cart items right here we create our params and then we simply return the session this looks good to me let's reload one more time let's add to cart open the cart and click pay with stripe the same error is happening one more time localhost 3000 forward slash api forward slash drive internal server error if we click right here and right there we should be able to see something at the payload and we can see that we do have a pair of headphones so we were successfully sending them in but we can see an error right here cannot read properties of undefined reading map let's go back to our code let's search for a map and as you can see it cannot read property of undefined reading map this is a weird error but it definitely must do something with our cart items and the way we're mapping over them if we open up the console we can see that cart items seem to be undefined although that definitely shouldn't be the case we are passing them right here body and then cart items oh i see the error right here we're passing the card items straight right here as the body we didn't specify an object where we said cart items are equal to cart items in the body so we're immediately referencing to that so if we go back to our backend endpoint the card items are going to be straight inside of the rec dot body there we go so right here rec.body.map should be fine in our case let's retry the request there we go looks like we got another error but this time it is a 400 bad request let's open the new one received unknown parameter line item 0 adjustable quantity minimum did you mean minimum yes i misspelled that so stripe really gave us a meaningful error right here this is going to be minimum there we go let's try to retry it one more time pay with stripe and another 400 the currency of your line items usd must match with your currency of your shipping rate and the shipping rate is in euros so this is really cool stripe is really making sure that we do everything correctly so i'm going to go back to my shipping grades and i'll see if i can edit them it looks like i cannot edit them right away so what i'm going to do in my case i'm simply going to switch this to euros but you can keep it in usd if this worked for you so i'm gonna go back right here reload this and b with stripe another 400 the currency of your item line euro must match with the currency of your shipping rate which is in usd so it seems that it is the other way around now i'm gonna bring this back to usd and i'll try to create two new shipping rates so let's simply go to shipping rates i'm gonna add a new one and that is going to be in usd as well let's do something like zero again just free shipping and let's click save so now we know that this is in usd and i'm going to copy the id right here and let's say that we only have one shipping rate which is going to be free i'm just going to paste it right here let's save that and let's test it one more time pay with stripe and we got a 200 and we were redirected to our checkout would you look at this we have our special javascript mastery checkout which is currently in test mode we can modify the quantity right here we have the price of our headphones the subtotal the free shipping and the total amount and right here we have a beautiful checkout which is powered by stripe and it allows us to enter all of our information let's give it a go so right here i'm gonna enter my email i'm gonna do javascript mastery zero zero at dot com card information for stripe you have a fake demo card which is four two four two and then just keep repeating four two until you come to the end you can just enter four two four two for the date and same thing goes for the cv the name can be something like javascript mastery and you can also choose your region and let's click pay and we have a successful order and we were returned back to our home page this means that we have successfully carried out our first transaction of course this was just a test payment but with stripe it should be fairly easy to bring this to real payments as well let's go back to our shipping rates if we go to our payments and under our payments in our stripe dashboard we can see a 55 bucks succeeded payment we can even open it up to see more information about a customer to see the ending of the car they used the checkout summary and everything is here if you were to ship these products you would be able to do that based on this information so this is great amazing job we have actually carried out a complete test payment looking great and if you want to send an email about a successful payment to your paying customer you can go to settings right here scroll down to business settings and then emails email customers about successful payments and that's going to be it just make sure to save it right here it is highly likely that these payments won't be set for test payments but if you turn this on once you actually start accepting real payments they will get an email but just the fact that we can see our succeeded payment right here is enough for me this is looking great now what do you say that we create a great looking payment succeeded page let me show you how this looks like on our finished site we can buy some speakers and headphones and we can pay with stripe in here you can see how it looks like for multiple products we can enter our email and in this case i chose two different shipping methods you can do that as well i showed you how easy it is to create a new shipping method we can enter our fake card data right here there we go and for name i'm gonna use javascript mastery and let's use some fake address right here test test let's do zero zero zero zero and the city is going to be test and we can pay it let's not save this and payment succeeded thank you for your purchase with a lot of confetti right here so let's implement this new successful page right away that's going to be our next task let's go back to our own page and let's simply collapse it right here to do that we can create a new page inside of the pages folder so let's right click click new file and let's call it success.js inside of here we can also run rafce we're going to call this success and let's first import all of the components that we're going to have to use let's fix the typos first of course success with double c and double s we want to import react use state and use effect hooks we also need to import the link component which is coming from next forward slash link we're gonna also import an icon called bs bag check fill and that is coming from react dash icons forward slash bs we're gonna also have to use the use router hook which is coming from next forward slash router finally we're gonna also use the state context here so we can say use state context and that is coming from dot slash context forward slash state context that's all that we need so first things first in here we can immediately get some properties from our state context we are gonna get set cart items we need this because we'll reset the cart items to an empty array set total price we're gonna also reset this to zero and then set total quantities as well like this because that's also going to be reset to zero and we get all of these by using that state context i hope that by now you can notice the advantage that we got by using this specialized context state we can always just tap into it from all of our components and they all share the same state we're going to also create a new state in this component right here so use state we can use the use state snippet and we're going to call it order and set order and at the start it's going to be set to null finally let's create the jsx for our success page we're going to have a new class name right here that class name is going to be success dash wrapper then inside of there we're gonna have a new div and that div is going to have a class name equal to success inside of there we're gonna have a p tag and this b tag is going to have a class name equal to icon and of course it's going to render the bs bag check fill which is going to be a self-closing icon component we can already go to this page by simply going to success so localhost 3000 for slash success let's try to open it up there we go and success there we go you can see that we have this bag right here then below our p tag we're gonna simply create an h2 inside of this h2 we can say thank you for your order great and now that i think about it we won't even be needing this order right here and we also won't use the use router so we can get rid of those things immediately great below r thank you for your purchase we're gonna have a p tag right here and that p tag is going to have a class name equal to email dash msg as in message so we can say check your email inbox for the receipt there we go and below that we're gonna add a description to our successful order and that's going to be a p tag that's going to have a class name equal to description and there we can say if you have any questions please email and then we can render an anchor tag right here that's going to have a class name equal to email and an href is going to be equal to mail 2 and then you can enter your name right here i'm gonna do orders at example.com and you can simply copy that email address and put it inside of the anchor tag as well now if you save this they'll be able to click here if they have any questions finally below this b tag we're going to add a link and that link is going to have an href to simply forward slash we want to render a button inside of it and that button is going to have a type equal to button we can give it a fixed width of around 300 pixels and finally we're going to give it a class name equal to btn and it's simply going to say continue shopping there we go we have our button we have our confirmation everything is here besides one thing we also want to clear all of our states we need to make sure that the previous order is completely done so to do that we're going to use a use effect and as soon as somebody comes to this page meaning on load meaning this dependency array is going to be empty that means that this function is going to execute as soon as the successful page is loaded there we want to first of all clear the local storage so localstorage.clear this is something that we're going to implement later on so far we are not yet saving anything into local storage but just so we don't forget let's clear it here in any case then we're going to also set the cart items to be equal to an empty array we will also set the total price to be set to zero we need to set the total quantities to be zero as well and we get an error as you can see right here because set cart items doesn't seem to be existent let's see set cart items this is looking good to me it is possible that we are not passing it though through our context so if we go here and scroll all the way down we need to pass set cart items there we go it looks like we're also not passing the set total price so let's pass the set total price as well and the same thing goes for the set total quantities we're gonna pass that as well great but what do you say that we add that great looking confetti page as well well that confetti is going to be another one of our components well the code for that confetti is going to be in a new file inside of our lib we're going to create a utils file utils.js utils stands for utility functions you call these in a few places in your application you don't want to write the code everywhere you just write it here and then call it from other places so right here we can import confetti from canvas dash confetti this is a great confetti package that i found online and they provide you with the entirety of the code to achieve that confetti look so let's go to our site and let's simply google canvas confetti mpm if we go here you're gonna notice that they have almost 250 000 weekly downloads and what do we have to do if you keep scrolling you can see that you can easily create something but we want to look for some pre-done examples so let's scroll up let's go to demo we have the basic canon right here we have the random direction the realistic look as well i really like this one yeah fireworks is going to be good so let's simply copy this fireworks right here let's export const run fireworks like this that's going to be an arrow function there we go and inside of there we can pass our code we're just gonna make this about five seconds i think that should be more than enough and all of this code is something you don't have to worry about we just have it here we copied it from there library so now if we go back to our success page we can simply import the confetti from the top import run fireworks and this will be coming from dot slash lib forward slash utils and we can simply call the run fireworks right here there we go so what do you say that we give it one final go we go through the entirety of our application and see if everything works first of all it looks like we have some problems with our confetti so let's go to our utils right here confetti from canvas confetti this is looking good to me let's reload the page and it looks like i misspelled confetti my bad there that's going to be 1f and then two t's sorry about that hopefully you got it right so once we have that we should be able to reload the page and we immediately can see that confetti it should stop after about five seconds but as i promised let's give our application one final go so let's say we want to buy some headphones we can click shop now to buy the summer sale headphones right here and we can add them to the cart we're gonna also figure out hey we might want to use some cool in-ear headphones as well so let's add two pairs let's go to our cart and let's click pay with stripe it's going to take a second we'll see that redirecting popup and we can immediately see our entire checkout with the correct amount let's go ahead and enter our email enter the 42424 as the card information name on card is going to be javascript mastery and we are ready to pay it's processing hopefully we got enough money and we are not redirected to our success page that's a bummer right so what we can do is we can see that we are redirected to success is equal to true and if you remember correctly stripe had that success url so actually we have to redirect to just success or just cancel like this without any extra parameters like this i think this is going to work so let's just give it one final go i'll try to be really quick add to cart pay with stripe you can see it looks great on mobile as well we input our demo card we are really going hard on it right we enter our name and we pay it and there we go thank you for your order the success page is right here and we can continue shopping this is looking great if you remember correctly i promise you that we're gonna do a few things and first of these things is to also fix the buy now button as right now it is not working the buy now button is going to be much simpler because instead of adding something to the cart and then going to pay with stripe we're going to make it work immediately just straight to the checkout so that's going to be our next step and we are slowly closing down on this great project a fully functional ecommerce application with complete stripe payment integration and with sanity the platform for structured data looking great stay excited until the end because we are really nailing this down you're learning quite a lot and even better stuff is coming implementing that by now functionality is going to be incredibly easy let's go ahead and collapse this let's go back to our code and what we can do right here is go back to our slug file the product details file we can scroll up and go to our buy now button on click we can call our handle by now function and that function can be created right here cons handle buy now the only thing we have to do to make this look and function great is call that same on add function right here on add and we're gonna pass the product we want to buy and the quantity we want to buy and we're also going to set the show cart to be set to true so as soon as we do that we can go back and now if you simply click buy now as you can see we're gonna get an error set show card is not defined and that's happening because we are not getting it right here from the state context so we can say set show cart now we have access to that and if we reload the page and click buy now you can see it adds it and you can immediately complete the purchase so essentially this is incredibly similar to add to cart this one just adds it so you can continue shopping but if you go ahead and click buy now it is immediately going to hide it right there and you can proceed with the purchase with that said you remember how we had some errors before so let's open up the console and see if we still have some we have one right here on click is supposed to be a value but it is a string so let's fix this one right away we can already see that our error is inside of a span element inside of product details so that is our slack component right here but i think we solved this so if i reload the page yep now we only have one error so that's going to be a span inside of product details let's go ahead and find it on click is equal to and then right here so if you click on this specific number there we don't need to have any on click properties just like that and now we have zero errors zero warnings everything is working as it should we can go ahead and inspect it go to the mobile view right here let's do iphone 12 this is looking good as well everything is mobile responsive let's go to our speaker looking great as well these elements scroll right here at the bottom we can hover over specific elements to get new images we can add it to the cart and the change appears right here so everything is looking great we have our final e-commerce store of course you can make this completely your own go wild with the styles now that you know how the functionality works styling it is easy find a great looking design for an e-commerce store online accommodate it to your own product and go wild but the most important part is that you know how to handle the items using sanity and you know how to handle payments using stripe with that said the last step in our journey is deploying this great store to the web so that you can share it with your friends potential employers and most importantly customers if you're planning to bring this store live deploying applications using nextgs is pretty straightforward let me show you how to do it first of all let's close all of our files to have a clean working environment there we go and we can also close all of our currently open pages right here we just need the store and the sanity managed project there we go for deployment with nextgs we're gonna use versailles versel combines the best developer experience with an obsessive focus on end user performance so what we can do is just click start deploying right here and then you can continue with github once you log in you'll be able to import your git repository but of course to get our store live we have to first push it to git and github to do that you can go to github create a new repository let's name it something like e-commerce underscore sanity underscore stripe again feel free to use your own name right here i'm going to make it public just in this case and let's go ahead and create a repository once you have it keep these instructions right here on the side and on the left side we're going to have our code editor so let's open up our terminal ctrl c and then y and make sure that you are inside of this ecommerce folder let's run git init git add dot git commit dash m and then in here we can say first commit let's also change the branch to main let's also do get remote add origin and finally get push u origin master in just a few seconds you can reload your github page and you'll be able to see that all of your code is right here now we can go back to our cell and immediately we have our e-commerce website right here so let's import it right here we can choose a next.js framework and we can add some environment variables right here we can essentially copy everything we have in our env so let's copy the next public sanity token and right here we can copy the actual key let's add it and repeat the process for all other variables next public stripe publishable key as well and the value right here final one is next public stripe secret key and also the value for that as well and we are ready to deploy our project so let's click deploy and let's wait about a minute as vercell is going to do all the heavy lifting for us and there we go in just a few seconds we can see our website deployed we can click right here and we'll be re-navigated to our new deployed site this is looking great let's go ahead and test it out let's go to the speaker right here and let's buy it pay with stripe we got redirected to our own custom stripe checkout let's try with the fake card one more time again four two four two four two name javascript mastery and pay its processing and immediately thank you for your order which means that it went through if we open up our stripe dashboard you can see that we have our newest payment right here and it is looking great so this is it the deployed store finally let me show you how easily you can add new items or remove and even edit the current items using sanity you don't have to go back to the code you can do everything straight from their interface so if the price changes for these specific headphones you can modify it really easily or if you want to change the images the title or anything else it is incredibly simple so what we can do is we can go back to our project and in here we can just manage the project details but now since the project is deployed we also need to deploy the sanity studio and that is also going to be incredibly simple so let's go back to our code let's open up the terminal let's cd into sanity ecommerce and i think that even running the command sanity help is going to tell us what we need to do to deploy it so as you can see we have a lot of different commands right here and there is a deploy command of course there is to make it incredibly simple so we can run sanity deploy and this is immediately going to get the project info for the hostname i'm going to type ecommerce dash jsm and sanity is building it out and there we go in just under half a minute we have success studio deployed to and we can control click this link connecting to sanity and there we go you can share this link with people who own the store with your fellow developers copywriters or really anyone who wants to edit the content and you can do that right here so if we wanted to add a new product let's go right here let's add item and let's add something interesting for example this smart watch right here which we haven't seen so far there we go we can say smart watch the slug is going to be automatically generated the price is going to be 99 bucks and we can say cool smartwatch there we go and let's publish it now if we go back to our deployed site go back to the home page and press ctrl shift r to do a reload while cleaning cache you can see that our watch is going to appear right here instantly you can see it you can buy it and everything is working perfectly that is the power of integrated headless software such as stripe but most importantly sanity everything is working perfectly you can hand this over to your client to the store owner and everything will be fine great so that part is now done our sanity desk is deployed and if we go right here and reload the page you should be able to see there we go our studio is now deployed and when it comes to the usage there is no way we're going to go past these limits we've done 216 requests and we can do 1 million same thing goes for all of these other metrics we have plenty more to go so working with sanity is phenomenal they even decided to sponsor this video to allow me to build such an amazing e-commerce application so definitely expect more great projects really soon with that said thank you so much for watching that's going to be it for this video and i'll see you in the next one have a wonderful day [Music]
Info
Channel: JavaScript Mastery
Views: 830,866
Rating: undefined out of 5
Keywords: javascript, javascript mastery, js mastery, master javascript, ecommerce website, react ecommerce project, react eccomerce, react ecommerce application, react ecommerce app, react web shop, react e commerce web shop, web shop react, web shop react tutorial, ecommerce tutorial, ecommerce react js, ecommerce stripe, react ecommerce stripe, stripe website, stripe react, stripe react js, stripe checkout react, stripe checkout page react, stripe e commerce, react tutorial
Id: 4mOkFXyxfsU
Channel Id: undefined
Length: 214min 11sec (12851 seconds)
Published: Fri Apr 22 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.