--- title: Attributes description: The API for interacting with cart and checkout attributes. api_version: 2026-01 api_name: checkout-ui-extensions source_url: html: https://shopify.dev/docs/api/checkout-ui-extensions/latest/apis/attributes md: https://shopify.dev/docs/api/checkout-ui-extensions/latest/apis/attributes.md --- # Attributes The API for interacting with cart and checkout attributes. ## StandardApi The base API object provided to `purchase` extension targets. * **attributes** **SubscribableSignalLike\** **required** The custom attributes left by the customer to the merchant, either in their cart or during checkout. ### SubscribableSignalLike Represents a read-only value managed on the main thread that an extension can subscribe to. Example: Checkout uses this to manage the state of an object and communicate state changes to extensions running in a sandboxed web worker. This interface is compatible with \[Preact's ReadonlySignal]\(https://github.com/preactjs/signals/blob/a023a132a81bd4ba4a0bebb8cbbeffbd8c8bbafc/packages/core/src/index.ts#L700-L709). Some fields are deprecated but still supported for backwards compatibility. In version 2025-10, \[\`StatefulRemoteSubscribable\`]\(https://github.com/Shopify/remote-dom/blob/03929aa8418a89d41d294005f219837582718df8/packages/async-subscription/src/types.ts#L17) was replaced with \`ReadonlySignalLike\`. Checkout will remove the old fields some time in the future. * current ```ts T ``` * destroy ```ts () => Promise ``` * subscribe Subscribes to value changes and calls the provided function whenever the value updates. Returns an unsubscribe function to clean up the subscription. Use to automatically react to changes in the signal's value. ```ts (fn: (value: T) => void) => () => void ``` * value The current value of the signal. This property provides immediate access to the current value without requiring subscription setup. Use for one-time value checks or initial setup. ```ts T ``` ```ts export interface SubscribableSignalLike extends ReadonlySignalLike { /** * @deprecated Use `.value` instead. */ readonly current: T; /** * @deprecated No longer needed. Use Preact Signal management instead. */ destroy(): Promise; } ``` ### Attribute * key The key for the attribute. ```ts string ``` * value The value for the attribute. ```ts string ``` ```ts export interface Attribute { /** * The key for the attribute. */ key: string; /** * The value for the attribute. */ value: string; } ``` ## CheckoutApi The API object provided to `purchase.checkout` extension targets. * **applyAttributeChange** **(change: AttributeChange) => Promise\** **required** **deprecated** Performs an update on an attribute attached to the cart and checkout. If successful, this mutation results in an update to the value retrieved through the [`attributes`](https://shopify.dev/docs/api/checkout-ui-extensions/apis/attributes#standardapi-propertydetail-attributes) property. **Note:** This method will return an error if the \cart instruction\ \\attributes.can\Update\Attributes\\ is false, or the buyer is using an accelerated checkout method, such as Apple Pay or Google Pay. **Deprecated:** * Consumers should use cart metafields instead. ### AttributeChange ```ts AttributeUpdateChange | AttributeRemoveChange ``` ### AttributeUpdateChange Updates an attribute on the order. If an attribute with the provided key does not already exist, it gets created. * key Key of the attribute to add or update ```ts string ``` * type The type of the \`AttributeUpdateChange\` API. ```ts 'updateAttribute' ``` * value Value for the attribute to add or update ```ts string ``` ```ts export interface AttributeUpdateChange { /** * The type of the `AttributeUpdateChange` API. */ type: 'updateAttribute'; /** * Key of the attribute to add or update */ key: string; /** * Value for the attribute to add or update */ value: string; } ``` ### AttributeRemoveChange Removes an attribute on the order if an attribute with the provided key already exists. * key Key of the attribute to remove ```ts string ``` * type The type of the \`AttributeRemoveChange\` API. ```ts 'removeAttribute' ``` ```ts export interface AttributeRemoveChange { /** * The type of the `AttributeRemoveChange` API. */ type: 'removeAttribute'; /** * Key of the attribute to remove */ key: string; } ``` ### AttributeChangeResult ```ts AttributeChangeResultSuccess | AttributeChangeResultError ``` ### AttributeChangeResultSuccess The returned result of a successful update to an attribute. * type The type of the \`AttributeChangeResultSuccess\` API. ```ts 'success' ``` ```ts export interface AttributeChangeResultSuccess { /** * The type of the `AttributeChangeResultSuccess` API. */ type: 'success'; } ``` ### AttributeChangeResultError The returned result of an unsuccessful update to an attribute with a message detailing the type of error that occurred. * message A message that explains the error. This message is useful for debugging. It is \*\*not\*\* localized, and therefore should not be presented directly to the buyer. ```ts string ``` * type The type of the \`AttributeChangeResultError\` API. ```ts 'error' ``` ```ts export interface AttributeChangeResultError { /** * The type of the `AttributeChangeResultError` API. */ type: 'error'; /** * A message that explains the error. This message is useful for debugging. * It is **not** localized, and therefore should not be presented directly * to the buyer. */ message: string; } ``` ## use​Apply​Attribute​Change() Returns a function to mutate the `attributes` property of the checkout. ### Returns * **(change: AttributeChange) => Promise\** ### AttributeChange ```ts AttributeUpdateChange | AttributeRemoveChange ``` ### AttributeUpdateChange Updates an attribute on the order. If an attribute with the provided key does not already exist, it gets created. * key Key of the attribute to add or update ```ts string ``` * type The type of the \`AttributeUpdateChange\` API. ```ts 'updateAttribute' ``` * value Value for the attribute to add or update ```ts string ``` ```ts export interface AttributeUpdateChange { /** * The type of the `AttributeUpdateChange` API. */ type: 'updateAttribute'; /** * Key of the attribute to add or update */ key: string; /** * Value for the attribute to add or update */ value: string; } ``` ### AttributeRemoveChange Removes an attribute on the order if an attribute with the provided key already exists. * key Key of the attribute to remove ```ts string ``` * type The type of the \`AttributeRemoveChange\` API. ```ts 'removeAttribute' ``` ```ts export interface AttributeRemoveChange { /** * The type of the `AttributeRemoveChange` API. */ type: 'removeAttribute'; /** * Key of the attribute to remove */ key: string; } ``` ### AttributeChangeResult ```ts AttributeChangeResultSuccess | AttributeChangeResultError ``` ### AttributeChangeResultSuccess The returned result of a successful update to an attribute. * type The type of the \`AttributeChangeResultSuccess\` API. ```ts 'success' ``` ```ts export interface AttributeChangeResultSuccess { /** * The type of the `AttributeChangeResultSuccess` API. */ type: 'success'; } ``` ### AttributeChangeResultError The returned result of an unsuccessful update to an attribute with a message detailing the type of error that occurred. * message A message that explains the error. This message is useful for debugging. It is \*\*not\*\* localized, and therefore should not be presented directly to the buyer. ```ts string ``` * type The type of the \`AttributeChangeResultError\` API. ```ts 'error' ``` ```ts export interface AttributeChangeResultError { /** * The type of the `AttributeChangeResultError` API. */ type: 'error'; /** * A message that explains the error. This message is useful for debugging. * It is **not** localized, and therefore should not be presented directly * to the buyer. */ message: string; } ``` ## use​Attributes() Returns the proposed `attributes` applied to the checkout. ### Returns * **Attribute\[]** ### Attribute * key The key for the attribute. ```ts string ``` * value The value for the attribute. ```ts string ``` ```ts export interface Attribute { /** * The key for the attribute. */ key: string; /** * The value for the attribute. */ value: string; } ``` ## use​Attribute​Values(**[keys](#useattributevalues-propertydetail-keys)**​) Returns the values for the specified `attributes` applied to the checkout. ### Parameters * **keys** **string\[]** **required** An array of attribute keys. ### Returns * **(string | undefined)\[]** Examples ### Examples * #### Attribute values ##### Preact ```jsx import '@shopify/ui-extensions/preact'; import {render} from 'preact'; import {useAttributeValues} from '@shopify/ui-extensions/checkout/preact'; export default function extension() { render(, document.body); } function Extension() { const [buyerSelectedFreeTShirt, tshirtSize] = useAttributeValues([ 'buyerSelectedFreeTShirt', 'tshirtSize', ]); if (Boolean(buyerSelectedFreeTShirt) === true) { return ( You selected a free t-shirt, size:{' '} {tshirtSize} ); } return null; } ``` * #### Applying changes to attributes ##### Description You can add or remove cart and checkout attributes by using the \`applyAttributeChange\` API. ##### Preact ```jsx import '@shopify/ui-extensions/preact'; import {render} from 'preact'; import {useAttributeValues} from '@shopify/ui-extensions/checkout/preact'; export default function extension() { render(, document.body); } function Extension() { const [giftWrapValue] = useAttributeValues([ 'giftWrap', ]); const giftWrap = Boolean(giftWrapValue); async function toggleGiftWrap() { const result = giftWrap ? await shopify.applyAttributeChange({ type: 'removeAttribute', key: 'giftWrap', }) : await shopify.applyAttributeChange({ type: 'updateAttribute', key: 'giftWrap', value: 'true', }); if (result.type === 'error') { console.error(result.message); } } return ( Gift wrapping:{' '} {giftWrap ? 'Added' : 'Not set'} {giftWrap ? 'Remove gift wrap' : 'Add gift wrap'} ); } ``` ## Related [Reference - Targets](https://shopify.dev/docs/api/checkout-ui-extensions/targets) [Reference - Components](https://shopify.dev/docs/api/checkout-ui-extensions/components) [Reference - Configuration](https://shopify.dev/docs/api/checkout-ui-extensions/configuration) [Learn - Tutorials](https://shopify.dev/apps/checkout)