Custom Cart With Shopify Storefront API
As part of Jamstack Conf, Jason is building a swag app with experts from around the community. This 5-part series will go through the whole process of building an e-commerce site with Shopify, Algolia, Sentry, Twilio, and Fauna.
Links & Resources
Full Transcript
Click to toggle the visibility of the transcript
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON: Hello, everyone, and welcome to the first of 5 very special Learn with Jasons. We're going to do a lot today. This is going to be big. So we're going to do this in 5 parts across 2 days. So today, we're going to do the first 3, on Wednesday, we're going to do 2 more and our goal is to build a whole Shopify powered database backed commandbar driven email notification sending error monitored e commerce. And we're going to do it all in about 5 hours total. And so, to help with that, first and foremost, we're bringing in Shopify expert Kelly Vaughn. How are you doing?
KELLY: I'm great. How are you?
JASON: I'm signing up for a lot of pain.
KELLY: I'm loving this 5 part series, usually, I hit part 1, I'm like, cool,ed good enough, let's ship it. You know, so I get to see things continue to happen. But I don't have to write the code. It's great.
JASON: You're not going to do that. You would never leave us after part 1, you're hanging out, here to the end. Ride or die.
KELLY: That's right.
JASON: I'm seeing a ton of first time chats, what a cool feature from Twtich. Welcome to everybody here. Francisco. Seraj, thank you for hanging out today. This is going to be fun. I see a lot of familiar faces in here, too. I am pumped. This is going to be fun. However, we don't have any time to get this done. . We're doing this in an hour. And what we have to do is we need to build out a full shopping cart experience. And we've got to do it fast. So Kelly, before we start, why don't you give everybody a quick background on who you are and we'll jump right in.
KELLY: Yeah. My name is Kelly Vaughn, the founder and CEO of the Tap and co founder of Gavalo. I have been a Shopify partner for a little over 7 years now. So I live, eat, breathe, sleep, dream about, unfortunately, e commerce, literally all the time. I've been coding for almost 20 years, and I live in Atlanta, and my house smells like countertops were just put in because countertops were put in. And I'm really excited.
JASON: Congrats on the countertops.
KELLY: Thank you!
JASON: Thank you for the subs. I see Mechanic Now, thank you, thank you, thank you. Let's jump over and start building this thing. We're going to get right into this screen. And I'm going to show you. This is this is where we were going. So there was a whole gimmick, right? We were originally planning to do this live at Jamstack Con and we were going to pretend I had forgotten to build it so during the conference I was building the swag site. As some of you may know, we had the most Murphy's Law of all things happen and a bird flew into a transformer and took out power for the whole neighborhood that we were trying to film in, which meant that we weren't able to do the live stream part. Our hot spot wasn't strong enough to do that effectively. We rescheduled, which means, this is going to seem a lot less funny, I guess, and so we'll just, you know what, if we can't be funny, we'll be useful, right? I guess that's if we had to optimize for one thing. So here's what we have right now. We have this cart kind of slide out deal. We've got these two pieces of swag. And these are set up where you can kind of choose the T shirt size, but when you click these buttons, nothing happens, right? They don't do anything. You're not updating your cart. So what I wanted to work with you on, and thank you all for the bits and the cheers. Thank you very much. Still seeing a lot of first time chatters, what up y'all. Someone's watching from the Chick fil a drive thru.
Good choice.
Zander gifting out a bunch of subs. Even though the background's different today, it still works. OK. So here's what we need to do, we need to use Shopify's store front API, because they have a new cart feature. Right? If I look at the reference, we've got cart and this is the feature that we want to use, I'll drop this in the chat for everybody to look at. But so, the way that I was thinking of making this work is this site is built in astro. And so, if we look at the site itself, we can see that we've got, we've got a basic layout and our layout's barely straightforward here. We have our styles, I'm not going to go into the CSS at all today. I read all of this ahead of time so we wouldn't have to focus on it. Let me collapse that. But go check it out, it was fun to write, I think there's cool stuff in there. We have a header, our header loads a client component. This is a React component or Preact that will load when the site loads. This is where we use the client load and that will rehydrate. And then, that's it, we have the slot where the rest of our content goes and that's where this index.astro comes in. In index.astro, I'm going to collapse the styles. We have our layout, which is what we looked at. That wraps the whole thing and sets the title. And then, we have our add to cart button. And that also is going to hydrate as soon as we get an idle, like request idle callback, I think, is what it uses. And this gives us our two things. I pulled these in hard coded from Shopify, these are the variant IDs for the Jamstack comp and also for the swag pack. And so, these are set up in such a way that you can choose the size that you want, and then, what we need to make these do, if we look in this add to cart button, we like, if there are options we provide a select and then we show a button and button on click adds to cart. But that add to cart doesn't do anything, right? So we need to make this add to cart button work, and we also need the ability to load our cart where we have an empty and then, we need to be able to display the cart itself. We don't have it. There is no cart. We're setting it empty. So that's what we need that your brilliant mind for, Kelly.
KELLY: Cool. Just a couple things.
JASON: Probably the easiest way is through Netlify functions. And I have this set up already where we can run Netlify dev and I'll show here that badabing, here it goes, we have the environment variables we're going to need. We can touch lightly on how you would find those things. But we're not actually going to, like, go get them today because we don't have time. And we can also see that there are some functions here that I need to check and make sure I'm on the right branch so we don't
KELLY: Surprise, we're done.
JASON: They're all to do. That's what I want. We don't have to do some of the, like, really structural stuff. So, for example, here's our create cart. This has a like, send to Netlify or send Shopify store front request. We don't have to write this. Right? I wrote this ahead of time. This is a fetch API, this is a built in kind of fetch API, using node fetch to simulate the browser fetch API. And we send off the GraphQL query and any variables as a post request using application JSON and we send in our store front access token which lets us actually make the request. And then, down here, we're going to actually use that. But right now, we don't use it at all. It's just here ready for us to use so we can pull that around. Load cart, we pull in that send Shopify store front request to use it same with add to cart pulling it in. I could have set this up in utilities function, I didn't. I don't know why. Yeah. That's where we're starting, that's where we're going. Should we build?
Yeah, let's build.
All right. So what should I do first?
I was going to ask you the same thing. I do want to preface one thing. As Jason mentioned, we're using the cart API. This is brand new as of this month. If you already created a, like a private API key to use a store front API prior to October, you need to go in and update to be on 2021 110 if you want access to the cart API. A heads up there. I just saved you a lot of stress and struggle waiting to find out why nothing's working.
JASON: Yes. And let me make sure I have the Netlify, my Shopify.com and that should let me get to the Admin. It does. OK. I'm logging in really quick so I can do this off screen. And then, I will show everybody what we're looking at.
KELLY: Yeah.
JASON: Here are sour.
KELLY: If you're unfamiliar with Shopify APIs, there's the Admin API and the store front API.
JASON: You hackers, you dirty hackers.
KELLY: The Admin API is usually used when you're creating an application like a Shopify app on why there's a private app, public app, doesn't matter. You don't display this API key anywhere. Never, never. On the store front API, anything that happens on the Shopify store front or the headless build. And it's OK to expose that key because you're not creating, deleting customers products, orders, things like that. It's a manipulation of data that already is safe for the store front.
JASON: We are doing it in a serveless function. Technically, we aren't exposing that key. But, you know, we got options, right?
KELLY: Options are good to have.
JASON: We have the Netlify swag store and we've got a few things in here. Here's old Jamstack.com, this is what powerswag.Netlify.com. If you're interested in any Netlify stuff, you can find it there. But we have a couple things that aren't in there. Like the other Jamstack Conf thing. Where's the swag pack. Jamstack swag pack.
It's a good name.
JASON: Yeah, this is our swag pack that we want to be able to sell. And that's what we're pulling in here. And when we look at this site, this is what we're pulling in. Like, this is the swag pack and the slot we're pulling in.
KELLY: Yes.
JASON: So to use the cart API, we need to go to apps, and we've got this Shopify graphical.
KELLY: It's for internal if you want to test Shopify. You have two options here if you're building for yourself or for a client. You can go to private app route or you can go to the custom route app. Private, if you scroll to the bottom of the screen, there's a hidden thing that says manage private apps down there, you click on that to actually go through the process to create a private app. If you're working with a merchant, it's gated. So the merchant has to allow the creation of private apps. The other option would be to create custom app, which is an app you actually install on the store itself where you can build a user interface for the app if the merchant needs to, you know, manipulate any data. And you create that from within the Shopify partner's portal. It's free to sign up. You should do it. It's fun. Whenever you're not doing anything that involves Admin UIs, I recommend the private app route because it's a lot faster.
JASON: It is a lot faster.
KELLY: This is my friend Kurt.
JASON: Hello, Kurt. So now that we've got, I basically, if we click in here, you can see your, oh, shit, do I need to roll these now?
KELLY: Disable all permissions. The store front API, again, doesn't matter. Just make sure the app itself you don't have any Admin API permissions enabled.
JASON: Let me double check I did that. So
KELLY: It is a Kurt with a K. To answer your question. Doesn't hurt to also refresh it if you I don't think you're actually using it, though, I think you're just going store front.
JASON: Yeah, I've got to make sure I didn't accidentally show a whole bunch of permissions to everybody. I thought they would be hidden.
KELLY: Delete the store.
JASON: Get rid of it. Get rid of it. Load, load. Oh, no. OK. While we're waiting for that to happen, let's maybe write some code, right?
KELLY: Yeah. Let's write code.
JASON: We need to what? Like actually create a cart?
KELLY: Yeah. Let's start with creating the cart. We're not going to have data to pull into it yet. But you need it so you can actually see something's happening.
JASON: Yes. So the first thing we want to do is to create a cart, we need to make a request for one. So in here, we have our create cart. And I, through the power of movie magic am going to just have this query ready to go. So let me set this in here. This is the query we need to fire off, right? So to do that, we've got this send Shopify request. Built that ahead of time.
Yep.
JASON: I'm going to away, fetch, and then, I don't know.
KELLY: Don't redo your work!
JASON: What did I just say? And for variables, do I need variables when I'm creating a cart? Do I have to tell it to do anything?
KELLY: You don't need variables at this moment. This is creating a an instance of a cart. You're getting a checkout URL and an ID. Doing a headless build and you're going, using this cart API, the checkout URL is going to be your Shopify URL with the unique ID to go to Shopify's checkout.
JASON: Great. We can check so because of the way that we set this, we can see that it's like getting the result .JSON, returns it back, air checking if the request fails. So what we're going to do is just check like if it's missing data. Then, we will just return a plain
500 and say, something went wrong with the server and we can JSON stringify a message and that message will say there was a problem creating a cart. That's a useful ish message, it's not a great message. But we're going to live with it. If we do get this, what we want to send back instead of this to do message is we can pop down here and let's, let's send it back
KELLY: Pass the cart ID and the checkout URL.
JASON: Checkout URL.
KELLY: So, if you're the respond ticket back is several layers deep, so you're going to have to check for cart create is the first response.
JASON: Cart create.
KELLY: Check to see if that exists, question mark. And then, cart. Question mark and then ID. And you'll do the same but for checkout URL.
JASON: Same this bit. And then, we'll say check out URL. OK. And that should be the whole thing. Let me do a quick check. We're using ES build here. It lets us do a couple things with our functions. First and foremost, we get to use the ES module syntax of import/export as opposed to module.exports and means we can use things like optional chaining here, newer versions of node only. Which this is very, very nice.
KELLY: It's beautiful. . Shortens, makes life so much cleaner.
JASON: Let's run it. Go to postman, and I'm going to fire off a function call. Postman opened in the wrong monitor, let's get it over here. And we will say about all of this, don't save. All right. Let's do http local host, 8888 and did I set up a redirect on this? Yes, we want it to be in API, right? Normally, to get to a function, you/Netlify/functions and then the name of the function, but we want this to be an API./API and cart. And we're redirecting any call to API to the Netlify functions call. What we can do in here is go API create cart and we shouldn't need any parameters, we should be able to send it. And it sends back. That's great. Makes me really happy. And then, we get back the checkout URL. So this is exactly what we want. And now, we can actually use it, which we will do in this cart component. So this is like our cart.jsx, a preact component, but it's React. Otherwise it's functionally identical. Makes the app much smaller. So let's what do I need to do here? I need to just get
You need to create the cart, get the cart.
We need to get the cart, the first thing we can do is in here, when we get a cart, we want to it has to happen after the component's loaded. So we can put that in our use effect. That's going to fire when? Just when it opens?
Yeah.
So this empty array means it'll fire when the page first loads. And to do an async call, which can what we're going to do is twine another function in here. Actually, no, we're getting ahead of ourselves. Really, what we need to do is set up our local cart data. We're going to get cart. Inside here, we need to let local cart data. Because let's walk through how this is actually going to work. Right? Because of the way that astro is set up, we don't share context across the app. Each, like, the cart component is its own Mini React app and the add to cart buttons are their own mini React apps and allows us to ship so little JavaScript. But we need to actually keep some kind of context and we'll do that through local storage. So to do that, we're going to just kind of like keep that data locally. So what we need to do is, like, check for a local cart. We can do, right, if we can find an existing cart, we will do that. Right now, we don't have that. So let's, instead, just create one, right?
Yep. And to do that, we call our function. API, create cart. And whatever comes back should be JSON, right? And we checked that and it worked. And we can set our cart, which is this function up here that's currently in ID and lines. And lines are like the items in the cart.
Yes.
KELLY: Yes.
JASON: I'm going to set the cart and in it, we want to set an ID, which will be local cart data.cart ID. Right? That comes back from our create cart. And then, we want to set a checkout URL, which will be localcartdatacheckout URL. And then, there's a couple other things that we're going to need. We need to know how much the cart costs, but we don't know that right now. We created a cart and then our lines are going to stay as an empty array because this is a new cart, there are no items in that cart. And then we need to put it in local storage.
KELLY: We use it for, we recently released a client set actually that has 3 different Vlaps, quiz flow, what's in the quiz results and the cart itself. And we're using local storage to communicate through the few apps, as well, and this is built directly into a Shopify theme. I cannot take credit for it. My team's an absolute genius for figuring that out.
JASON: I love it. This is cool right here. What we are able to do here, then, is we can do window.local storage, set item and that will set a cart. Let's run this and see if it works. It's changed and if we come out here, we're local host 8888, I'm going to refresh and no functional change, but let's look at the application. And if I look at local storage in here we can see, hopefully, oh, guess what we forgot to do?
KELLY: What did we forget to do?
JASON: Call the function.
KELLY: Yeah.
JASON: We can go. Note it's gray because we never called it. So we need to actually call that thing.
KELLY: Small details.
JASON: Just the little things. Now, if I reload the page here. We should see Jamstack conf. That he did what we wanted. I am surprised it didn't include estimated cost or the limes, though. Oh, I know why. Now, we have our cart ID. Everybody memorize this quickly we're about to change it. So if I refresh the page. OK. Everybody memorize that one. You can see this change is no longer the same ID. And same if I reload, again, you can see that these are changing. It's easier to look at the end. These are no longer matching keys. Which means if I leave the page and come back, even if I just refresh, I don't have the same cart, which means I lose everything and that's all a bummer. How do we fix that?
KELLY: We need to see if the item exists in local storage and set the cart to that. And if not, create a cart.
JASON: Let's do it. I'm going to first and foremost, I just lost everything. Oh, my God, where I am? What day is it? Where are you? OK. We need to check if
KELLY: Writing local cart data right now.
JASON: Yeah, we're going to try to get this data out. We'll do window.local storage.get item. And inside of that, we want to check for the same key. So I can grab this key and put that right here then, here, if we have local data, we can say, like, if the data is set. Because it'll come back null if it's not set in local storage, then we can, we need to load that cart, which we'll have to write in a second.
KELLY: I was going to ask if we've written it yet.
JASON: We can set the cart to be let's do, ID, I think we can just copy this out, actually. Local cart, check out URL. And then, we need to get our estimated cost. But this is going to end up coming up from the loaded cart, right? So for now, we can set it to null and then, our lines are the same thing going to come from the existing cart. So let's set it back to an empty array and we'll say, like, load these from existing carts. And then, because we've done this, we can return. So this, should, if we did this right, when we reload the page, our ID shouldn't change anymore. It ends in ZMX, let's see what happens. Reloaded, still ZMX, that's great. And then, I think the only other thing to do is make sure there's a way to clear this because if you want to get rid of your cart, we want a button to make that happen.
KELLY: Yes. Once you add something to your cart, you can never get rid of it, again.
JASON: So let's do that really quickly. We'll write this empty cart here. Oops. So for that, all you have to do to empty a cart is just remove the thingy. The window.
KELLY: Remove the thingy.
JASON: Yeah, get the thingy, window.localstorage.removeitem and the item we want to remove is this one. Get out of here. Right?
KELLY: Perfect.
JASON: So that. I'm feeling good about that. That feels good. We should save that and then, to actually call it, we need to, let's see, here's a button. And it looks like this button won't actually show up until we've got something in the cart. So we'll deal with that momentarily. So next, we need to load the cart. Let's do that. Let's go to back to our functions here. How are we doing on time?
KELLY: We've got a half an hour.
JASON: We're killing. Kelly, this is amazing. How are you feeling, chat? Are you excited? How's everybody doing? I'm very, very excited about how far we've gotten in 30 minutes. I'm not going to lie. [ Laughter ]
KELLY: It's a magical thing happening right here.
JASON: So, in our load cart, we get to use this same send Shopify store front request. And again, through the power of movie magic, I am going to grab all the query. And this one, it's significantly more important to have that query going. Because this query
KELLY: We have enough time, write the entire thing.
JASON: I know. Do a quick check on what this one does. This query gets the cart and it sends the cart query and the ID we pass it is the cart ID which will pass in as a variable. That gives us back the checkout URL, the estimated cost, which is the subtotal of how much our cart is going to cost us. And then, it grabs the lines, which are the items in the cart. We limit it to the first 100. And then, edges, it's like a GraphQL term for, like, the connections
KELLY: Going deep.
JASON: And node is a actual item. This would be the line itself. So we need, the quantity, like how many somebody wants, the estimated cost of the individual item and then, the merchandise, we want details. For the merchandise, the product variant. This is for like a type subset. So merchandise can return more than product variance, but in our case, it doesn't. We get the titled, the product title. The title variant is the title which doesn't make any sense. The product title is the overarching top title. And then, the price V2, because there's always a V2, .V3. And then, the amount in the currency code so that we can pull out which each of these things is worth. So that's the query. Now, we need to send it, which we do by first getting the cart ID. We're going to have to post to this function so we can get the cart ID. And whenever you post to a function, you get, oh, wait, hold on. We don't need to post, we're going to send it in a
KELLY: Yeah.
JASON: This is easier. We send it as query stream parameters so we can do that. Once we have that cart ID, we can, again, use our send Shopify store front request. And we send in a query, and send in variables. Now, our variable is going to be the cart ID, right? And we have to match this name, the cart ID needs to match this name. That's how GraphQL does it. So then, just drop this thing right in here, right? Done and done. Now I'm going to collapse it. It's too much to look at.
KELLY: You were using get lens for the previous.
JASON: Yeah, it is get lens and it is incredible. I think it shows me stuff over here.
KELLY: I can't live without it. It's really great. Useful for get blaming, as well. I'm the one to be blamed.
JASON: You can see I made this change or this one. So the short answer is graph theory, the longer answer is when you are looking at relationships between data in a graph, you have your nodes and, like, if you're thinking about REST, you kind of have a parent and children. But when you think about graphs, they're not there's not hierarchy like that, there's connections. And so, a graph is connected like nodes are connected along edges and edges would be aligned in 2 points. If you're looking at complicated data like a website will have posts and comments and authors and authors can have both posts and comments assigned to them. Comments can only have authors. Maybe posts can only have authors with a certain type of permissions. And so along those edges, sometimes you'll get metadata. How many per page, you know, is there what else shows up in edges? You can put different, just different metadata. It's not actually like nodes. It's the
KELLY: Cur so, as well.
JASON: Yeah, cursor, where you are in the list. And a little pieces of metadata that can be about the data that's being returned but it's not, like, strictly nodes, it's more like around the nodes. And so, edges is sort of the, edges are the relationships and nodes are the items. If that makes sense. But yeah, if you want to fall down a rabbit hole, read about graph theory, it's a lot.
KELLY: That's your homework.
JASON: Yeah, that's your homework, chat, get out there and learn. When we get this data back, what comes back from the store front request, I think we can return it.
KELLY: Yep.
JASON: I don't need to send it as an object. It's already an object.
KELLY: Yep.
JASON: We send that back. Now, this should, if I go back here, if grab out my uh, what is it? My Jamstack Conf Shopify cart. Cart ID and copy this and go back to postman and let's call this load cart. You frozen on me? No, I'm editing the wrong field. And then, I can go to my query params and call it cart ID and the value would be this. Here's the cart ID, here's the parameter. I'm going to send it. And it sends back my.
KELLY: The text, the type you have there. Down in the previous below.
JASON: I'm looking
KELLY: There you go. You did it.
JASON: OK. So here we have the cart, the checkout URL, estimated costs, we can see it's zero dollars and then, the lines we have our edges. And so, since there's nothing in here, there's not a lot to see. But we can see that Shopify's giving us back what we need. And that is enough for us to go back into our cart and actually load our cart, which is the part that we need to do here. And we can do that by going to where is it? Here.
KELLY: Yeah.
JASON: So we can get the existing cart. And that's going to be an await of a fetch. And what we're going to fetch is API, load cart, like we said and then, we're going to send in a cart ID and then, we've got this local cart data and we pass in the cart ID. OK? So that should do everything that we want it to do. And then, we know it's sending back JSON so res JSON and now we have an existing cart. Which means, down here, we can clear that up. And this is no longer a to do. So we can clear that up and we will say existing cart. what was it?
KELLY: .cart. And .estimated costs.
JASON: OK. And for lines, go existing cart .cart, again.
KELLY: .lines .edges.
JASON: You would think oh, lines, yeah. But it's because of the metadata that may come along, you have to go an extra layer deeper.
KELLY: The number of times I try to loop through the array that does not exist.
JASON: Yes, absolutely. So there's our lines. And that should, I think, that's everything.
KELLY: Now, if you refresh, we should see the estimated cost of lines in there now.
JASON: Let's do it. Let's do the thing. I'm going to here we go. I don't think there's any way to see it until we add something to the cart. Maybe what we should do then is
KELLY: Click on the local storage, what we had on there.
JASON: JA we don't put that in local storage.
KELLY: In the state. Yeah. OK. Because we need to load the latest cart anyway. Yeah.
JASON: We need to add an item to the cart.
KELLY: Yes.
JASON: So we can see any of this stuff work. Go up to add to cart and again, send Shopify store front request. Let's head on up and grab this query through the power of everybody sick of me making that power of movie magic?
KELLY: It's OK, they can't tell you otherwise.
JASON: They can just stop. Please, don't leave.
KELLY: Good point. Please, stay.
JASON: I need you. So, this one, we are running a mutation, so in GraphQL, when you run a mutation that's when you change data. It gets a cart ID and variant ID, the variant is the one we looked at in this add to cart button. No, it's not. These are variant IDs. So we're going to send in cart ID and variant ID and we want to ad a cart line, so cart line add, we send in the cart ID, aligns, you get one when you click the button and we pass in the merchandise ID, which is our variant ID, and then, what we return is the same thing that we need for the cart. Lines, edges, node and we get quantity merchandise product title. I don't think we use this, I think it's more just to verify we got a response back.
KELLY: Yeah.
JASON: OK. So then, to actually use this, we head back to the add to cart button, and we're going to start by pulling out the cart ID, nope, needs to be a we're going to structure this cart ID and variant ID and those come out of the, we are going to post this one so it gets posted in JSON. We need to parse it. And event.body. So when we post, we get event.body, when we use get like a query stream it's event.get parameters. Once we have that, we want to get our data and that's going to be, again, the send Shopify store front request, that takes a query. And variables. And the variables that we want to send are the cart ID and the variant ID. And the query is going to be multiline. So we're going to use one of those. Grab this thing out. And drop it in. We're close here, we've got our data. What should happen when we run this is that data will change. When that comes back, we don't need the data, we need the cart to update, right? We can tell it to update the cart.
KELLY: Yep.
JASON: To use this, we've got to add to cart. 15 minutes left. We're going to get this done.
KELLY: We got this. We got this.
JASON: To add to the cart, we are going to, if I can find
KELLY: First, we need to get the cart ID from local storage.
JASON: Yes. We need to get the cart ID and we are going to do that in a where? We're going to do this
KELLY: Inside the add to cart function. We'll want to fetch the local cart data.
JASON: And this is going to be, actually, this is going to be copy/paste. Let's copy paste and it's going to be under load, under cart. So if we were being more responsible, we would probably abstract this out. But, you know, we're going for shipped over perfect. And then, in here, if we don't have local cart data.cart ID, if there is no ID, something else has gone wrong if we don't have a cart ID by the time you click add to cart button. As soon as we load the page, it should check if one exists and create one otherwise. We could say there was an error loading your carts, and we'll just error out.
KELLY: Yeah.
JASON: Not the perfect solution, but an OK solution. The only way to theoretically break this is if you were programmatically trying to add to cart. So then, to do that, we're going to use the fetch call and send it to API add to cart. And this one, because it's it's a post, tell it to use post. And for the body, we're going to JSON stringify and send in the cart ID, which is local storage.cart ID. And then, we need a variant ID. And that comes from here. So we're going to use this ID. Right? And now that's set. Where do we set it? Right here.
KELLY: Yeah.
JASON: Need to change one of those. Does that happen like right? Oh, it happens right after the bat. It defaults to whatever the variant ID is.
KELLY: Yeah.
JASON: And set ID for options. We need to update that when it happens.
KELLY: Yep.
JASON: All right. We're sending in our variant ID. And what we get back, we're going to do a quick check, if the result is not OK, then, we, again, just, you know, log in error because that's how much time we have.
KELLY: Yes.
JASON: There was a problem. There was a problem adding the item to the cart.
KELLY: This might be like the variant is out of stock. But we're not handling quantities or inventory right now.
JASON: There's something else that happens here. Let's try this first and we'll see what happens. I'm going to jump out over here, we have this should work and we can watch it in the network tab. So when I click this, we should see the add to cart happen. We get back a response. It sends back the variant ID. So that was a request payload. Am I doing something to filter?
KELLY: Go back to the code for a second. Scroll up. May have had a no, that looks local cart data, cart ID, that's correct.
JASON: Cart ID.
KELLY: That's the one on JSON stringify, that should be local cart data.
JASON: You are correct.
KELLY: Thank you, I read the chat.
JASON: Add to cart, response. That's better. That gives us back. Here are the lines and gives us back our edges and our node and in our node, we get the IDs, the merchandise, and the merchandise we can see the product title of the slot bracelet and all of those things. That being the case, when I go up here, what happened? That didn't work. If I refresh the page, it's, oh, no, we have a problem. How does our cart know to update? That's the that's the challenge we have here. But we can now check for empty cart words. Let's try. Nothing happened. Wait.
KELLY: If you refresh the page, though.
JASON: We have an issue, where we need our cart to be checking if it needs to update. Because this is astro, we don't have shared context and we don't really need anything fancy here, we basically need to periodically check if anything has changed. And so, a very, like, quick and dirty way to do that is to literally just set a variable that says, what? That was helpful. Thank you. We're just literally going to set an item that says, like, what the status is. So we'll Jamstack Conf Shopify status. And I'm going to set it to dirty. You're dirty. And then, what we can do is we can go back to our cart. And in the cart, we can check if it's dirty by just running a regular interval here. So we'll go down under get cart and we'll like set interval. And then, that interval will run, so the state is going to be window.localstorage.get item. And we're going to get Jamstack Conf, Shopify status, which is the dirty or the clean. And then, we're going to say if the state exists, and if the state is dirty, then we want to run get cart. And we also want to window local storage set item. And we're going to use the same key.
I like the suggest in the chat of calling this function wash.
JASON: I do like that. That's fun. And then, we're going to run this every 500 milliseconds. And I'm realizing as I'm looking at this what we also need to do is, like, return a function. We'll return a function that once this cleans, we want to clear this interval so it doesn't. We'll end up with a memory leak. Now, every half second, our cart should check whether or not there is new data. And that should mean if we run this, let's get it in here and look. Actually, I'm going to turn this off so that we can, we can look faster. I'm going to click. And there it is. We didn't have to reload. Empty, oh, that one doesn't work. Let's fix it. So what we need to do with the empty cart is we also need to set that state. I'm going to go back to the add and this one. And I'm going to grab this. And I'm going to move it over into our empty cart. Same deal, we're going to remove the cart and check the status and now, if I reload. OK. Let's add. There's my cart item, empty, goes empty and we're in business.
Yep.
KELLY: Did we wire that up?
JASON: I thought we did. What did I do wrong? Let's try it, again. Adds to cart, oh, but the lines came back as null. What got send? Sent? Cart ID, variant ID. Did my variant IDs all change?
KELLY: They shouldn't have. Did you delete the product?
JASON: Oh, God. Somebody change my product? Let's go find out. Where is my swag pack? Jamstack swag pack. Let me update the stock so that I can make these available. We'll just make it available. I'm going to set all of these. Open bulk editor, where is my quantity?
KELLY: Did you find it? You have to choose a location.
JASON: I'm going to set one so it works and apply to all. Save, and now, that we are doing that, if I come over here and I purchase here, just reload really quick.
KELLY: Show me add to cart function, again.
JASON: Add to cart function.
KELLY: You are passing quantity in there.
JASON: Yeah, the last time I happened, nothing was in stock. But I've just set the variance as having a location, which means I need to figure out.
KELLY: Is it fetching the latest? That wouldn't matter.
JASON: I'm now relatively convince that had the variant IDs got changed.
KELLY: Yeah.
JASON: I'm going to go in here to, we might just have to do the quick we've got 4 minutes. We're going to make this work. So we're going to go into the GraphQL app. And I'm going to do a quick query. I want store front. And then, I'm going to go to in here and we want nope, not that one. We want products. And then, we want edges
KELLY: You'll need to give it a number of how many. Under products.
JASON: Oh. And then, we want the variants. And I need the title. So that we can see which one it is.
KELLY: Helpful.
JASON: The edges and whoops. The oh, my god, node.
KELLY: We did it.
JASON: What?
KELLY: Query cost. Oh.
JASON: Run this one? There we go. Show me the Jamstack, do I have to query this? What's the ?
KELLY: I think there's a handle.
JASON: I need the swag pack. No? Can I do the first 50? Is that under the limit.
KELLY: Let's find out. I think cutting down the variance also helped.
JASON: Here's the swag pack, here's our first variant ID. That's not the variant ID I need.
KELLY: Other, I think there's a store front ID, as well.
JASON: Store front.
KELLY: Yeah. Admin ID, store front ID. That's the first ID is the actual unique ID for the variant.
JASON: OK. Here is the variant ID, make this smaller so I can actually get to it. All right. So I'm going to change this one out for the extra small. Please, let me select things. What are you doing?
KELLY: We'll clean it up.
JASON: What you selecting right now? Oh, my goodness, what just happened? Swag pack, store front ID. Copy/paste. Hey hey.
KELLY: Let's see if it's different. And this was for which the first variant, as in yeah.
JASON: Yeah. So here we're going to add to cart, no, it's index, and then we want to search and that matches. So this variant ID matches.
KELLY: Go back to the product, somebody mentioned it's in draft mode,.
JASON: That's absolutely what's going on, let's go back. It's always fun when things change. Let's go. Swag pack. Here's our swag pack says it's active.
KELLY: Is it available on your store front API? Yeah, it's there. It's there, active sales channels. OK. Let's just turn it off and turn it on, again, and see if that makes a difference. Fingers crossed. If all else fails, we can just chalk this up to me not know what's going on with the swag Conf itself. And we know this one has one in stock and then, it it was just some lag. But anyways, now we have the ability to, like if I add another one of these, it says 2X, and then, if I add one of these, gives us a slap bracelet. So we did it.
KELLY: We did it.
JASON: In exactly 1 hour.
KELLY: Can I make one little request? One little thing to add in? On the success function?
JASON: After adding
KELLY: Add to the cart.
JASON: Toggle the cart open, the way we would do that is potentially more than we have time for.
KELLY: Oh, OK. I thought it just lived inside there. You can say that you add toggle cart to the
JASON: I guess, if it was, actually, I guess, I could, set open to true.
KELLY: Was toggle cart not
JASON: So toggle cart's here.
KELLY: There we go.
JASON: Otherwise, what would happen is if I added. So thank you so much for all of your help in guidance in making sure I didn't get completely off the rails as we did an absolute speed run. We're back in 14 minutes. We're going to get Kelly back to her day doing a dual founder.
KELLY: I have so some food here to eat.
JASON: You go eat your food. Next up, we're bringing on Rob Sutter from Fauna and we're going to set up some Shopify coupon codes. Be back here in 13 minutes. And we're going to get up and running with Rob. Kelly, thank you so much. We will see you all in exactly 13 minutes.
KELLY: Thank you so much. Enjoy the rest of your day.
Learn With Jason is made possible by our sponsors: