---
title: Updating to 2024-10
description: >
Some checkouts may be created with [cart
instructions](/docs/api/checkout-ui-extensions/apis/cart-instructions) that
prevent buyers from making certain changes to their checkout. As of version
`2024-07`, UI extensions must check for instructions before calling select
APIs, to properly handle checkouts where those APIs are not available. >
Caution: As of **July 22nd, 2024**, all UI extensions on this version will
render in **draft order** invoice checkouts. As draft order invoice checkouts
have restrictions on what buyers can edit, UI extensions in draft order
invoice checkouts will be subject to cart instructions.
api_version: 2024-10
api_name: checkout-ui-extensions
source_url:
html: >-
https://shopify.dev/docs/api/checkout-ui-extensions/2024-10/instructions-update
md: >-
https://shopify.dev/docs/api/checkout-ui-extensions/2024-10/instructions-update.md
---
# Updating to 2024-10
Some checkouts may be created with [cart instructions](https://shopify.dev/docs/api/checkout-ui-extensions/apis/cart-instructions) that prevent buyers from making certain changes to their checkout.
As of version `2024-07`, UI extensions must check for instructions before calling select APIs, to properly handle checkouts where those APIs are not available.
Caution
As of **July 22nd, 2024**, all UI extensions on this version will render in **draft order** invoice checkouts. As draft order invoice checkouts have restrictions on what buyers can edit, UI extensions in draft order invoice checkouts will be subject to cart instructions.
***
## Required instruction checking
You will need to check for cart instructions before calling the following APIs:
| Extension API | As of July 2024 |
| - | - |
| applyAttributeChange() | Attributes cannot be modified on draft order checkouts. |
| applyShippingAddressChange() | Buyers cannot change the address on a draft order checkout if it has fixed shipping rates. |
| applyDiscountCodeChange() | By default, discounts cannot be modified in draft order checkouts. Merchants must allow it via a setting on the draft order. |
| applyCartLinesChange() | Cart lines cannot be modified on draft order checkouts. |
| applyMetafieldChange() | Cart metafields cannot be modified on draft order checkouts. Metafields can still be modified. |
| applyNoteChange() | Notes cannot be modified on draft order checkouts. |
Caution
If you don't check for instructions, the APIs will return an error when they're not available in a given checkout
[Learn more - Cart Instructions API](https://shopify.dev/docs/api/checkout-ui-extensions/apis/cart-instructions)
***
## Checking for cart instructions
Use the cart instructions API to determine if the affected APIs are available in checkout.
Changes to applyAttributeChange()
Check `instructions.attributes.canUpdateAttributes` before calling `applyAttributeChange()`.
Changes to applyShippingAddressChange()
Check `instructions.delivery.canSelectCustomAddress` before calling `applyShippingAddressChange()`. When `true`, this instruction implies that extensions can change the shipping address.
Changes to applyDiscountCodeChange()
Check `instructions.discounts.canUpdateDiscountCodes` before calling `applyDiscountCodeChange()`.
Changes to applyCartLinesChange()
Check `instructions.lines.canAddCartLine` or `instructions.lines.canRemoveCartLine` or `instructions.lines.canUpdateCartLine` before calling `applyCartLinesChange()`.
Changes to applyMetafieldChange()
Check `instructions.metafields.canSetCartMetafields` or `instructions.metafields.canDeleteCartMetafields` before calling `applyMetafieldChange()` if you are working with cart metafields.
Changes to applyNoteChange()
Check `instructions.notes.canUpdateNote` before calling `applyNoteChange()`.
## Migrating applyAttributeChange()
##### React
```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
);
}
}
```
##### JavaScript
```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',
),
);
}
},
);
```
## Migrating applyShippingAddressChange()
##### React
```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
);
}
}
```
##### JavaScript
```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',
),
);
}
},
);
```
## Migrating applyDiscountCodeChange()
##### React
```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
);
}
}
```
##### JavaScript
```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',
),
);
}
},
);
```
## Migrating applyCartLinesChange()
##### React
```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
);
}
}
```
##### JavaScript
```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',
),
);
}
},
);
```
## Migrating applyMetafieldChange()
##### React
```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
);
}
}
```
##### JavaScript
```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',
),
);
}
},
);
```
## Migrating applyNoteChange()
##### React
```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
);
}
}
```
##### JavaScript
```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',
),
);
}
},
);
```
***