Transcript for:
Shopify Cart Transform Function Overview

hello in this video we are going to see the card transform Shopify function there is a function that let us modify the customer's card as they add or remove products to it directly on shopify's back end so the changes we do there will propagate across the whole buyer Journey from the stores front to the checkout and thank you page with this function we are able to do things like Dynamic bundles updating some parts of the product's information after the user has added it to the card so with that being said let's get started now from BS I'm going to run mpm init Shopify app latest to start a new app I'm going to name this card transform app and I'm going to start by adding my first extension here this will install theary dependencies I'll come back in a moment with the app created let's generate the extension now so I'm going to take all of this out of here going to delete this folder I'm going to run mpm run Shopify app J generate extension from here we are going to select the type of extension that we are generating I'm going to create this as a new app keep this name and here we are going to pick card Transformer function I'm going to name this card Transformer just like it just like this I'm going to keep the default and I'm going to use typescript for this we are going to install the dependencies so I'll be right back and with this we have now in this extensions folder the default code for the extension in this round. DS file which at the moment is doing no changes before running this we are going to come here to Shopify app. TL and in the Scopes we are going to add right card transforms as that's the scope that is needed to to run the card transform function if you need to add any other scope this is the place to do so I'm going to leave in the description the link of all possible Scopes because depending on what you're trying to do you may need to add more values over here and before going any further let's make sure we have the graphql extension installed because in Shopify functions we get the input that way and Shopify has recently started generating thisg graphql rcjs file which if you recall from previous videos in the channel was not there before and this basically gives us a to complete in this run. graphql file which is the file controlling the input of the function if we have the appropriate extension installed so here I'm going to look for graphql and the one we want to install is this one from the graphql foundation which at the moment is not the first one showing but this is the one we want it will also install this graphql syntax highlighting extension and once installed if we click on this file this is syntax highlighted and also we get the autocomplete for the possible values or attributes that we can query for in this particular place like for example cost here it tells me that I must query an attribute of this and note that here we get the type and also a short description of what this value means so let's get a mount and see how now I know that this query is valid you can still check this file for all the possible types and their descriptions which is where the data for the aut compete is coming from but well now it is more convenient if you have the graphical extension installed and now let's begin with the operations as you can see here a card Transformer function returns a list of card operations there are three operations right now first we have the expand operation which specifies the components of an item and can apply some price adjustments to it so this one basically takes a single product in the card and expands it into a bundle then we have the merge operation with it we are going to take multiple products in the card and merge them together into a bundle one of the possible uses for this is dynamic bundling so basically letting the customer mix and match products together and then bundle their selection finally we have the update operation over here which let us update the title price or image of an item in the customer's card this can be used when the customer customizes some products to show the customized item directly in the card so let's begin with an example for the merge operation so here I have a development store that was created with test data and what you're going to do is divide the catalog in into two groups then let the customer pick any product from group one and then bundle it together with any product from group two and offer a 10% discount on that bundle in this I'll create the segmentation between the products artificially by tagging some with group one and then some others with group two as most products in this store are snowboards but if this was for example a clothing store you could do things like letting the customer pick any t-shirt and then any pair of pants and bundling that together so what I'm going to do now is select the snowboards from this one up to this one and click on bulk edit then I'm going to in the TX tab over here if you don't have it you can enable it the columns over here I'm going to select them all and at the top I'm going to add group one click on save to add it to every product in this selection and then I'll do the same for the remaining ones but the tag will be group two so I'll selection of this and here I'll add group two and click and save next we are going to create a product that will serve as a container for this bundle because in Shopify a bundle is internally registered as a product so when we are merging the items in the card transform function we will need to specify a parent buan ID and that ID is something we'll get from this product we are about to create so here I'm going to click on add product and I'm just going to name this bundle container I'm going to keep its inventory as zero so the so the customer cannot add it to the card onless we are adding it as a bundle through the function and to get the variant ID because it only has the default variant so it doesn't show over here I'm going to add the Json to this URL and I'm going to copy this large ason over here I'm going to paste this this code and I'm going to format it and the default variant is this one and I'm going to grab this ID and paste it over here in Fr the TS because we are going to use this later in the video now I'm going to add the front end code that will let the customer select the products they want to bundle together and then let the Shopify function know which products to put together because as you'll see later the function always receives the whole customer's card as its input so the products that should be bundled together need to be marked somehow the way we'll approach this is by using line item properties basically We'll add a bundle ID property to the items that should be bundled together and from the Shopify function if two line items share the same bundle ID then we can assume they should be bundled together note that in this case the front end is a liquid theme so if you're using something different for your front end like for example hydrogen the Shopify framework then this step won't be exactly the same for you but the general idea should be the same so here I'm going to click on edit code and we are going to add a section to handle this now I'm going to add a section bundle Builder liquid and from here I'm going to change the name to be bundle Builder the presets I'm going to add one with the name bundle Builder this is so later I can add this section to this store from the from the theme editor so now I'm going to create a form the ID will be bonel form and here I'm going to open a div over here I'm going to look through every product in the store so for product in collections. all. products I'm going to close this for Loop and over here I'm going to check if product. tax contains group one and if no for that me add a label here group one and this will be for group one and I also have to add a select I will be group one and the name will be group one two I'm going to close the the select over here and now inside this if I'm going to create a variable ass sign variant would be product dot selected or first available variant so I'm always going to select the first variant if you were building this for a production store you probably want something more robust in this but I think that for this example this will do so here I'm going to display the product title and then the variant price I'm going to format this with money and then the value over here will be variant. ID I'm going to save this and now I'm going to copy all of this and paste it below and just change all of these ones for a two and now I'm going to add a submit button the next thing we're going to do is add a script tag over here and then we're going to get the form with document. get element by ID BND form then I'm going to add anend listener for submit this will be a synchronous because we are going to call the Shopify API to submit the form the selected products to the API so group one will be document. getet element by ID group one and I'm going to assume that it will always have a value for group two I'll do the same and now now the bundle ID I'm going to quickly generate it by using the date and just getting the time then I'm going to do a fetch to card .js the method is post the headers we just need to add content type and set it to application Json and then the body will be json. stringify I have to hear some the items it is an array DD will be the one that I got from group one the quantity will be one and then in properties this is what I'm going to use in the Shopify function to note that these two products should be bundled together I'm going to put bundle ID and I'm going to do the same for group two just making sure that I Chang this variable to be group two now I'm going to save and I'm going to go to the store Editor to get here I just click on customize over here then I'm going to add a section bundle Builder I'm going to move this to the top but you can already see that the products are listed correctly here and now if I go to the store and refresh this I get my products now this will make the form and if I go to the card page the card is empty let's see why that may be and we have two issues here the first one is that I need to add a prevent default so the page doesn't refresh automatically as I submit the form also I have a typo here this I should be an uppercase and also note that we are this let's add windows. location. reload so after I make this request to add to card the page is refreshed so I'll save this and if I refresh the page here and click on submit now the two items are in the card with your bundal ID and now that we see that the bundal ID is working let's hide this because this is an implementation detail and the customer doesn't need to see that so what I'm going to do is add um underscore to the bundle ID preface it with an underscore and then this will be equal to bundle ID and I'm going to do the same here I'm going to save and I'm going to remove these two items from the card and now if I add again and go to my card I don't see the Bund ID but it is being stored just as a hidden attribute we will read it later from the Shopify function and after this length is set up I'll clean the card and I'll go to the code over here let's update the query this codes over here we don't need that we are going to query for attribute we are going to get the key and the value and here we're going to specify the key the key we want is bundle ID some matter fact we don't need the key here because we know that this will always be bundle ID and we can alious this to bundle ID now I'm going to open another console here and I'm going to go into extensions hard Transformer and I'm going to run npn run type gen todate the typings in front of TS to match what I have here in front of the gra now the next thing that I'm going to do is delete this because I don't need this Con no changes for now let's return an an array and now let's create a constant group items this will be the items that will that are grouped by their vnd ID the type of this will be a record of a string and pick of a card line and from the car line I need the ID and the quantity this will be an array and this will start an empty object now I'm going to do input. card lines for each and for each line item I'm going to get the bondle ID so this will be line. bondle ID and if it exists because this is a property it is optional and if it has a value then I'm going to enter here and if group items bundle id. value so if there is if this bundle ID has not been registered over here I'm going to register it ridon one d. value will be equal to anay at first and then I'm always going to push to this this line item now over here I'm going to return operations and operations is an array and from here I'm going to have object values group Items Map group and I'm going to have here merch operation this will be equal to a car operation and here I'm going to use a merch cut lines will be equals to group map and I'm going to get here the line and I'm going to return part line ID will be line. ID and quantity will be line. quantity and I also have to specify a parent Varian ID and that is what we got earlier in the video so I'm just going to copy this and paste it over here then I'm going to return merge operation in the line below we have no errors over here so I'm going to save this and let's see if this is working by running mpm from death this will take a moment the first time we run it but it will ask us in which store I want to install this card for store is the one that I'm using then over here let's see what we got we got a pro link so I'm going to click press p and this will ask me to install the function in this store which shall do now this is not enough to enable it now I have to go into graphic and frun a query to actually enable this function in the store so I'm going to press D because now graphic comes built in toop and let's build the query okay so the first thing we need to do is get the function ID for this I'm going to delete everything here and I'm going to get Shopify function the first I'm going to get the first 10 but you can get the first any if you don't get the one that you created right away and here I'm going to get the ID and the title to know which function I have over here I just have a single function so the ID is this one I'm going to copy all of this and I'm going to put it over here as a comment because I need it and now I'm going to run amutation which is card transform create the function ID is this over here so let me copy and paste it over here and then I can get the the the ID of the card transformed and user errors in case we have an error I'm doing this so I'm going to run this as is denied so it seems like the right car transformer scope we can have over here hasn't been updated so what I'll do if you get this error even if you have it over here what you have to do is run mpm CR deploy by deploying this Shopify will update the Scopes so let's see over here you can see that it will release a new version of this app so it is building it and the access Scopes got updated as you can see so now if I run npm and that and now over here if I press P again I will be prompted to update the data access over here so you now can access car transforms and the app has been installed and now I can go to graphic Q Again by pressing G the imitation got saved so if I run this again now I don't have an error and I get the ID of my cont phone so it should be working in the store let's go over here and let's click on submit here and I get a single item this time and it is bundle container with my two items combined so this seems to be working and how do I know that my two items are combined well I can see here the price but also if I go to check check out I see here bundle container and my two items are bondle together so the function is definitely working now we can add a couple more things here first you can add a discount so you can see that this is the price right now but let's say that we want to add a 10% discount to do so I'm going to add here price percentage decrease and I'm going to decrease this by 10% if I save this I refresh a page okay seems like I have to add it again so let's delete it from the card let's add it again and you can see here that the price is 10% lower than it was before if I go to check out I get the preduce price we can also change the title that's why I said earlier in the video that the title we gave to the product was not that important because we can change it dynamically from here from the function so let's say my custom IED bundle I'm going to save this I'm going to remove this from the card and I'm going to submit again and if I go to check out I see my customized bundle but over here it doesn't show like that and the reason for this is because this custom title that we gave it is in a different property in liquid so we have to change some liquid to get that let's see how typically do that so here from the editor I'm going to look for main card items over here and I'm going to look here for item. product. tile this is what is rendering this title over here however the custom bundle title is inside of item. title so if I save this and refresh this page you're going to see my customized bundle over here now we don't always want to use this item. title so we are going to render this based of an if statement so let me put this in a new line and I'm going to check if item Dot and for this I'm going to use the item components property so basically bundle items will list its components under item components so if item. item components do size is greater than zero then we are going to use item. title else we are going to use what we were using before I'm going to save this and now if I refresh this I see my customized bundle but if I add a regular product to the card such as this one I see here this regular title and I can got the check out and everything works fine now that we saw the item components property we can replicate something like this if we wanted to because we have access to every item in the bundle so if we wanted to indicate which items are inside a bundle we can do so from the card page over here so let's quickly do some something like that so let's say four four component in item do item components and I'm going to put this inside a a list item components the title and let's wrap this inside and order this and I'm going to render this list only if this is if this is true if the item component size is greater than zero let me save this and let me format I'm sure that but actually worked but anyways let's refresh the page over here and I see here the two items that are inside this bu I could also show the image or anything else that I want as this is just a regular line item object so any property accessible from line item will be accessible from the item component we can also add a custom image so for this I'm going to say image URL and here I'm going to paste a URL for an image which I'll get from Shopify I'm going to use this one for example and I'll paste it over here and if I save this and go to the store if I refresh this I see no changes but if I go to check out my new image is there and at the moment I think this is a bug because I can't see the image over here when I'm in the store but if I go to check out it shows up over there I checked the line item properties and I don't see a new property that has the image as of now so over here in the card what you will get is the parent product image which in this case is empty but we can populate it with something else from the admin let's do that so from the admin here I'm just going to grab this URL copy it and go to the bundle container and add from URL here and paste that URL and now after this finishes processing I'm going to save this okay seems like I need to save it and if I refresh this I can see this image in checkout I still see my Custom Image but let's remove it here because then we will have an inconsistent image experience over here with check out having this image and the card having a different one so if I refresh this I get the image for the parent product now I don't think this a deal breaker which is why I decided to make the video despite it as in most situations when you letting the customer mix and match products together you don't have a pre-rendered image of every single combination so usually the bundle image is a more generic one and then when the bundle is expanded the customer can see what items are actually included and by expanded I mean for example here being the checkout page I can expand the bundle to see the items with our image and I showed you earlier in the video how you could create a similar experience in the car page fortive nonetheless if in the future this gets fixed or I discover a way of showing the customiz image in the card I'll update the description or at a pin comment in the video with that update and also if you know a way around it please share it out in the comments to help future Watchers of this video and the last thing I'll show you about the merch operation is an actual limitation of the image property and it is that if you try to use an image that is not in a Shopify CDN URL such as this one from Wikipedia I just copyed the URL for this generic JavaScript code and if I try using this as the image of the bundle I will get an error so if I refresh this let's give it a second there we go so the bundle is no longer showing and if we go to the console we will see an error and let me take this as an opportunity to show you how to see errors so from Shopify Partners you can click on all apps find the app that has your function in this case is this one and then in extensions I click on carard Transformer and here I see this invalid output eror if I click on this I'm going to see that the base image URL must be either CDN shopify.com or CDN Shopify cdnet so basically you need to host your images in Shopify for them to be able to be used with this Shopify function so let's quickly undo this and now if I go back here and refresh this page my bundle is showing and if I refresh here I can see that these executions have a success status and also note how over here they input has these three line items but if I go to the store the card shows as if it only has two and that is because the card that we get here is actually the card after it has been processed over here so each time we update the card it will be processed over here in the Shopify function and then we will get the value here so let's add another bundle here you can see it is working they both have different prices and if I go to check out each time I go to check out and I refresh the page also another execution of my Shopify function happens so let me go back here the last execution is this one but if I refresh this page note how the last execution now is this one which happened a couple of seconds after if you wanted to use console. logs this is also the place where you will see that output so here I'm going to do console.log testing conso Lock And if I save this and I got the check out and refresh this page and then refresh the partners Dash over here this last execution she'll have a consulted log here at the bottom testing consulted log you now let's see the next operation which is the expand operation what this one let us do is take a single line item and expand it into a bundle one of the uses for this one could be if you wanted to give the customer an item when they purchase another for example in the snowboard store I can give the customer a free sqa when they are purchasing a snowboard so you can see here in the catalog for this store that I have these skags over here and I can give one of these to the customer for free when they are purchasing any snowboard so I'm going to start by grabbing the barant I here I'm going to take this one and I'm just going to copy this one over here and copy this part now I need to update the WR query over here because I need more information so merchandise on product variant I need to get the variant ID also for later let's get the product and the title so I'm going to save this and I'm going to run mpm R type J to get the updated updated typings over here I'm going to remove this console plock and now what I'm going to do is that I'm going to filter the items that don't have a bundle ID attached to them because even though a c transform function can return multiple operations multiple operations targeting the same line item usually are not recommended you'll see why in a moment so that point of not recommending multiple operations targeting the same line item is because of this over here you can see how Shopify will behave if multiple operations are targeting the same line item depending on what those operations are so if you have multiple expand operations the first B operation is executed and all the others are discarded the same happens in the case of merch the first one is executed and all the others are discarded and if an expand and a merge operation are targeting the same cardline item the expand operation is executed and the merge operation is discarded So to avoid collisions here what we are going to do is we are going to filter the line items that don't have a bundle ID because for those ones we are not executing the merge operation so here I'll do it conses items with no bondol ID will be equal to input. card. lines and I'm going to filter this so line Bond id. value is equal to false so I'm converting this to aoan and then if this is falsy then I can assume that it doesn't have a bundle ID now over here what I'm going to do next is map this so items with not with no B ID that map item and I'm going to have here expand operation this will be a card operation and here I'll say expand card line ID will be item. ID expanded card items here we have to specify which to which items we are responding this so item merchandise I'm going to C this as a product variant and get the ID and the quantity we should actually query here also for the quantity so let's get that oh we are generate better so item quantity and we should do the same here merchandise ID this is where we are going to copy this ID got in a moment got a moment ago and the quantity will be item the quantity and then I'm going to return the expand operation so what I'm doing here is this line this line item I'm going to expand it into the product it already has and I'm also going to add this skads this is the variant ID for the keyx and I'm going to replicate the same quantity so if I have a single item I'm going to be adding just a single sqx if I have two I'm going to be adding two so by Saving this and by refreshing here in the store you can see that I already have a snowboard that is not bundled with anything else so this one doesn't have a bundle ID if I refresh we have an error no we don't have an error that took a moment to be updated in shopy 5 back but now you can see that we got it expanded and I have this selling plan skx and if you notice the price didn't change because I'm not adjusting the price yet so the customer is getting this for free we can also here update a couple of properties with the same limitations we saw a moment ago for Merch so we have title price and image let's update the title so so I'm going to say item but merchandise going to cast this to product variant and I'm going to get the product and the title and I'm going to say plus three key wi and if I save this this will take a moment to refresh and here we have it plus fre SQL I can also go to the stores card this will be refresh here but if I remove this item and add it again I can see here that I get plus fre SQ we can also update the price if we wanted to so let's say that we didn't want to give the customer this item for free but just at a discount so I'm going to go here to run the graph ql and I'm going to get let's see price was was it here cost total amount amount believe it was over here the price now I'm going to run mpm run typ G and while this is generating I'm going to add here price adjustment fixed price per unit amount and the amount here will be item merchandise see item that cost the total amount that amount so we are going to be keeping this price the same way it is but for this one adjustment face price per unit and the reason I had to specify it over here even though I'm keeping it the same is is because if I specify it in in one item in this array I have to specify it for every other item in this array so here the price let's say that it will be $10 if I save this you can see that the price is this right now but if I go to check out it has increased by $10 and just to mention to keep this video shorter I'm hard coding this ID and this price over here but if you are doing this in a real app you should be using an app meta field to get this data you can query app metafield from over here car transform meta field and over here you can get meta fields for this function and that way you can get data dynamically instead of having it hardcoded as I'm doing right now and lastly let's see the update operation this is a very simple one that let us update the title price and image of a line item an example could be when a store offers custom Engravings in some products once the customer has typed what they want to engrave we can update the car item to show that in the title and this one has this limitation over here which if you're Distributing this through the Shopify App Store you should be aware of and handle appropriately if a customer tries to use the update operation in a store that is not on Shopify Plus or a development store they will get an invalid operation error so make sure you handle those cases to demo this I'm just going to command all of this out and I'm going to change the title of the first part line item I'm commenting all of this so there are no collisions as we saw a moment ago Shopify doesn't like when two different operations Target the same line item so the here I'm going to do a date the card line ID will be input card lines z. ID and the title let's say it is input card lines zero merchandise I'm going to cast this to product variant I'm going to get product the title and I'm going to just have here updated I'm going to save this and if I go to the checkout here and refresh this all these bundles will be down but the first item over here should have updated as you can see here and if you wanted to do something more realistic like the Engravings example I mentioned a moment ago you will just need to pass the engraving string as a property like we did with the bundle ID earlier in the video then query it from the function and append it to the title and to close the video let me show you how orders processed by card transform functions look like in the order stab so I'm going to click pen out over here we can see that updated is still showing and now if I go to Shopify admin so if I look here for updated you can see that that string is no nowhere to be found and basically that change we did with the DAT operation was just cosmetic for the custom NTC but internally the product still has the name it was registered with now I uncommented the merge operation we have the custom bundle over here I'm going to click on pay now and going to go to the admin here and in this order we can see both products separately but the parent product is not here so this bundle container does not show in the order instead we get the two products that are part of the bundle and lastly I have the expand operation with the free sqa so from the code here I remov the part where I was making making the price of the ski wax to be 10 instead it is now just free so I'm going to order this and in the order step let's check what we get here I get the two items but this one appears to be at a discount so the total in the end ends up being the original price of this one so this one doesn't appears at CEO instead this item gets discounted the price of this item if that makes sense so the price here you can see is this one but the original price of this item is greater than that if the combined price that it has over here plus this one over here I hope that makes sense and that does it for this video if you find it useful remember to like And subscribe for more Shopify related content and I'll see you all in the next one