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.
Select
The Select component provides a dropdown menu for choosing a single value from a predefined list of options. It supports option groups, placeholder text, disabled and read-only states, and inline validation errors.
For visible radio/checkbox lists, use ChoiceList.
Supported targets
- admin.
abandoned-checkout-details. action. render - admin.
abandoned-checkout-details. block. render - admin.
catalog-details. action. render - admin.
catalog-details. block. render - admin.
collection-details. action. render - admin.
collection-details. block. render - admin.
collection-index. action. render - admin.
company-details. action. render - admin.
company-details. block. render - admin.
company-location-details. block. render - admin.
customer-details. action. render - admin.
customer-details. block. render - admin.
customer-index. action. render - admin.
customer-index. selection-action. render - admin.
customer-segment-details. action. render - admin.
discount-details. action. render - admin.
discount-details. function-settings. render - admin.
discount-index. action. render - admin.
draft-order-details. action. render - admin.
draft-order-details. block. render - admin.
draft-order-index. action. render - admin.
draft-order-index. selection-action. render - admin.
gift-card-details. action. render - admin.
gift-card-details. block. render - admin.
order-details. action. render - admin.
order-details. block. render - admin.
order-details. print-action. render - admin.
order-fulfilled-card. action. render - admin.
order-index. action. render - admin.
order-index. selection-action. render - admin.
order-index. selection-print-action. render - admin.
product-details. action. render - admin.
product-details. block. render - admin.
product-details. configuration. render - admin.
product-details. print-action. render - admin.
product-details. reorder. render - admin.
product-index. action. render - admin.
product-index. selection-action. render - admin.
product-index. selection-print-action. render - admin.
product-purchase-option. action. render - admin.
product-variant-details. action. render - admin.
product-variant-details. block. render - admin.
product-variant-details. configuration. render - admin.
product-variant-purchase-option. action. render - admin.
settings. order-routing-rule. render - admin.
settings. validation. render
Supported targets
- admin.
abandoned-checkout-details. action. render - admin.
abandoned-checkout-details. block. render - admin.
catalog-details. action. render - admin.
catalog-details. block. render - admin.
collection-details. action. render - admin.
collection-details. block. render - admin.
collection-index. action. render - admin.
company-details. action. render - admin.
company-details. block. render - admin.
company-location-details. block. render - admin.
customer-details. action. render - admin.
customer-details. block. render - admin.
customer-index. action. render - admin.
customer-index. selection-action. render - admin.
customer-segment-details. action. render - admin.
discount-details. action. render - admin.
discount-details. function-settings. render - admin.
discount-index. action. render - admin.
draft-order-details. action. render - admin.
draft-order-details. block. render - admin.
draft-order-index. action. render - admin.
draft-order-index. selection-action. render - admin.
gift-card-details. action. render - admin.
gift-card-details. block. render - admin.
order-details. action. render - admin.
order-details. block. render - admin.
order-details. print-action. render - admin.
order-fulfilled-card. action. render - admin.
order-index. action. render - admin.
order-index. selection-action. render - admin.
order-index. selection-print-action. render - admin.
product-details. action. render - admin.
product-details. block. render - admin.
product-details. configuration. render - admin.
product-details. print-action. render - admin.
product-details. reorder. render - admin.
product-index. action. render - admin.
product-index. selection-action. render - admin.
product-index. selection-print-action. render - admin.
product-purchase-option. action. render - admin.
product-variant-details. action. render - admin.
product-variant-details. block. render - admin.
product-variant-details. configuration. render - admin.
product-variant-purchase-option. action. render - admin.
settings. order-routing-rule. render - admin.
settings. validation. render
Anchor to PropertiesProperties
Props for the Select component, a form control that lets the user choose one value from a predefined list of options presented in a dropdown menu.
- Anchor to labellabellabelstringstringrequiredrequired
The visible label displayed above the select field. This label is also used by assistive technologies to describe the field.
- Anchor to optionsoptionsoptions(OptionDescription | OptionGroupDescription)[](OptionDescription | OptionGroupDescription)[]requiredrequired
The options a user can select from, provided as an array of
orobjects. Each option requires alabelandvalue.- Anchor to disableddisableddisabledbooleanboolean
Whether the select is disabled. When
true, the field can't be interacted with and appears in a dimmed state.- Anchor to errorerrorerrorstringstring
An error message to display beneath the field. When set, the field receives a specific stylistic treatment to communicate a problem that needs to be resolved immediately.
- Anchor to idididstringstring
A unique identifier for the field. When no
idis set, a globally unique value will be used instead.- Anchor to namenamenamestringstring
An identifier for the field that is unique within the nearest containing Form component. This value is used when submitting the form data.
- Anchor to onBluronBluronBlur() => void() => void
A callback that fires when the field loses focus. Use this to trigger validation or other side effects when the user moves away from the select.
- Anchor to onChangeonChangeonChange(value: string) => void(value: string) => void
A callback that fires whenever the selected option changes. The callback receives the string
valueof the newly selected option. This component is controlled, so you must store this value in state and reflect it back in thevalueprop.- Anchor to onFocusonFocusonFocus() => void() => void
A callback that fires when the field receives focus. Use this to trigger side effects when the user interacts with the select.
- Anchor to placeholderplaceholderplaceholderstringstring
A short hint that describes the expected value of the field. The placeholder is displayed when no
valueis set, giving the user guidance on what to select.- Anchor to readOnlyreadOnlyreadOnlybooleanboolean
Whether the field is read-only. When
true, the current value can't be changed by the user but the field remains focusable and its value is still included in form submissions.- Anchor to requiredrequiredrequiredbooleanboolean
Whether the field requires a value. This adds semantic meaning to the field for assistive technologies, but it won't cause an error to appear automatically. If you want to present an error when this field is empty, use the
errorprop.- Anchor to valuevaluevaluestringstring
The currently selected value. This should match the
valueproperty of one of the items in theoptionsarray. When not set, the value defaults to an empty string, which displays theplaceholdertext as the selected value.
OptionDescription
Describes a single selectable option when using the `options` prop on a Select component.
- disabled
Whether this option is disabled. When `true`, the option appears dimmed and can't be selected by the user.
boolean - label
The text displayed to the user for this option.
string - value
The value that will be passed to the select's `onChange` callback when this option is selected.
string
OptionGroupDescription
Describes a group of related options when using the `options` prop on a Select component. Groups display a non-selectable heading label above their nested options.
- disabled
Whether all options within this group are disabled. When `true`, none of the options in the group can be selected.
boolean - label
The visible label for this group of options. It's displayed as a non-selectable heading above the group's options.
string - options
The selectable options within this group. Each option requires a `label` and `value`.
OptionDescription[]
Anchor to ExamplesExamples
Anchor to Assign warehouse locationAssign warehouse location
Assign a product to a warehouse location from a dropdown of four regions. This example uses Select with four warehouse options, and a Button that assigns the warehouse and closes the modal.
Assign warehouse location
 that assigns the warehouse and closes the modal.](https://cdn.shopify.com/shopifycloud/shopify-dev/production/assets/assets/images/templated-apis-screenshots/admin-extensions/2025-07/select-default-PvnxNkRy.png)
Assign warehouse location
React
import {useState} from 'react';
import {reactExtension, useApi, Select, Button, BlockStack} from '@shopify/ui-extensions-react/admin';
function App() {
const {data, close} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;
const [warehouse, setWarehouse] = useState('');
return (
<BlockStack>
<Select
label="Assign warehouse"
name="warehouse"
value={warehouse}
options={[
{label: 'East Coast — New York', value: 'nyc'},
{label: 'West Coast — Los Angeles', value: 'lax'},
{label: 'Central — Chicago', value: 'chi'},
{label: 'International — London', value: 'lon'},
]}
onChange={setWarehouse}
/>
<Button
variant="primary"
onPress={async () => {
await fetch('/api/products/warehouse', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, warehouse}),
});
close();
}}
>
Assign warehouse
</Button>
</BlockStack>
);
}
export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);TS
import {extension, Select, Button, BlockStack} from '@shopify/ui-extensions/admin';
export default extension(
'admin.product-details.action.render',
(root, api) => {
const {data, close} = api;
const productId = data.selected[0]?.id;
let warehouse = '';
const stack = root.createComponent(BlockStack);
const field = root.createComponent(Select, {
label: 'Assign warehouse',
name: 'warehouse',
options: [
{label: 'East Coast — New York', value: 'nyc'},
{label: 'West Coast — Los Angeles', value: 'lax'},
{label: 'Central — Chicago', value: 'chi'},
{label: 'International — London', value: 'lon'},
],
onChange: (value) => {
warehouse = value;
},
});
const saveButton = root.createComponent(
Button,
{
variant: 'primary',
onPress: async () => {
await fetch('/api/products/warehouse', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, warehouse}),
});
close();
},
},
'Assign warehouse',
);
stack.appendChild(field);
stack.appendChild(saveButton);
root.appendChild(stack);
},
);Anchor to Add placeholder prompt textAdd placeholder prompt text
Guide merchants to make a selection by adding a placeholder that appears before any option is chosen. This example uses a placeholder message in a product classification dropdown, making it clear that a selection is expected.
Add placeholder prompt text
React
import {reactExtension, Select, BlockStack, Text} from '@shopify/ui-extensions-react/admin';
function App() {
return (
<BlockStack>
<Text fontWeight="bold">Product classification</Text>
<Select
label="Product category"
name="category"
placeholder="Select a category…"
options={[
{label: 'Electronics', value: 'electronics'},
{label: 'Apparel', value: 'apparel'},
{label: 'Home & Garden', value: 'home-garden'},
{label: 'Health & Beauty', value: 'health-beauty'},
{label: 'Food & Beverage', value: 'food-beverage'},
]}
/>
</BlockStack>
);
}
export default reactExtension(
'admin.product-details.block.render',
() => <App />,
);TS
import {extension, Select, BlockStack, Text} from '@shopify/ui-extensions/admin';
export default extension(
'admin.product-details.block.render',
(root) => {
const stack = root.createComponent(BlockStack);
const heading = root.createComponent(
Text,
{fontWeight: 'bold'},
'Product classification',
);
const field = root.createComponent(Select, {
label: 'Product category',
name: 'category',
placeholder: 'Select a category…',
options: [
{label: 'Electronics', value: 'electronics'},
{label: 'Apparel', value: 'apparel'},
{label: 'Home & Garden', value: 'home-garden'},
{label: 'Health & Beauty', value: 'health-beauty'},
{label: 'Food & Beverage', value: 'food-beverage'},
],
});
stack.appendChild(heading);
stack.appendChild(field);
root.appendChild(stack);
},
);Anchor to Validate required selection on submitValidate required selection on submit
Validate that a required select field has a value before submission using the error prop. This example shows an inline error when merchants attempt to save without choosing a shipping class, preventing incomplete data from reaching your backend.
Validate required selection on submit
React
import {useState} from 'react';
import {reactExtension, useApi, Select, Button, BlockStack} from '@shopify/ui-extensions-react/admin';
function App() {
const {data, close} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;
const [shippingClass, setShippingClass] = useState('');
const [error, setError] = useState(undefined);
return (
<BlockStack>
<Select
label="Shipping class"
name="shippingClass"
required
value={shippingClass}
error={error}
options={[
{label: 'Standard (5-7 days)', value: 'standard'},
{label: 'Express (2-3 days)', value: 'express'},
{label: 'Overnight', value: 'overnight'},
{label: 'Freight', value: 'freight'},
]}
onChange={(value) => {
setShippingClass(value);
setError(undefined);
}}
/>
<Button
variant="primary"
onPress={async () => {
if (!shippingClass) {
setError('Please select a shipping class');
return;
}
await fetch('/api/products/shipping-class', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, shippingClass}),
});
close();
}}
>
Save shipping class
</Button>
</BlockStack>
);
}
export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);TS
import {extension, Select, Button, BlockStack} from '@shopify/ui-extensions/admin';
export default extension(
'admin.product-details.action.render',
(root, api) => {
const {data, close} = api;
const productId = data.selected[0]?.id;
let shippingClass = '';
const stack = root.createComponent(BlockStack);
const field = root.createComponent(Select, {
label: 'Shipping class',
name: 'shippingClass',
required: true,
options: [
{label: 'Standard (5-7 days)', value: 'standard'},
{label: 'Express (2-3 days)', value: 'express'},
{label: 'Overnight', value: 'overnight'},
{label: 'Freight', value: 'freight'},
],
onChange: (value) => {
shippingClass = value;
field.updateProps({error: undefined});
},
});
const saveButton = root.createComponent(
Button,
{
variant: 'primary',
onPress: async () => {
if (!shippingClass) {
field.updateProps({error: 'Please select a shipping class'});
return;
}
await fetch('/api/products/shipping-class', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, shippingClass}),
});
close();
},
},
'Save shipping class',
);
stack.appendChild(field);
stack.appendChild(saveButton);
root.appendChild(stack);
},
);Anchor to Best practicesBest practices
- Use Select for four or more options: When there are only two or three options, use a ChoiceList with radio buttons instead because all options are visible without interaction.
- Order options logically: Arrange options in an order that makes sense to merchants, such as alphabetically, by popularity, or by a natural sequence. Place the most common choice first when there's no inherent order.
- Use option groups for long lists: When the list has many options, group related items using option groups to make scanning easier.
- Write a clear label: The required
labelprop describes what the selection controls. Use specific labels like "Country" or "Sort by". - Use a placeholder when no default makes sense: Set the
placeholderprop (like "Select a country") when there's no obvious default value. This communicates that the merchant needs to make a choice.
Anchor to LimitationsLimitations
- Select supports single selection only. For multi-selection, use a ChoiceList with
multipleset totrue. - The dropdown options can't be customized with colors, icons, or rich content.
- Select doesn't support search or filtering within the options list. For large option sets, use option groups to help merchants find items faster.
- Dynamic loading of options as the user scrolls isn't supported.