🚨 Snipcart updated how the script is loaded. Here are the installation docs for more information.
I've also update the code in github to work with Snipcart's latest version.
We want to make sure that when we add something to the cart, we're going to be able to actually add it to our cart. I'm going to be using Snipcart to handle my cart and checkout flow.
We will also our cart update inside of our header with that dynamic value. To do that, we will sign up and install Snipcart where we add the installation to a custom document file and add our class name and data attributes to all of our Add to Cart buttons.
Lastly, we will install the useSnipcart hook so that we can grab that context to show that subtotal anywhere inside of our application.
Colby Fayock: [0:00] Now that we have our home page and we have individual pages for every single one of our products, it's time to actually let people buy these products. To do that, we're going to use Snipcart, where we can drop in a shopping cart that's going to provide us an end-to-end checkout flow.
[0:14] To do that, we'll add in the Snipcart SDK and map all of our products right inside of the DOM so that Snipcart can actually see all of our products inside of that page. To get started, you'll need a Snipcart account so you can hit get started.
[0:25] Or if you use the link SpaceJelly.dev/Snipcart, you'll be able to get an additional one month free. Either way, once you sign up, the first thing you'll need to do is verify your email address before we can actually move forward.
[0:36] When we first drop into Snipcart, we're going to notice two things. Particularly, we're going to see this list of nice things that we need to do in order to get started. We also see at the top here, we have these two tabs, live and test. They are exactly what they sound like.
[0:50] Where live is going to be the production site, and test is really going to be basically development mode, where we're going to learn how we can actually integrate these things. The first thing you want to do is click test to make sure that we're not actually making any changes to the production site.
[1:04] Because we are in test mode, we don't need to configure as much stuff as we would when we are in live mode. We're going to skip through some of that stuff. What we're going to move forward to is we're going to get started installing Snipcart to our site.
[1:16] We're going to head over to the Snipcart documentation where you can go ahead and click this Snipcart install link, where it will take you to the docs. Or you can navigate to docs.snipcart.com, where you'll be able to find store setup and installation on the side.
[1:29] As we start scrolling down, we can see what we need to do in order to install this. We have some preconnect tags, which will help with the performance. We have our style sheets, which is going to be their styles for their shopping cart.
[1:40] Then we have the script tags, which is going to add the JavaScript that's going to make the shopping cart actually work. Before we actually install this on our project, we're going to use an additional tool to supplement our Snipcart installation.
[1:53] As we're using Next.js and React, we're also using client-side routing. Once we click a page, that new page is going to be loaded right inside of the browser, as opposed to making a full request to the actual server and getting that response back.
[2:08] That's great. That's going to help these pages load snappy, especially when this is statically deployed. The issue is, we're going to miss some of the data inside of the DOM that was replaced outside of the React lifecycle.
[2:21] Particularly, that's exactly how Snipcart works, where it is a very independent way to add a strapping cart to your application.
[2:28] That said, when we try to add particular data points to our application based off of that information, we're going to lose that when React reloads the page.
[2:37] Instead, we're going to use a React hook on top of that, in order to try to mitigate those issues. That hook is called useSnipcart, which is a simple hook that I created that wraps the Snipcart library, so that we can access it between all the pages and not have to worry about that ever-changing state outside of the React lifecycle.
[2:56] To get started, we still need to follow the standard installation which we'll do now. On top of that, we'll install useSnipcart alongside of it. Back to adding the installation of Snipcart, we want to add all these tags globally so that all of our application can access the cart and the Snipcart state.
[3:13] To do that, we need to use a custom document page inside of Next.js, which is going to allow us to modify outside of the body and load these scripts so that they do load globally. Under source pages, we're going to add a new file and we're going to call that _document.js.
[3:31] We're going to copy the same exact snippet right over from the Next.js documentation and paste it right inside. Next, we can go ahead and grab those pre-connect hints. Back inside of my document.js file, the first thing I'm going to do is open up that head tag, so I can go ahead and paste in those pre-connect links.
[3:49] Next, we're going to do the exact same thing with our style sheet and paste that in right under our pre-connect hints. Finally, we need to include this Snipcart script. We're going to go ahead and copy that tag and then we're going to paste that under our next script tag that we see here.
[4:03] As we're looking through what we just pasted in, we have this hidden div, which is where Snipcart's going to inject the code. We also see we have this configuration of data API key where this is where we need to paste in our API key. To find our API key, again, make sure we're in test mode, so that we're using our test API key.
[4:22] We can head over to our account section right here, where if we start to scroll down, we're going to see our account section where we can select API keys and we see our public test API key which we can copy and we can paste right into that field.
[4:36] At this point whenever you add or edit your document file, you want to make sure that you restart your server so that it can pick up those new changes. Once we're back inside of our application, we're not going to see anything change by default.
[4:48] If we reload the page and we search for Snipcart in the filter, we're going to see that we are indeed now loading those scripts. Next, we want to be able to add our products to the shopping cart and see that shopping cart.
[4:59] To do that, we can head over to the product section here, where we're going to see the documentation on how we can do that by adding all these attributes to each of our buttons, which is going to serve as our Add to Cart buttons.
[5:11] As we can see, we have a class what we're going to add, but then we have a bunch of data attributes, which is going to be where we're going to put our product data.
[5:18] What I'm going to do, is I'm going to simply copy this snippet. Inside of my product page at productsslug.js, I'm going to scroll down until I find that buy button. This button component that we're going to be using, is going to be a wrapper around the actual button element itself.
[5:35] What we can do, is we can paste in these attributes just like we would if it was a regular button element. Where the only thing we need to do, is we need to make sure that we fix this class name so that it's going to be recognized by React.
[5:47] Additionally, we want to make sure that all these data attributes have our data. We can start to replace these data attributes with the data that we have. If we scroll down, if we remember inside of our query, we have our ID, image and name, price, and our description.
[6:02] If we scroll up, we can start to replace some of these things such as our product, the ID. We can add our price as product.price. We can have our URL, which is going to be dynamic, which will come back to in a second. We have our description where you don't necessarily need a description.
[6:19] I'm going to go ahead and get rid of it. You can add it optionally if you want. For our name, it's going to be product.name. We know we have our image URL by scrolling up to our image tag, where I'm going to grab the product.image.url.
[6:33] I'm going to go ahead and replace that asset URL. The tricky thing is, for our URL, we need to use our slug, which we're currently not querying. If we look down at our list, we can see that it's not inside. What we can do is simply add that slug right inside of that query, where we can now scroll back up and we can start to create a dynamic value out of that URL.
[6:54] Where I'm going to say, I want this to be /products, and then I'm going to insert the variable of product.slug. Once we refresh the page, we can go ahead and click that Add to Cart button, where we can see our Snipcart cart. We can even see that we can interact with this where we can add items. We can simply remove all of the items.
[7:12] We're going to be able to manage our shopping cart or add items back into it. If we notice, the shopping cart is opening full width. Personally, I like to open it as a sidebar. We can do that by configuring it right inside of our Snipcart snippet.
[7:26] Back on our installation page, if we scroll all the way down into the bottom, we're going to see that we have our global configurations. Particularly, we're going to look at data-config-modal style, where all we need to do is add this attribute to our hidden div and it's going to only open up on the side.
[7:42] Back inside document.js, I'm going to go to that hidden div and the very end, I'm going to go ahead and add that value. Remember at this point, make sure you restart your server as we made a change inside of document.js.
[7:54] If we go ahead and click Add a Cart again, we can see that it's going to open up to the side and it looks great. We don't only want to be able to add products from our product page, we also want to be able to add them from the home page.
[8:03] If we navigate over back to our home page, we see that we also have these Add to Cart buttons. Inside of our index.js, we have that same button for Add a Cart like we had before. I'm going to simply copy that button right from my product page.
[8:17] I'm going to paste that right in to my index.js. Similar to our product page, we need to make sure that we have all this data. We should have most of this, but we never used the ID on this home page. We can scroll down until we find our query, where now we see our products.
[8:33] I'm going to simply add that ID. Now, once I reload the page, I can add my Cosmo-fitted hat and we can see it gets added right to the cart. The last thing we're going to do in this lesson, is anytime we add something to the cart, we want to make sure that this value in our header is going to reflect that cart value.
[8:49] The traditional way to do that with Snipcart is by adding a class name to that container, so that Snipcart can handle updating that value, similar to how we added a class name to our Add to Cart buttons. The issue is like we were talking about before with client-side routing, React will override that and wipe out that value whenever we change pages.
[9:08] That's where we are going to use our useSnipcart hook in order to alleviate that issue. First, we want to install useSnipcart. I'm going to copy this Yarn add command and install it as a dependency. Of course, you can use NPM if you prefer.
[9:23] Then we see we want to wrap our entire application with this Snipcart provider. Before when globally adding our scripts, we use the document.js file. We want to instead use the app.js file where this is going to be able to load all of our React, and we're going to be able to pass in the context to all of our components.
[9:40] I'm going to first copy this import statement and I'm going to paste it right at the top of this file. Then all I need to do is wrap it with the Snipcart provider. I'm going to add that Snipcart provider around my component.
[9:54] What this is going to do is make this Snipcart provider context available throughout the application. We want this available in the header files. I'm going to open up header where we can scroll down, and we can see that what we ultimately want to update is this .00 value.
[10:09] To do that, now we want to use this useSnipcart hook. I'm going to first copy that import statement. Like before, I'm going to paste that in as a dependency at the top. We can now grab that snippet, which we're going to use at the top of this header component, which is where we use our hooks.
[10:25] Now, let's log out this cart object so that we can actually see what's inside. Once the page reloads, we can see that once Snipcart actually gets picked up, we can open this up and we can see all the fields that we have available, which includes a lot of the data that we necessarily don't need right now. What we want to find is the subtotal.
[10:42] If we scroll down here, and we actually click these three dots to grab the value, we can see that it's currently at 70. We want to replace that inside of our header. Down where we're adding that value, I'm saying I want that to be cart.subtotal. We can immediately see that it updates to 70 inside of the header.
[11:00] Traditionally, in e-commerce, we usually see two decimal places to make sure that we account for the cents inside that value. I can say that if I do have a subtotal, I want to use two fixed. I'm going to pass in two, which means it's going to have two decimal places.
[11:15] Now, importantly, I added this conditional operator here to make sure that it doesn't try to run this function if that value is undefined. Now, we can see that it was immediately updated to 70.00. Even if we add a new value, we can see that it's going to update inside of the Snipcart shopping cart. As soon as we scroll up, we see that it's now 90.
[11:34] The only issue, though, is if you try to click that, nothing is going to happen, where we want to be able to see our shopping cart, and we don't want to force people to have to add something to their cart in order to actually see the cart.
[11:45] Well, we skipped the Snipcart installation for showing the value of the cart. We want to be able to allow them to open up the cart. To do that, we're still going to use the Snipcart installation, where all we need to do is simply add a class name, a Snipcart-checkout, on the button we want to activate.
[12:01] Back on that button inside of my Header.js, I'm going to simply add that class name and paste in my Snipcart-checkout. Now, if we try to click that cart value, we can see we can open up our cart. We have full access to checkout.
[12:14] In review, we wanted to make sure that when we add something to the cart, we're going to be able to actually add it to our Snipcart cart. When I click Add to Cart, we can see our Snipcart shopping cart.
[12:23] We can also see that it's going to update inside of our header with that dynamic value. To do that, we signed up an install Snipcart where we added the installation to a custom document file and added our class name and data attributes to all of our Add to Cart buttons.
[12:38] Finally, we installed the useSnipcart hook so that we were able to grab that context to show that subtotal anywhere inside of our application.