# 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',
),
);
}
},
);
```