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.

Checkbox

The Checkbox component provides a binary toggle for a single option that merchants can turn on or off. Use it for boolean settings like agreeing to terms, enabling a feature, or opting into a notification.

For selecting from a group of related options, use ChoiceList.

Support
Targets (46)

Supported targets


Props for the Checkbox component, which renders a toggleable input that lets the merchant choose between a checked and unchecked state.

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 checked
checked
boolean
Default: false

Whether the checkbox is currently checked. This is a controlled prop, so you must update it in response to onChange to reflect the new state.

Anchor to disabled
disabled
boolean
Default: false

Whether the checkbox is disabled. When true, then the checkbox can't be interacted with and appears in a muted style to indicate it isn't available.

Anchor to error
error
string

An error message displayed below the checkbox. When set, the checkbox receives a specific visual treatment to indicate a problem that the merchant needs to resolve before continuing.

string

A unique identifier for the checkbox. When no id is set, a globally unique value is generated automatically.

Anchor to label
label
string

The text label displayed next to the checkbox. Use this to clearly describe what the checkbox controls.

string

An identifier for the checkbox that is unique within the nearest containing Form component. Use this to identify the checkbox's value when the form is submitted.

Anchor to onChange
onChange
(value: boolean) => void

A callback fired whenever the checkbox's checked state changes. The callback receives a boolean indicating the new checked state. Because this is a controlled component, you must store this value in state and reflect it back in the checked or value prop.

Anchor to value
value
boolean

Whether the checkbox is checked. This is an alias for checked and can be useful in form libraries that provide a normalized API for handling both boolean and string values. If both value and checked are set, then checked takes precedence.


Anchor to Toggle feature settingsToggle feature settings

Toggle automatic inventory sync on or off. This example uses Checkbox with a checked state, and a Button that saves the setting and closes the modal.

Toggle feature settings

Toggle automatic inventory sync on or off. This example uses `Checkbox` with a `checked` state, and a [Button](/docs/api/admin-extensions/2025-07/ui-components/actions/button) that saves the setting and closes the modal.

Toggle feature settings

import {useState} from 'react';
import {reactExtension, useApi, Checkbox, 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 [syncEnabled, setSyncEnabled] = useState(false);

return (
<BlockStack>
<Checkbox
label="Enable automatic inventory sync"
checked={syncEnabled}
onChange={setSyncEnabled}
/>
<Button
variant="primary"
onPress={async () => {
await fetch('/api/products/sync-settings', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, syncEnabled}),
});
close();
}}
>
Save settings
</Button>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
import {extension, Checkbox, 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 syncEnabled = false;

const stack = root.createComponent(BlockStack);

const checkbox = root.createComponent(Checkbox, {
label: 'Enable automatic inventory sync',
checked: syncEnabled,
onChange: (value) => {
syncEnabled = value;
},
});

const saveButton = root.createComponent(
Button,
{
variant: 'primary',
onPress: async () => {
await fetch('/api/products/sync-settings', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, syncEnabled}),
});
close();
},
},
'Save settings',
);

stack.appendChild(checkbox);
stack.appendChild(saveButton);
root.appendChild(stack);
},
);

Anchor to Validate required agreementValidate required agreement

Require merchants to agree to terms before connecting a service using the error prop for validation. This example shows an inline error when the merchant attempts to submit without checking the box, which requires explicit consent before proceeding.

Validate required agreement

import {useState} from 'react';
import {reactExtension, useApi, Checkbox, Button, BlockStack, Text} from '@shopify/ui-extensions-react/admin';

function App() {
const {close} = useApi('admin.product-details.action.render');
const [agreed, setAgreed] = useState(false);
const [error, setError] = useState(undefined);

return (
<BlockStack>
<Text fontWeight="bold">Terms of service</Text>
<Checkbox
label="I agree to the fulfillment provider terms of service"
checked={agreed}
error={error}
onChange={(value) => {
setAgreed(value);
setError(undefined);
}}
/>
<Button
variant="primary"
onPress={async () => {
if (!agreed) {
setError('You must agree to the terms before connecting');
return;
}
await fetch('/api/fulfillment/connect', {method: 'POST'});
close();
}}
>
Connect provider
</Button>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
import {extension, Checkbox, Button, BlockStack, Text} from '@shopify/ui-extensions/admin';

export default extension(
'admin.product-details.action.render',
(root, api) => {
const {close} = api;
let agreed = false;

const stack = root.createComponent(BlockStack);

const heading = root.createComponent(
Text,
{fontWeight: 'bold'},
'Terms of service',
);

const checkbox = root.createComponent(Checkbox, {
label: 'I agree to the fulfillment provider terms of service',
checked: agreed,
onChange: (value) => {
agreed = value;
checkbox.updateProps({error: undefined});
},
});

const connectButton = root.createComponent(
Button,
{
variant: 'primary',
onPress: async () => {
if (!agreed) {
checkbox.updateProps({error: 'You must agree to the terms before connecting'});
return;
}
await fetch('/api/fulfillment/connect', {method: 'POST'});
close();
},
},
'Connect provider',
);

stack.appendChild(heading);
stack.appendChild(checkbox);
stack.appendChild(connectButton);
root.appendChild(stack);
},
);

Anchor to Select multiple channel optionsSelect multiple channel options

Present multiple independent options as a group of checkboxes for channel publishing. This example renders three checkboxes (Online Store, Point of Sale, and Wholesale), letting merchants select any combination of sales channels for a product.

Select multiple channel options

import {useState} from 'react';
import {reactExtension, useApi, Checkbox, Button, BlockStack, Text} from '@shopify/ui-extensions-react/admin';

function App() {
const {data, close} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;
const [channels, setChannels] = useState({
online: true,
pos: false,
wholesale: false,
});

return (
<BlockStack>
<Text fontWeight="bold">Publish to channels</Text>
<Checkbox
label="Online Store"
checked={channels.online}
onChange={(value) => setChannels({...channels, online: value})}
/>
<Checkbox
label="Point of Sale"
checked={channels.pos}
onChange={(value) => setChannels({...channels, pos: value})}
/>
<Checkbox
label="Wholesale"
checked={channels.wholesale}
onChange={(value) => setChannels({...channels, wholesale: value})}
/>
<Button
variant="primary"
onPress={async () => {
await fetch('/api/products/channels', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, channels}),
});
close();
}}
>
Update channels
</Button>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
import {extension, Checkbox, Button, BlockStack, Text} 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;
const channels = {online: true, pos: false, wholesale: false};

const stack = root.createComponent(BlockStack);

const heading = root.createComponent(
Text,
{fontWeight: 'bold'},
'Publish to channels',
);

const onlineCheckbox = root.createComponent(Checkbox, {
label: 'Online Store',
checked: channels.online,
onChange: (value) => { channels.online = value; },
});

const posCheckbox = root.createComponent(Checkbox, {
label: 'Point of Sale',
checked: channels.pos,
onChange: (value) => { channels.pos = value; },
});

const wholesaleCheckbox = root.createComponent(Checkbox, {
label: 'Wholesale',
checked: channels.wholesale,
onChange: (value) => { channels.wholesale = value; },
});

const saveButton = root.createComponent(
Button,
{
variant: 'primary',
onPress: async () => {
await fetch('/api/products/channels', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, channels}),
});
close();
},
},
'Update channels',
);

stack.appendChild(heading);
stack.appendChild(onlineCheckbox);
stack.appendChild(posCheckbox);
stack.appendChild(wholesaleCheckbox);
stack.appendChild(saveButton);
root.appendChild(stack);
},
);

  • Use positive, clear labels: Write checkbox labels as positive statements that describe what happens when checked. For example, use "Send email notifications" instead of "Disable email notifications".
  • Use for independent choices: Each checkbox should control a single, independent setting. If options are mutually exclusive, use a ChoiceList with radio buttons instead.
  • Don't require checkboxes to be unchecked: Requiring that a checkbox must remain unchecked creates a confusing experience. Checkboxes should feel optional even when they are required for submission.

  • Checkbox doesn't support an indeterminate (mixed) state. It is either checked or unchecked.
  • The label prop only accepts a string. Rich content like links or formatted text inside the label isn't supported.
  • Checkbox has both checked and value props that serve the same purpose (value is an alias for checked). Use one or the other, not both, to avoid confusion.
  • Checkbox doesn't include a description or helper text prop. To add explanatory text below the checkbox, place a Text or Paragraph component adjacent to it.

Was this page helpful?