Cart InstructionsAPI
Instructions used to create the checkout.
Anchor to standardapiStandardApi
The base API object provided to purchase
extension targets.
- Anchor to instructionsinstructionsStatefulRemoteSubscribable<>required
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
method, check
to ensure it's supported in this checkout.
CautionAs 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 for more information.
Docs_Standard_CartInstructionsApi
- instructions
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](/docs/api/checkout-ui-extensions/apis/cart-instructions#examples) for more information.
StatefulRemoteSubscribable<CartInstructions>
export interface Docs_Standard_CartInstructionsApi
extends Pick<StandardApi, 'instructions'> {}
CartInstructions
- attributes
Cart instructions related to cart attributes.
AttributesCartInstructions
- delivery
Cart instructions related to delivery.
DeliveryCartInstructions
- discounts
Cart instructions related to discounts.
DiscountsCartInstructions
- lines
Cart instructions related to cart lines.
CartLinesCartInstructions
- metafields
Cart instructions related to metafields.
MetafieldsCartInstructions
- notes
Cart instructions related to notes.
NotesCartInstructions
export interface CartInstructions {
/**
* Cart instructions related to cart attributes.
*/
attributes: AttributesCartInstructions;
/**
* Cart instructions related to delivery.
*/
delivery: DeliveryCartInstructions;
/**
* Cart instructions related to discounts.
*/
discounts: DiscountsCartInstructions;
/**
* Cart instructions related to cart lines.
*/
lines: CartLinesCartInstructions;
/**
* Cart instructions related to metafields.
*/
metafields: MetafieldsCartInstructions;
/**
* Cart instructions related to notes.
*/
notes: NotesCartInstructions;
}
AttributesCartInstructions
- canUpdateAttributes
Indicates whether or not cart attributes can be updated.
boolean
export interface AttributesCartInstructions {
/**
* Indicates whether or not cart attributes can be updated.
*/
canUpdateAttributes: boolean;
}
DeliveryCartInstructions
- canSelectCustomAddress
Indicates whether a buyer can select a custom address. When true, this implies extensions can update the delivery address.
boolean
export interface DeliveryCartInstructions {
/**
* Indicates whether a buyer can select a custom address.
*
* When true, this implies extensions can update the delivery address.
*/
canSelectCustomAddress: boolean;
}
DiscountsCartInstructions
- canUpdateDiscountCodes
Indicates whether or not discount codes can be updated.
boolean
export interface DiscountsCartInstructions {
/**
* Indicates whether or not discount codes can be updated.
*/
canUpdateDiscountCodes: boolean;
}
CartLinesCartInstructions
- canAddCartLine
Indicates whether or not new cart lines can be added.
boolean
- canRemoveCartLine
Indicates whether or not cart lines can be removed.
boolean
- canUpdateCartLine
Indicates whether or not cart lines can be updated.
boolean
export interface CartLinesCartInstructions {
/**
* Indicates whether or not new cart lines can be added.
*/
canAddCartLine: boolean;
/**
* Indicates whether or not cart lines can be removed.
*/
canRemoveCartLine: boolean;
/**
* Indicates whether or not cart lines can be updated.
*/
canUpdateCartLine: boolean;
}
MetafieldsCartInstructions
- canDeleteCartMetafield
Indicates whether or not cart metafields can be deleted.
boolean
- canSetCartMetafields
Indicates whether or not cart metafields can be added or updated.
boolean
export interface MetafieldsCartInstructions {
/**
* Indicates whether or not cart metafields can be added or updated.
*/
canSetCartMetafields: boolean;
/**
* Indicates whether or not cart metafields can be deleted.
*/
canDeleteCartMetafield: boolean;
}
NotesCartInstructions
- canUpdateNote
Indicates whether or not notes can be updated.
boolean
export interface NotesCartInstructions {
/**
* Indicates whether or not notes can be updated.
*/
canUpdateNote: boolean;
}
Anchor to useInstructionsuse Instructions()
Returns the cart instructions used to create the checkout and possibly limit extension capabilities.
- attributes
Cart instructions related to cart attributes.
- delivery
Cart instructions related to delivery.
- discounts
Cart instructions related to discounts.
- lines
Cart instructions related to cart lines.
- metafields
Cart instructions related to metafields.
- notes
Cart instructions related to notes.
CartInstructions
UseInstructionsGeneratedType
Returns the cart instructions used to create the checkout and possibly limit extension capabilities.
CartInstructions
export function useInstructions<
Target extends RenderExtensionTarget = RenderExtensionTarget,
>(): CartInstructions {
return useSubscription(useApi<Target>().instructions);
}
CartInstructions
- attributes
Cart instructions related to cart attributes.
AttributesCartInstructions
- delivery
Cart instructions related to delivery.
DeliveryCartInstructions
- discounts
Cart instructions related to discounts.
DiscountsCartInstructions
- lines
Cart instructions related to cart lines.
CartLinesCartInstructions
- metafields
Cart instructions related to metafields.
MetafieldsCartInstructions
- notes
Cart instructions related to notes.
NotesCartInstructions
export interface CartInstructions {
/**
* Cart instructions related to cart attributes.
*/
attributes: AttributesCartInstructions;
/**
* Cart instructions related to delivery.
*/
delivery: DeliveryCartInstructions;
/**
* Cart instructions related to discounts.
*/
discounts: DiscountsCartInstructions;
/**
* Cart instructions related to cart lines.
*/
lines: CartLinesCartInstructions;
/**
* Cart instructions related to metafields.
*/
metafields: MetafieldsCartInstructions;
/**
* Cart instructions related to notes.
*/
notes: NotesCartInstructions;
}
AttributesCartInstructions
- canUpdateAttributes
Indicates whether or not cart attributes can be updated.
boolean
export interface AttributesCartInstructions {
/**
* Indicates whether or not cart attributes can be updated.
*/
canUpdateAttributes: boolean;
}
DeliveryCartInstructions
- canSelectCustomAddress
Indicates whether a buyer can select a custom address. When true, this implies extensions can update the delivery address.
boolean
export interface DeliveryCartInstructions {
/**
* Indicates whether a buyer can select a custom address.
*
* When true, this implies extensions can update the delivery address.
*/
canSelectCustomAddress: boolean;
}
DiscountsCartInstructions
- canUpdateDiscountCodes
Indicates whether or not discount codes can be updated.
boolean
export interface DiscountsCartInstructions {
/**
* Indicates whether or not discount codes can be updated.
*/
canUpdateDiscountCodes: boolean;
}
CartLinesCartInstructions
- canAddCartLine
Indicates whether or not new cart lines can be added.
boolean
- canRemoveCartLine
Indicates whether or not cart lines can be removed.
boolean
- canUpdateCartLine
Indicates whether or not cart lines can be updated.
boolean
export interface CartLinesCartInstructions {
/**
* Indicates whether or not new cart lines can be added.
*/
canAddCartLine: boolean;
/**
* Indicates whether or not cart lines can be removed.
*/
canRemoveCartLine: boolean;
/**
* Indicates whether or not cart lines can be updated.
*/
canUpdateCartLine: boolean;
}
MetafieldsCartInstructions
- canDeleteCartMetafield
Indicates whether or not cart metafields can be deleted.
boolean
- canSetCartMetafields
Indicates whether or not cart metafields can be added or updated.
boolean
export interface MetafieldsCartInstructions {
/**
* Indicates whether or not cart metafields can be added or updated.
*/
canSetCartMetafields: boolean;
/**
* Indicates whether or not cart metafields can be deleted.
*/
canDeleteCartMetafield: boolean;
}
NotesCartInstructions
- canUpdateNote
Indicates whether or not notes can be updated.
boolean
export interface NotesCartInstructions {
/**
* Indicates whether or not notes can be updated.
*/
canUpdateNote: boolean;
}
Discounts
examples
Discounts
description
Check `instructions.discounts.canUpdateDiscountCodes` before calling `applyDiscountCodeChange()`.
React
import { Banner, Button, useApplyDiscountCodeChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { const applyDiscountCodeChange = useApplyDiscountCodeChange(); const instructions = useInstructions(); if ( instructions.discounts.canUpdateDiscountCodes ) { return ( <Button onPress={() => applyDiscountCodeChange({ type: 'addDiscountCode', code: 'FREE_SHIPPING', }) } > Apply your loyalty discount </Button> ); } else { return ( <Banner status="warning"> Loyalty discounts are unavailable </Banner> ); } }
JavaScript
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', ), ); } }, );
Anchor to examplesExamples
Use the cart instructions API to determine if the affected APIs are available in checkout.
Anchor to example-attributesAttributes
Check before calling
.
Anchor to example-deliveryDelivery
Check before calling
. When
true
, this instruction implies that extensions can change the shipping address.
Anchor to example-discountsDiscounts
Check before calling
.
Check or
or
before calling
.
Anchor to example-metafieldsMetafields
Check or
before calling
if you are working with cart metafields.
Check before calling
.
Attributes
examples
Attributes
description
Check `instructions.attributes.canUpdateAttributes` before calling `applyAttributeChange()`.
React
import { Banner, Button, useApplyAttributeChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { const applyAttributeChange = useApplyAttributeChange(); const instructions = useInstructions(); if ( instructions.attributes.canUpdateAttributes ) { return ( <Button onPress={() => applyAttributeChange({ type: 'updateAttribute', key: 'loyaltyPoints', value: '100', }) } > Apply 100 loyalty points </Button> ); } else { return ( <Banner status="warning"> Loyalty points are unavailable </Banner> ); } }
JavaScript
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', ), ); } }, );
Delivery
description
Check `instructions.delivery.canSelectCustomAddress` before calling `applyShippingAddressChange()`. When `true`, this instruction implies that extensions can change the shipping address.
React
import { Banner, Button, useApplyShippingAddressChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { const applyShippingAddressChange = useApplyShippingAddressChange(); const instructions = useInstructions(); if ( instructions.delivery.canSelectCustomAddress ) { return ( <Button onPress={() => applyShippingAddressChange({ type: 'updateShippingAddress', address: { zip: '90201', }, }) } > Change your postal code </Button> ); } else { return ( <Banner status="warning"> Shipping address cannot be modified </Banner> ); } }
JavaScript
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', ), ); } }, );
Discounts
description
Check `instructions.discounts.canUpdateDiscountCodes` before calling `applyDiscountCodeChange()`.
React
import { Banner, Button, useApplyDiscountCodeChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { const applyDiscountCodeChange = useApplyDiscountCodeChange(); const instructions = useInstructions(); if ( instructions.discounts.canUpdateDiscountCodes ) { return ( <Button onPress={() => applyDiscountCodeChange({ type: 'addDiscountCode', code: 'FREE_SHIPPING', }) } > Apply your loyalty discount </Button> ); } else { return ( <Banner status="warning"> Loyalty discounts are unavailable </Banner> ); } }
JavaScript
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', ), ); } }, );
Lines
description
Check `instructions.lines.canAddCartLine` or `instructions.lines.canRemoveCartLine` or `instructions.lines.canUpdateCartLine` before calling `applyCartLinesChange()`.
React
import { Banner, Button, useApplyCartLinesChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { const applyCartLinesChange = useApplyCartLinesChange(); const instructions = useInstructions(); if (instructions.lines.canAddCartLine) { return ( <Button onPress={() => applyCartLinesChange({ type: 'addCartLine', merchandiseId: 'gid://shopify/product/1234', quantity: 1, }) } > Add a free gift to your order </Button> ); } else { return ( <Banner status="warning"> The products in your cart cannot be modified </Banner> ); } }
JavaScript
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', ), ); } }, );
Metafields
description
Check `instructions.metafields.canSetCartMetafields` or `instructions.metafields.canDeleteCartMetafields` before calling `applyMetafieldChange()` if you are working with cart metafields.
React
import { Banner, Button, useApplyMetafieldChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { const applyMetafieldChange = useApplyMetafieldChange(); const instructions = useInstructions(); if ( instructions.metafields.canSetCartMetafields ) { return ( <Button onPress={() => applyMetafieldChange({ type: 'updateCartMetafield', metafield: { namespace: 'loyalty', key: 'loyaltyPoints', value: '100', type: 'string', }, }) } > Apply 100 loyalty points </Button> ); } else { return ( <Banner status="warning"> Loyalty points are unavailable </Banner> ); } }
JavaScript
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', ), ); } }, );
Notes
description
Check `instructions.notes.canUpdateNote` before calling `applyNoteChange()`.
React
import { Banner, Button, useApplyNoteChange, useInstructions, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { const applyNoteChange = useApplyNoteChange(); const instructions = useInstructions(); if (instructions.notes.canUpdateNote) { return ( <Button onPress={() => applyNoteChange({ type: 'updateNote', note: 'Please include a free gift.', }) } > Include a free gift with your order </Button> ); } else { return ( <Banner status="warning"> Free gifts cannot be added to this order </Banner> ); } }
JavaScript
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', ), ); } }, );