Skip to main content
Migrate to Polaris

Version 2025-07 is the last API version to support React-based UI components. Later versions use web components, native UI elements with built-in accessibility, better performance, and consistent styling with Shopify's design system. Check out the migration guide to upgrade your extension.

CustomerAccountAction

The CustomerAccountAction component displays a modal to complete an order action flow. This component can only be used to populate the order action extension target, which renders as a result of the customer clicking the order action button rendered via the order action menu item extension target.

Support
Targets (25)

Configure the following properties on the CustomerAccountAction component.

Anchor to title
title
string
required

The main title displayed at the top of the action modal, rendered in the header alongside the close button. Use a short, descriptive phrase that tells the customer what the action does, such as "Request a return" or "Edit shipping address."

Anchor to primaryAction
primaryAction
RemoteFragment

The primary action for the modal. Accepts a single button component. Use this for the main confirmation action, such as "Submit" or "Confirm."

Anchor to secondaryAction
secondaryAction
RemoteFragment

The secondary action for the modal. Accepts a single button component. Use this for dismissive actions like "Cancel" or alternative actions.

Anchor to Primary action button propertiesPrimary action button properties

Configure the following properties on the primary action button.

Anchor to accessibilityLabel
accessibilityLabel
string

A label that describes the purpose or content of the button for users of assistive technologies such as screen readers. When set, any children supplied to this component won't be announced to screen reader users.

Anchor to accessibilityRole
accessibilityRole
Default: 'button'

The role of the button that will be rendered.

  • 'button': Renders a regular button.
  • 'submit': Renders a button that submits a form.
Anchor to disabled
disabled
boolean
Default: false

Whether the button is disabled, preventing it from being activated or receiving focus.

Anchor to loading
loading
boolean
Default: false

Whether the button is in a loading state, which replaces the button content with a loading indicator while a background action is being performed. This also disables the button.

Anchor to loadingLabel
loadingLabel
string

Accessible label for the loading indicator when user prefers reduced motion. This value is only used if loading is true.

Anchor to onPress
onPress
() => void

A callback fired when the button is activated by the user.

Anchor to Secondary action button propertiesSecondary action button properties

Configure the following properties on the secondary action button.

Anchor to accessibilityLabel
accessibilityLabel
string

A label that describes the purpose or content of the button for users of assistive technologies such as screen readers. When set, any children supplied to this component won't be announced to screen reader users.

Anchor to disabled
disabled
boolean
Default: false

Whether the button is disabled, preventing it from being activated or receiving focus.

Anchor to loading
loading
boolean
Default: false

Whether the button is in a loading state, which replaces the button content with a loading indicator while a background action is being performed. This also disables the button.

Anchor to loadingLabel
loadingLabel
string

Accessible label for the loading indicator when user prefers reduced motion. This value is only used if loading is true.

Anchor to onPress
onPress
() => void

A callback fired when the button is activated by the user.


Anchor to Create a basic action modalCreate a basic action modal

Display a modal with a heading, content, and a primary action button. This example shows a CustomerAccountAction with a simple layout for the order action target.

Create a basic action modal

A dismissible modal with a header, content area, and action buttons

Create a basic action modal

import {
Button,
CustomerAccountAction,
TextBlock,
reactExtension,
useApi,
} from '@shopify/ui-extensions-react/customer-account';
import React from 'react';

export default reactExtension('customer-account.order.action.render', () => (
<App />
));

function App() {
const api = useApi<'customer-account.order.action.render'>();

return (
<CustomerAccountAction
title="Extension title"
primaryAction={
<Button
onPress={() => {
api.close();
}}
>
Click to close
</Button>
}
>
<TextBlock>Extension content</TextBlock>
</CustomerAccountAction>
);
}
import {
Button,
CustomerAccountAction,
extension
} from '@shopify/ui-extensions/customer-account';

export default extension(
'customer-account.order.action.render',
(root, api) => {
renderApp(root, api);
},
)

async function renderApp(root, api) {
const primaryAction = root.createFragment();
await primaryAction.append(root.createComponent(Button, {onPress: () => {api.close()}}, 'Click to close'));

const customerAccountAction = root.createComponent(
CustomerAccountAction,
{
title: 'Extension title',
primaryAction,
},
root.createComponent('TextBlock', {}, 'Extension content')
);
root.append(customerAccountAction);
}

Anchor to Show a confirmation dialogShow a confirmation dialog

Present a confirmation dialog for a destructive action. This example shows a CustomerAccountAction with both primary and secondary action buttons for canceling an order.

Show a confirmation dialog

import {
Button,
CustomerAccountAction,
TextBlock,
reactExtension,
useApi,
} from '@shopify/ui-extensions-react/customer-account';
import React from 'react';

export default reactExtension('customer-account.order.action.render', () => (
<App />
));

function App() {
const api = useApi<'customer-account.order.action.render'>();

return (
<CustomerAccountAction
title="Cancel order"
primaryAction={
<Button
onPress={() => {
api.close();
}}
>
Confirm cancellation
</Button>
}
secondaryAction={
<Button
onPress={() => {
api.close();
}}
>
Go back
</Button>
}
>
<TextBlock>
Are you sure you want to cancel this order? This action
can't be undone.
</TextBlock>
</CustomerAccountAction>
);
}
import {
Button,
CustomerAccountAction,
extension,
} from '@shopify/ui-extensions/customer-account';

export default extension(
'customer-account.order.action.render',
(root, api) => {
renderApp(root, api);
},
);

async function renderApp(root, api) {
const primaryAction = root.createFragment();
await primaryAction.append(
root.createComponent(
Button,
{onPress: () => api.close()},
'Confirm cancellation',
),
);

const secondaryAction = root.createFragment();
await secondaryAction.append(
root.createComponent(
Button,
{onPress: () => api.close()},
'Go back',
),
);

const customerAccountAction = root.createComponent(
CustomerAccountAction,
{
title: 'Cancel order',
primaryAction,
secondaryAction,
},
root.createComponent(
'TextBlock',
{},
"Are you sure you want to cancel this order? This action can't be undone.",
),
);
root.append(customerAccountAction);
}

Anchor to Submit a return requestSubmit a return request

Collect confirmation from a customer before processing a return. This example shows a CustomerAccountAction modal with a description and primary and secondary actions.

Submit a return request

import {
Button,
CustomerAccountAction,
TextBlock,
reactExtension,
useApi,
} from '@shopify/ui-extensions-react/customer-account';
import React from 'react';

export default reactExtension('customer-account.order.action.render', () => (
<App />
));

function App() {
const api = useApi<'customer-account.order.action.render'>();

return (
<CustomerAccountAction
title="Submit return request"
primaryAction={
<Button
onPress={() => {
api.close();
}}
>
Submit request
</Button>
}
secondaryAction={
<Button
onPress={() => {
api.close();
}}
>
Cancel
</Button>
}
>
<TextBlock>
Your return request will be reviewed within 2 business
days. You'll receive an email with the return shipping
label.
</TextBlock>
</CustomerAccountAction>
);
}
import {
Button,
CustomerAccountAction,
extension,
} from '@shopify/ui-extensions/customer-account';

export default extension(
'customer-account.order.action.render',
(root, api) => {
renderApp(root, api);
},
);

async function renderApp(root, api) {
const primaryAction = root.createFragment();
await primaryAction.append(
root.createComponent(
Button,
{onPress: () => api.close()},
'Submit request',
),
);

const secondaryAction = root.createFragment();
await secondaryAction.append(
root.createComponent(
Button,
{onPress: () => api.close()},
'Cancel',
),
);

const customerAccountAction = root.createComponent(
CustomerAccountAction,
{
title: 'Submit return request',
primaryAction,
secondaryAction,
},
root.createComponent(
'TextBlock',
{},
"Your return request will be reviewed within 2 business days. You'll receive an email with the return shipping label.",
),
);
root.append(customerAccountAction);
}

  • Highlight the key decision: Use the component to present essential details and actions needed to confirm or complete an order task.
  • Collect only what's necessary: Request the minimum information required to finish the task so the flow stays quick and friction-free.
  • Keep forms simple: Use clear labels, intuitive actions, and concise copy so customers know what's required and what happens next.
  • Use full-page extensions for complex flows: If the task spans multiple steps or needs extensive input, consider building a full-page extension instead.

  • This component can only be used within the customer-account.order.action.render extension target. It won't render in other targets.
  • The modal doesn't support multi-step flows. Each action modal is a single-step interaction.

Was this page helpful?