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.

Popover

The Popover component displays contextual content in a small overlay triggered by user interaction. Use for secondary actions, settings, or information that doesn't require a full modal.

The library automatically applies the WAI-ARIA Popover Widget pattern to both the activator and the popover content. For interactions that need more space or user focus, such as confirmations or complex forms, use Modal instead.

Support
Targets (25)

Configure the following properties on the Popover component.

Anchor to alignment
alignment
Default: 'center'

The alignment of the popover in the axis determined by the position.

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.

Anchor to maxInlineSize
maxInlineSize
< number | `${number}%` | 'fill' >

The maximum inline size (maximum width in horizontal writing modes). The element won't grow wider than this value.

  • number: The size in pixels.
  • `${number}%`: The size as a percentage of the parent container's inline size.
  • 'fill': Takes all the available space.

Learn more about the max-inline-size property.

Anchor to minInlineSize
minInlineSize
< number | `${number}%` | 'fill' >

The minimum inline size (minimum width in horizontal writing modes). The element won't shrink narrower than this value.

  • number: The size in pixels.
  • `${number}%`: The size as a percentage of the parent container's inline size.
  • 'fill': Takes all the available space.

Learn more about the min-inline-size property.

Anchor to onClose
onClose
() => void

A callback fired when the popover is closed.

Anchor to onOpen
onOpen
() => void

A callback fired when the popover is opened.

Anchor to padding
padding
<<>>

The padding on all edges of the element, using a shorthand syntax. You can specify one, two, or four values following the CSS shorthand convention.

  • T: A single value applied uniformly to all edges.
  • [T, T]: The first value applies to block-start and block-end, the second to inline-start and inline-end.
  • [T, T, T, T]: Values apply to block-start, inline-end, block-end, and inline-start respectively.
Anchor to position
position
Default: 'blockStart'

The position of the popover relative to the activator.


Anchor to Display contextual informationDisplay contextual information

Surface supplementary information on demand without cluttering the main view. This example shows payment details in a popover triggered by a pressable element.

Display contextual information

A popover displaying contextual payment information.

Display contextual information

import {
reactExtension,
Pressable,
Popover,
View,
TextBlock,
} from '@shopify/ui-extensions-react/customer-account';

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

function Extension() {
return (
<Pressable
overlay={
<Popover>
<View
maxInlineSize={200}
padding="base"
>
<TextBlock>
A thoughtful way to pay
</TextBlock>
<TextBlock>Tap don’t type</TextBlock>
<TextBlock>
Shop Pay remembers your important
details, so you can fill carts, not
forms. And everything is encrypted
so you can speed safely through
checkout.
</TextBlock>
</View>
</Popover>
}
>
More info
</Pressable>
);
}
import {
extension,
Pressable,
Popover,
View,
TextBlock,
} from '@shopify/ui-extensions/customer-account';

export default extension('customer-account.page.render', (root) => {
const popoverFragment = root.createFragment();
const popover = root.createComponent(Popover, {}, [
root.createComponent(View, {maxInlineSize: 200, padding: 'base'}, [
root.createComponent(TextBlock, {}, 'A thoughtful way to pay'),
root.createComponent(TextBlock, {}, 'Tap don’t type'),
root.createComponent(
TextBlock,
{},
'Shop Pay remembers your important details, so you can fill carts, not forms. And everything is encrypted so you can speed safely through checkout.',
),
]),
]);
popoverFragment.appendChild(popover);
const pressable = root.createComponent(
Pressable,
{overlay: popoverFragment},
'More info',
);

root.appendChild(pressable);
});

Anchor to Show a form in a popoverShow a form in a popover

Collect input inline without navigating away from the page. This example presents a text field and submit button inside a popover for verifying a veteran ID.

Show a form in a popover

import {
reactExtension,
Button,
Pressable,
Popover,
View,
TextField,
} from '@shopify/ui-extensions-react/customer-account';

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

function Extension() {
return (
<Pressable
overlay={
<Popover>
<View
maxInlineSize={280}
padding="base"
>
<TextField label="Veteran ID" />
<Button>Verify</Button>
</View>
</Popover>
}
>
Verify veteran status
</Pressable>
);
}
import {
extension,
Button,
Pressable,
Popover,
View,
TextField,
} from '@shopify/ui-extensions/customer-account';

export default extension(
'customer-account.order-status.block.render',
(root) => {
const popoverFragment = root.createFragment();
const popover = root.createComponent(Popover, {}, [
root.createComponent(
View,
{maxInlineSize: 280, padding: 'base'},
[
root.createComponent(TextField, {label: 'Veteran ID'}),
root.createComponent(Button, {}, 'Verify'),
],
),
]);
popoverFragment.appendChild(popover);
const pressable = root.createComponent(
Pressable,
{overlay: popoverFragment},
'Verify veteran status',
);

root.appendChild(pressable);
},
);

Anchor to Display a list of actionsDisplay a list of actions

Present a set of related actions in a compact overlay. This example shows an action list with options for returns, support, and issue reporting.

Display a list of actions

import {
reactExtension,
Button,
Popover,
View,
BlockStack,
Link,
} from '@shopify/ui-extensions-react/customer-account';

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

function Extension() {
return (
<Button
overlay={
<Popover>
<View padding="base">
<BlockStack>
<Link to="/account/returns">
Start a return
</Link>
<Link to="/account/support">
Contact support
</Link>
<Link to="/account/report">
Report an issue
</Link>
</BlockStack>
</View>
</Popover>
}
>
Order actions
</Button>
);
}
import {
extension,
Button,
Popover,
View,
BlockStack,
Link,
} from '@shopify/ui-extensions/customer-account';

export default extension(
'customer-account.order-status.block.render',
(root) => {
const popoverFragment = root.createFragment();
const popover = root.createComponent(Popover, {}, [
root.createComponent(View, {padding: 'base'}, [
root.createComponent(BlockStack, {}, [
root.createComponent(Link, {to: '/account/returns'}, 'Start a return'),
root.createComponent(Link, {to: '/account/support'}, 'Contact support'),
root.createComponent(Link, {to: '/account/report'}, 'Report an issue'),
]),
]),
]);
popoverFragment.appendChild(popover);
const button = root.createComponent(
Button,
{overlay: popoverFragment},
'Order actions',
);

root.appendChild(button);
},
);

  • Avoid placing critical information in a popover: Popovers are hidden until triggered, making them unsuitable for essential content that customers need to see immediately.
  • Group related actions: Contain actions that share a relationship to each other so the popover feels cohesive.
  • Trigger with a clearly labeled activator: The element that opens the popover should clearly indicate what'll appear when activated.

  • Popovers can only be opened by user interaction through an activator component, not programmatically on page load.
  • The popover position is determined by the activator element and can't be manually overridden.
  • Content within the popover doesn't scroll automatically; use a View component for internal scrolling if needed.

Was this page helpful?