Version 2025-07 is the last API version to support React-based UI components. Later versions use Polaris web components, native UI elements with built-in accessibility, better performance, and consistent styling with Shopify's design system. Check out the upgrade guide to upgrade your extension and avoid being blocked from updating your extension after October 1st 2026.
Attributes API
The Attributes API provides read-only access to the custom key-value pairs attached to the order. Use this API to read custom attributes attached to the order, such as delivery instructions or gift messages.
This API reads attributes that were set when the order was placed. To store your own custom data on orders, use metafields instead.
Anchor to Use casesUse cases
- Display delivery instructions: Read and display special instructions the buyer provided, such as "Leave at the back door."
- Show gift messages: Display a gift message the buyer attached to their order.
- Process custom data: Access key-value pairs added by other extensions during checkout, such as a preferred delivery date.
Supported targets
- customer-account.
order-status. announcement. render - customer-account.
order-status. block. render - customer-account.
order-status. cart-line-item. render-after - customer-account.
order-status. cart-line-list. render-after - customer-account.
order-status. customer-information. render-after - customer-account.
order-status. fulfillment-details. render-after - customer-account.
order-status. payment-details. render-after - customer-account.
order-status. return-details. render-after - customer-account.
order-status. unfulfilled-items. render-after - customer-account.
order. page. render
Supported targets
- customer-account.
order-status. announcement. render - customer-account.
order-status. block. render - customer-account.
order-status. cart-line-item. render-after - customer-account.
order-status. cart-line-list. render-after - customer-account.
order-status. customer-information. render-after - customer-account.
order-status. fulfillment-details. render-after - customer-account.
order-status. payment-details. render-after - customer-account.
order-status. return-details. render-after - customer-account.
order-status. unfulfilled-items. render-after - customer-account.
order. page. render
Anchor to PropertiesProperties
The Attributes API object provides custom attributes from the order. Access the following properties on the API object to read attribute data.
- Anchor to attributesattributesattributesStatefulRemoteSubscribable<Attribute[] | undefined>StatefulRemoteSubscribable<Attribute[] | undefined>requiredrequired
Custom key-value pairs that the buyer attached to the order during cart or checkout, commonly used for special instructions or order customization.
Attribute
- key
The attribute name. Keys are unique within the attribute list.
string - value
The attribute value as a string.
string
Examples
Description
Read all custom attributes from the order and display each key-value pair. This example uses the `useAttributes` hook and iterates over the attribute array.
React
import { reactExtension, useAttributes, } from '@shopify/ui-extensions-react/customer-account'; import { BlockStack, Text, } from '@shopify/ui-extensions/customer-account'; export default reactExtension( 'customer-account.order-status.block.render', () => <Extension />, ); function Extension() { const attributes = useAttributes(); if (!attributes || attributes.length === 0) { return null; } return ( <BlockStack> <Text emphasis="bold">Order details</Text> {attributes.map((attr) => ( <Text key={attr.key}> {attr.key}: {attr.value} </Text> ))} </BlockStack> ); }TS
import { extension, BlockStack, Text, } from '@shopify/ui-extensions/customer-account'; export default extension( 'customer-account.order-status.block.render', (root, api) => { const attributes = api.attributes.current; if (!attributes || attributes.length === 0) return; const stack = root.createComponent(BlockStack, {}); stack.appendChild( root.createComponent(Text, {emphasis: 'bold'}, 'Order details'), ); for (const attr of attributes) { stack.appendChild( root.createComponent(Text, {}, `${attr.key}: ${attr.value}`), ); } root.appendChild(stack); }, );Description
Look up a specific attribute by key and display its value in a banner. This example uses `useAttributeValues` to retrieve a single attribute without filtering the full list.
React
import { reactExtension, useAttributeValues, } from '@shopify/ui-extensions-react/customer-account'; import { Banner, Text, } from '@shopify/ui-extensions/customer-account'; export default reactExtension( 'customer-account.order-status.block.render', () => <Extension />, ); function Extension() { const [giftMessage] = useAttributeValues(['Gift Message']); if (!giftMessage) { return null; } return ( <Banner status="info" title="Gift message"> <Text>{giftMessage}</Text> </Banner> ); }TS
import { extension, Banner, Text, } from '@shopify/ui-extensions/customer-account'; export default extension( 'customer-account.order-status.block.render', (root, api) => { const attributes = api.attributes.current; const giftMessage = attributes?.find( (attr) => attr.key === 'Gift Message', ); if (!giftMessage) return; const banner = root.createComponent( Banner, {status: 'info', title: 'Gift message'}, ); banner.appendChild( root.createComponent(Text, {}, giftMessage.value), ); root.appendChild(banner); }, );Description
Read the delivery instructions attribute and display it as a banner. This example uses `useAttributeValues` to look up a known key and conditionally renders the result.
React
import { reactExtension, useAttributeValues, } from '@shopify/ui-extensions-react/customer-account'; import { Banner, } from '@shopify/ui-extensions/customer-account'; export default reactExtension( 'customer-account.order-status.block.render', () => <Extension />, ); function Extension() { const [instructions] = useAttributeValues([ 'Delivery Instructions', ]); if (!instructions) { return null; } return ( <Banner status="info" title="Delivery instructions"> {instructions} </Banner> ); }TS
import { extension, Banner, } from '@shopify/ui-extensions/customer-account'; export default extension( 'customer-account.order-status.block.render', (root, api) => { const attributes = api.attributes.current; const instructions = attributes?.find( (attr) => attr.key === 'Delivery Instructions', ); if (!instructions) return; root.appendChild( root.createComponent( Banner, {status: 'info', title: 'Delivery instructions'}, instructions.value, ), ); }, );
Anchor to Best practicesBest practices
- Use
useAttributeValuesfor known keys: When you need a specific attribute, useuseAttributeValuesinstead of filtering the full list. - Handle missing attributes gracefully: Attributes are optional. The list may be empty or
undefinedif the buyer didn't add any custom data.
Anchor to LimitationsLimitations
- Attribute values are always strings. If you stored structured data during checkout, you need to parse it in your extension.
- There's no metadata about who set an attribute. You can't determine whether an attribute was set by the buyer, a theme, or another extension.