# Cart Instructions Instructions used to create the checkout. ```jsx import { Banner, Button, useApplyDiscountCodeChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyDiscountCodeChange = useApplyDiscountCodeChange(); const instructions = useInstructions(); if ( instructions.discounts.canUpdateDiscountCodes ) { return ( ); } else { return ( Loyalty discounts are unavailable ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.discounts .canUpdateDiscountCodes ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyDiscountCodeChange({ type: 'addDiscountCode', code: 'FREE_SHIPPING', }), }, 'Apply your loyalty discount', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Loyalty discounts are unavailable', ), ); } }, ); ``` ## StandardApi The base API object provided to `purchase` extension targets. ### Docs_Standard_CartInstructionsApi ### instructions value: `StatefulRemoteSubscribable` The cart instructions used to create the checkout and possibly limit extension capabilities. These instructions should be checked prior to performing any actions that may be affected by them. For example, if you intend to add a discount code via the `applyDiscountCodeChange` method, check `discounts.canUpdateDiscountCodes` to ensure it's supported in this checkout. > Caution: As of version `2024-07`, UI extension code must check for instructions before calling select APIs in case those APIs are not available. See the [update guide](https://shopify.dev/docs/api/checkout-ui-extensions/instructions-update) for more information. ### CartInstructions ### attributes value: `AttributesCartInstructions` Cart instructions related to cart attributes. ### delivery value: `DeliveryCartInstructions` Cart instructions related to delivery. ### discounts value: `DiscountsCartInstructions` Cart instructions related to discounts. ### lines value: `CartLinesCartInstructions` Cart instructions related to cart lines. ### metafields value: `MetafieldsCartInstructions` Cart instructions related to metafields. ### notes value: `NotesCartInstructions` Cart instructions related to notes. ### AttributesCartInstructions ### canUpdateAttributes value: `boolean` Indicates whether or not cart attributes can be updated. ### DeliveryCartInstructions ### canSelectCustomAddress value: `boolean` Indicates whether a buyer can select a custom address. When true, this implies extensions can update the delivery address. ### DiscountsCartInstructions ### canUpdateDiscountCodes value: `boolean` Indicates whether or not discount codes can be updated. ### CartLinesCartInstructions ### canAddCartLine value: `boolean` Indicates whether or not new cart lines can be added. ### canRemoveCartLine value: `boolean` Indicates whether or not cart lines can be removed. ### canUpdateCartLine value: `boolean` Indicates whether or not cart lines can be updated. ### MetafieldsCartInstructions ### canDeleteCartMetafield value: `boolean` Indicates whether or not cart metafields can be deleted. ### canSetCartMetafields value: `boolean` Indicates whether or not cart metafields can be added or updated. ### NotesCartInstructions ### canUpdateNote value: `boolean` Indicates whether or not notes can be updated. ## Related - [Targets](https://shopify.dev/docs/api/checkout-ui-extensions/targets) - [Components](https://shopify.dev/docs/api/checkout-ui-extensions/components) - [Configuration](https://shopify.dev/docs/api/checkout-ui-extensions/configuration) - [Tutorials](/apps/checkout) ## Examples Instructions used to create the checkout. Check `instructions.attributes.canUpdateAttributes` before calling `applyAttributeChange()`. ```jsx import { Banner, Button, useApplyAttributeChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyAttributeChange = useApplyAttributeChange(); const instructions = useInstructions(); if ( instructions.attributes.canUpdateAttributes ) { return ( ); } else { return ( Loyalty points are unavailable ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.attributes .canUpdateAttributes ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyAttributeChange({ type: 'updateAttribute', key: 'loyaltyPoints', value: '100', }), }, 'Apply 100 loyalty points', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Loyalty points are unavailable', ), ); } }, ); ``` Check `instructions.delivery.canSelectCustomAddress` before calling `applyShippingAddressChange()`. When `true`, this instruction implies that extensions can change the shipping address. ```jsx import { Banner, Button, useApplyShippingAddressChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyShippingAddressChange = useApplyShippingAddressChange(); const instructions = useInstructions(); if ( instructions.delivery.canSelectCustomAddress ) { return ( ); } else { return ( Shipping address cannot be modified ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.delivery .canSelectCustomAddress ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyShippingAddressChange({ type: 'updateShippingAddress', address: { zip: '90201', }, }), }, 'Change your postal code', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Shipping address cannot be modified', ), ); } }, ); ``` Check `instructions.discounts.canUpdateDiscountCodes` before calling `applyDiscountCodeChange()`. ```jsx import { Banner, Button, useApplyDiscountCodeChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyDiscountCodeChange = useApplyDiscountCodeChange(); const instructions = useInstructions(); if ( instructions.discounts.canUpdateDiscountCodes ) { return ( ); } else { return ( Loyalty discounts are unavailable ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.discounts .canUpdateDiscountCodes ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyDiscountCodeChange({ type: 'addDiscountCode', code: 'FREE_SHIPPING', }), }, 'Apply your loyalty discount', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Loyalty discounts are unavailable', ), ); } }, ); ``` Check `instructions.lines.canAddCartLine` or `instructions.lines.canRemoveCartLine` or `instructions.lines.canUpdateCartLine` before calling `applyCartLinesChange()`. ```jsx import { Banner, Button, useApplyCartLinesChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyCartLinesChange = useApplyCartLinesChange(); const instructions = useInstructions(); if (instructions.lines.canAddCartLine) { return ( ); } else { return ( The products in your cart cannot be modified ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.lines .canAddCartLine ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyCartLinesChange({ type: 'addCartLine', merchandiseId: 'gid://shopify/product/1234', quantity: 1, }), }, 'Add a free gift to your order', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'The products in your cart cannot be modified', ), ); } }, ); ``` Check `instructions.metafields.canSetCartMetafields` or `instructions.metafields.canDeleteCartMetafields` before calling `applyMetafieldChange()` if you are working with cart metafields. ```jsx import { Banner, Button, useApplyMetafieldChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyMetafieldChange = useApplyMetafieldChange(); const instructions = useInstructions(); if ( instructions.metafields.canSetCartMetafields ) { return ( ); } else { return ( Loyalty points are unavailable ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.metafields .canSetCartMetafields ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyMetafieldChange({ type: 'updateCartMetafield', metafield: { namespace: 'loyalty', key: 'loyaltyPoints', value: '100', type: 'string', }, }), }, 'Apply 100 loyalty points', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Loyalty points are unavailable', ), ); } }, ); ``` Check `instructions.notes.canUpdateNote` before calling `applyNoteChange()`. ```jsx import { Banner, Button, useApplyNoteChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyNoteChange = useApplyNoteChange(); const instructions = useInstructions(); if (instructions.notes.canUpdateNote) { return ( ); } else { return ( Free gifts cannot be added to this order ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.notes.canUpdateNote ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyNoteChange({ type: 'updateNote', note: 'Please include a free gift.', }), }, 'Include a free gift with your order', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Free gifts cannot be added to this order', ), ); } }, ); ``` ## useInstructions Returns the cart instructions used to create the checkout and possibly limit extension capabilities. ### UseInstructionsGeneratedType Returns the cart instructions used to create the checkout and possibly limit extension capabilities. #### Returns: CartInstructions export function useInstructions< Target extends RenderExtensionTarget = RenderExtensionTarget, >(): CartInstructions { return useSubscription(useApi().instructions); } ### CartInstructions ### attributes value: `AttributesCartInstructions` Cart instructions related to cart attributes. ### delivery value: `DeliveryCartInstructions` Cart instructions related to delivery. ### discounts value: `DiscountsCartInstructions` Cart instructions related to discounts. ### lines value: `CartLinesCartInstructions` Cart instructions related to cart lines. ### metafields value: `MetafieldsCartInstructions` Cart instructions related to metafields. ### notes value: `NotesCartInstructions` Cart instructions related to notes. ### AttributesCartInstructions ### canUpdateAttributes value: `boolean` Indicates whether or not cart attributes can be updated. ### DeliveryCartInstructions ### canSelectCustomAddress value: `boolean` Indicates whether a buyer can select a custom address. When true, this implies extensions can update the delivery address. ### DiscountsCartInstructions ### canUpdateDiscountCodes value: `boolean` Indicates whether or not discount codes can be updated. ### CartLinesCartInstructions ### canAddCartLine value: `boolean` Indicates whether or not new cart lines can be added. ### canRemoveCartLine value: `boolean` Indicates whether or not cart lines can be removed. ### canUpdateCartLine value: `boolean` Indicates whether or not cart lines can be updated. ### MetafieldsCartInstructions ### canDeleteCartMetafield value: `boolean` Indicates whether or not cart metafields can be deleted. ### canSetCartMetafields value: `boolean` Indicates whether or not cart metafields can be added or updated. ### NotesCartInstructions ### canUpdateNote value: `boolean` Indicates whether or not notes can be updated. ## Related - [Targets](https://shopify.dev/docs/api/checkout-ui-extensions/targets) - [Components](https://shopify.dev/docs/api/checkout-ui-extensions/components) - [Configuration](https://shopify.dev/docs/api/checkout-ui-extensions/configuration) - [Tutorials](/apps/checkout) ## Examples Instructions used to create the checkout. Check `instructions.attributes.canUpdateAttributes` before calling `applyAttributeChange()`. ```jsx import { Banner, Button, useApplyAttributeChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyAttributeChange = useApplyAttributeChange(); const instructions = useInstructions(); if ( instructions.attributes.canUpdateAttributes ) { return ( ); } else { return ( Loyalty points are unavailable ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.attributes .canUpdateAttributes ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyAttributeChange({ type: 'updateAttribute', key: 'loyaltyPoints', value: '100', }), }, 'Apply 100 loyalty points', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Loyalty points are unavailable', ), ); } }, ); ``` Check `instructions.delivery.canSelectCustomAddress` before calling `applyShippingAddressChange()`. When `true`, this instruction implies that extensions can change the shipping address. ```jsx import { Banner, Button, useApplyShippingAddressChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyShippingAddressChange = useApplyShippingAddressChange(); const instructions = useInstructions(); if ( instructions.delivery.canSelectCustomAddress ) { return ( ); } else { return ( Shipping address cannot be modified ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.delivery .canSelectCustomAddress ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyShippingAddressChange({ type: 'updateShippingAddress', address: { zip: '90201', }, }), }, 'Change your postal code', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Shipping address cannot be modified', ), ); } }, ); ``` Check `instructions.discounts.canUpdateDiscountCodes` before calling `applyDiscountCodeChange()`. ```jsx import { Banner, Button, useApplyDiscountCodeChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyDiscountCodeChange = useApplyDiscountCodeChange(); const instructions = useInstructions(); if ( instructions.discounts.canUpdateDiscountCodes ) { return ( ); } else { return ( Loyalty discounts are unavailable ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.discounts .canUpdateDiscountCodes ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyDiscountCodeChange({ type: 'addDiscountCode', code: 'FREE_SHIPPING', }), }, 'Apply your loyalty discount', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Loyalty discounts are unavailable', ), ); } }, ); ``` Check `instructions.lines.canAddCartLine` or `instructions.lines.canRemoveCartLine` or `instructions.lines.canUpdateCartLine` before calling `applyCartLinesChange()`. ```jsx import { Banner, Button, useApplyCartLinesChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyCartLinesChange = useApplyCartLinesChange(); const instructions = useInstructions(); if (instructions.lines.canAddCartLine) { return ( ); } else { return ( The products in your cart cannot be modified ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.lines .canAddCartLine ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyCartLinesChange({ type: 'addCartLine', merchandiseId: 'gid://shopify/product/1234', quantity: 1, }), }, 'Add a free gift to your order', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'The products in your cart cannot be modified', ), ); } }, ); ``` Check `instructions.metafields.canSetCartMetafields` or `instructions.metafields.canDeleteCartMetafields` before calling `applyMetafieldChange()` if you are working with cart metafields. ```jsx import { Banner, Button, useApplyMetafieldChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyMetafieldChange = useApplyMetafieldChange(); const instructions = useInstructions(); if ( instructions.metafields.canSetCartMetafields ) { return ( ); } else { return ( Loyalty points are unavailable ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.metafields .canSetCartMetafields ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyMetafieldChange({ type: 'updateCartMetafield', metafield: { namespace: 'loyalty', key: 'loyaltyPoints', value: '100', type: 'string', }, }), }, 'Apply 100 loyalty points', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Loyalty points are unavailable', ), ); } }, ); ``` Check `instructions.notes.canUpdateNote` before calling `applyNoteChange()`. ```jsx import { Banner, Button, useApplyNoteChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => , ); function Extension() { const applyNoteChange = useApplyNoteChange(); const instructions = useInstructions(); if (instructions.notes.canUpdateNote) { return ( ); } else { return ( Free gifts cannot be added to this order ); } } ``` ```js import { extension, Banner, Button, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root, api) => { if ( api.instructions.current.notes.canUpdateNote ) { root.appendChild( root.createComponent( Button, { onPress: () => api.applyNoteChange({ type: 'updateNote', note: 'Please include a free gift.', }), }, 'Include a free gift with your order', ), ); } else { root.appendChild( root.createComponent( Banner, {}, 'Free gifts cannot be added to this order', ), ); } }, ); ```