Create a Shopping Cart Page to Manage Products to Purchase in a Next.js App

Colby Fayock
InstructorColby Fayock

Share this video with your friends

Send Tweet
Published 2 years ago
Updated 2 years ago

A common feature in an eCommerce store is to have a shopping cart to manage products. In this lesson, we're going to start off with a new shopping cart page that displays a placeholder item. This is a static cart page that includes basic styles with a static cart table and a checkout button.

Using the cart state available globally, we'll add the products our customers currently have in their cart as well as trigger a new checkout session with Stripe whenever they click the Check Out button.

Instructor: [0:00] When we try to add them to cart, we can see that our global cart state updates. When we click on that cart, we get taken to Stripe checkout where we can purchase those products, but typically, in online stores, there's a cart page where you can view and manage your cart.

[0:12] To get started, I already created this new static cart page. Aside from this header, it includes some simple things like the product name, quantity, price per item, and the subtotal for that particular product. It also includes a checkout button that we can use to send people to Stripe to complete their purchase.

[0:25] Inside our code, we can open up the cart page, where we can see that we configure a table with some placeholder data that we're passing into this table component, which I also created and added to the project. We're not really going to cover here how this table works. This goes through and maps out data into a standard HTML table.

[0:41] Like our placeholder data, we can see that we're passing in an array of objects, and the columns are defined by the columns array. While we have this cart page, we want to make it dynamic, so that when we come to this page, we can see all the items in our cart. To do that, we can use our global cart state and then import our data, so that it gets returned in the same structure as our placeholder data.

[1:00] To start, inside of our useCart hook, we're already creating an array of products in our cart called cartItems, which we can use to fill out our table. Currently, we're not making cartItems available in our global cart state, but because we're defining cartItems within our hook, like subtotal and quantity, we can make cartItems available right in that object.

[1:18] Now back on our static cart page, we're going to import our useCart hook from one level-up hooks use-cart.js. Inside of our cart page component, we can destructure our cartItems from our useCart hook.

[1:32] To test this out, we can console.log out those cartItems. Once we reload the page, we can open up our DevTools, and we can look inside and see our cartItems with the two objects.

[1:41] As we can see, each object has an ID, a price per unit, and a quantity. If we look at our placeholder data, we can see that it also has an ID, quantity, and price per unit, but it also has a total for that product, and it also has a title.

[1:53] To start, we're going to replace this placeholder array. We're going to start off with our cartItems. We're going to map through it. For each item that's inside of it, we're going to run this function, where because we already have some of that data we're going to spread out our original item. First, we're going to create a new property called total, which we can define as item.quantity multiplied by item price per unit.

[2:13] If we look in our browser, we can see that we have our two product rows for both products where we have our quantity, price per item, and item total, but we're still missing our product name. Similar to before, we can use our products array from our JSON file to fill that in.

[2:26] At the top of the page, I'm going to import my products from level-up products.json. Inside of my map function, I'm going to create a new constant called product. For its value, I'm going to look inside of the products array and use the find method, where I'm going to destructure the ID as my argument, where for my function, I'm going to say that the ID needs to equal my item ID.

[2:46] Now with that product, I can set my title equal to product.title. If we look back in our browser, we have both of our product names. Once we hit that checkout button, we want it to take us to Stripe. Back in our use cart hook, we can destructure the checkout function where on our button, we can say when someone clicks on it, we can fire that checkout function.

[3:03] If we go back to our browser and we click checkout, we can see that we get redirected to Stripe with both of those items. Finally, back in our app, if someone hits the cart in our navigation, that still redirects them to Stripe. We want someone to be navigated to the cart page any time they click the cart.

[3:17] Back on our navigation file, we can see that we're currently using a button where we have an onClick handler that runs the checkout function. Instead, we can turn this button into a link component, remove this onClick handler, add an href, which for this we can set to /cart, and finally we can add an anchor tag message inside of that component.

[3:33] Now, if we open up our app and click on the cart, we get redirected to the cart page. In review, we have our store where we can add products to our cart, but when we click the cart, instead we wanted a cart page for somebody to view and manage their products. We took our static cart page and made it dynamic by mapping through our cart items from our global state.

[3:49] We additionally updated the checkout button on the cart page to send people to Stripe. Inside our code, we were first able to do that by returning our cart items inside of our useCart hook, where we then imported it into our cart page, where we then mapped through it to create our table data.

[4:02] Finally, so people could get to this cart page, we updated the button in our navigation, so that when somebody clicked it they got taken to the cart page, so that when somebody navigates to the cart, they can see their items and then check out.