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.

Spinner

Use the Spinner component to notify customers that their action is being processed. Spinners are typically used for page or section loading states when sending or receiving data from a server.

Spinners support multiple sizes and an appearance property to match the surrounding content. For operations with a known duration, use Progress instead.

Support
Targets (25)

Configure the following properties on the Spinner component.

Anchor to accessibilityLabel
accessibilityLabel
string

A label that describes the purpose or contents of the element. When set, it will be announced to users using assistive technologies and will provide them with more context. When set, any children or label supplied won't be announced to screen readers.

Anchor to appearance
appearance
'accent' | 'monochrome'
Default: 'accent'

The visual appearance of the spinner icon.

  • accent: Uses the accent color to convey emphasis and draw attention.
  • monochrome: Inherits the color of its parent element.
string

A unique identifier for the component. Use this to target the component in scripts or stylesheets, or to distinguish it from other instances of the same component.

'extraSmall' | 'small' | 'large' | 'base' | 'fill'
Default: 'base'

The size of the spinner icon.

  • extraSmall: The smallest size for tight spaces or inline indicators.
  • small: A compact size for secondary loading states.
  • base: The default size, suitable for most use cases.
  • large: A larger size for more prominent loading states.
  • fill: Expands to fill the available space.

Anchor to Show a loading indicatorShow a loading indicator

Display a basic spinner to indicate that content is loading. Without an accessibilityLabel, the spinner renders an animated indicator for all customers.

Show a loading indicator

A spinner indicating that content is loading.

Show a loading indicator

import {
reactExtension,
Spinner,
} from '@shopify/ui-extensions-react/customer-account';

export default reactExtension(
'customer-account.page.render',
() => <Extension />,
);

function Extension() {
return <Spinner />;
}
import {extension, Spinner} from '@shopify/ui-extensions/customer-account';

export default extension('customer-account.page.render', (root) => {
const spinner = root.createComponent(Spinner);

root.appendChild(spinner);
});

Anchor to Display a labeled loading stateDisplay a labeled loading state

Pair a spinner with text to describe what's loading. This example centers a spinner above a "Loading order details..." message so customers know what to expect.

Display a labeled loading state

import {
reactExtension,
BlockStack,
Spinner,
Text,
} from '@shopify/ui-extensions-react/customer-account';

export default reactExtension(
'customer-account.page.render',
() => <Extension />,
);

function Extension() {
return (
<BlockStack inlineAlignment="center" spacing="base">
<Spinner accessibilityLabel="Loading order details" />
<Text appearance="subdued">
Loading order details...
</Text>
</BlockStack>
);
}
import {
extension,
BlockStack,
Spinner,
Text,
} from '@shopify/ui-extensions/customer-account';

export default extension('customer-account.page.render', (root) => {
const container = root.createComponent(
BlockStack,
{inlineAlignment: 'center', spacing: 'base'},
[
root.createComponent(Spinner, {
accessibilityLabel: 'Loading order details',
}),
root.createComponent(
Text,
{appearance: 'subdued'},
'Loading order details...',
),
],
);

root.appendChild(container);
});

Anchor to Use a monochrome spinnerUse a monochrome spinner

Set appearance="monochrome" so the spinner takes the color of its parent, blending with surrounding text. This example shows a small monochrome spinner inline with a status message.

Use a monochrome spinner

import {
reactExtension,
InlineStack,
Spinner,
Text,
} from '@shopify/ui-extensions-react/customer-account';

export default reactExtension(
'customer-account.page.render',
() => <Extension />,
);

function Extension() {
return (
<InlineStack spacing="base" blockAlignment="center">
<Spinner
size="small"
appearance="monochrome"
accessibilityLabel="Refreshing"
/>
<Text appearance="subdued">
Refreshing your subscription...
</Text>
</InlineStack>
);
}
import {
extension,
InlineStack,
Spinner,
Text,
} from '@shopify/ui-extensions/customer-account';

export default extension('customer-account.page.render', (root) => {
const container = root.createComponent(
InlineStack,
{spacing: 'base', blockAlignment: 'center'},
[
root.createComponent(Spinner, {
size: 'small',
appearance: 'monochrome',
accessibilityLabel: 'Refreshing',
}),
root.createComponent(
Text,
{appearance: 'subdued'},
'Refreshing your subscription...',
),
],
);

root.appendChild(container);
});

  • Always provide an accessibility label: Set accessibilityLabel so screen readers can announce what's loading. Without it, the spinner is just an animated graphic with no context.
  • Use spinners for page or section loading, not buttons: For button loading states, use the button's built-in loading property instead.
  • Pair with descriptive text: Spinners alone don't explain what's happening. Add nearby text that describes the operation in progress.
  • Use monochrome to blend with content: Set appearance="monochrome" when the spinner should match the color of its parent element rather than using the default accent color.

  • The Spinner component doesn't include built-in text. Pair it with layout and text components to describe the loading state.
  • Customers who prefer reduced motion see a static text label instead of the animated indicator, but only if accessibilityLabel is set. Without it, the animated indicator is shown to all customers.
  • Spinner sizes are limited to the predefined set (extraSmall, small, base, large, fill). Custom sizes aren't supported.

Was this page helpful?