Skip to main content

Button

The button component triggers actions or events, such as submitting forms, opening dialogs, or navigating to other pages. Use button to let users perform specific tasks or initiate interactions throughout the interface.

Buttons support various visual styles, tones, and interaction patterns to communicate intent and hierarchy. They can also function as links, guiding users to internal or external destinations. For navigation-focused interactions within text, use link. For grouping multiple related buttons, use button group.


Configure the following properties on the button component.

Anchor to disabled
disabled
boolean
Default: false
required

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

"" | "replace" | "search" | "split" | "link" | "edit" | "info" | "incomplete" | "complete" | "product" | "variant" | "collection" | "select" | "color" | "money" | "order" | "code" | "adjust" | "affiliate" | "airplane" | "alert-bubble" | "alert-circle" | "alert-diamond" | "alert-location" | "alert-octagon" | "alert-octagon-filled" | "alert-triangle" | "alert-triangle-filled" | "app-extension" | "apps" | "archive" | "arrow-down" | "arrow-down-circle" | "arrow-down-right" | "arrow-left" | "arrow-left-circle" | "arrow-right" | "arrow-right-circle" | "arrow-up" | "arrow-up-circle" | "arrow-up-right" | "arrows-in-horizontal" | "arrows-out-horizontal" | "asterisk" | "attachment" | "automation" | "backspace" | "bag" | "bank" | "barcode" | "battery-low" | "bill" | "blank" | "blog" | "bolt" | "bolt-filled" | "book" | "book-open" | "bug" | "bullet" | "business-entity" | "button" | "button-press" | "calculator" | "calendar" | "calendar-check" | "calendar-compare" | "calendar-list" | "calendar-time" | "camera" | "camera-flip" | "caret-down" | "caret-left" | "caret-right" | "caret-up" | "cart" | "cart-abandoned" | "cart-discount" | "cart-down" | "cart-filled" | "cart-sale" | "cart-send" | "cart-up" | "cash-dollar" | "cash-euro" | "cash-pound" | "cash-rupee" | "cash-yen" | "catalog-product" | "categories" | "channels" | "chart-cohort" | "chart-donut" | "chart-funnel" | "chart-histogram-first" | "chart-histogram-first-last" | "chart-histogram-flat" | "chart-histogram-full" | "chart-histogram-growth" | "chart-histogram-last" | "chart-histogram-second-last" | "chart-horizontal" | "chart-line" | "chart-popular" | "chart-stacked" | "chart-vertical" | "chat" | "chat-new" | "chat-referral" | "check" | "check-circle" | "check-circle-filled" | "checkbox" | "chevron-down" | "chevron-down-circle" | "chevron-left" | "chevron-left-circle" | "chevron-right" | "chevron-right-circle" | "chevron-up" | "chevron-up-circle" | "circle" | "circle-dashed" | "clipboard" | "clipboard-check" | "clipboard-checklist" | "clock" | "clock-list" | "clock-revert" | "code-add" | "collection-featured" | "collection-list" | "collection-reference" | "color-none" | "compass" | "compose" | "confetti" | "connect" | "content" | "contract" | "corner-pill" | "corner-round" | "corner-square" | "credit-card" | "credit-card-cancel" | "credit-card-percent" | "credit-card-reader" | "credit-card-reader-chip" | "credit-card-reader-tap" | "credit-card-secure" | "credit-card-tap-chip" | "crop" | "currency-convert" | "cursor" | "cursor-banner" | "cursor-option" | "data-presentation" | "data-table" | "database" | "database-add" | "database-connect" | "delete" | "delivered" | "delivery" | "desktop" | "disabled" | "disabled-filled" | "discount" | "discount-add" | "discount-automatic" | "discount-code" | "discount-remove" | "dns-settings" | "dock-floating" | "dock-side" | "domain" | "domain-landing-page" | "domain-new" | "domain-redirect" | "download" | "drag-drop" | "drag-handle" | "drawer" | "duplicate" | "email" | "email-follow-up" | "email-newsletter" | "empty" | "enabled" | "enter" | "envelope" | "envelope-soft-pack" | "eraser" | "exchange" | "exit" | "export" | "external" | "eye-check-mark" | "eye-dropper" | "eye-dropper-list" | "eye-first" | "eyeglasses" | "fav" | "favicon" | "file" | "file-list" | "filter" | "filter-active" | "flag" | "flip-horizontal" | "flip-vertical" | "flower" | "folder" | "folder-add" | "folder-down" | "folder-remove" | "folder-up" | "food" | "foreground" | "forklift" | "forms" | "games" | "gauge" | "geolocation" | "gift" | "gift-card" | "git-branch" | "git-commit" | "git-repository" | "globe" | "globe-asia" | "globe-europe" | "globe-lines" | "globe-list" | "graduation-hat" | "grid" | "hashtag" | "hashtag-decimal" | "hashtag-list" | "heart" | "hide" | "hide-filled" | "home" | "home-filled" | "icons" | "identity-card" | "image" | "image-add" | "image-alt" | "image-explore" | "image-magic" | "image-none" | "image-with-text-overlay" | "images" | "import" | "in-progress" | "incentive" | "incoming" | "info-filled" | "inheritance" | "inventory" | "inventory-edit" | "inventory-list" | "inventory-transfer" | "inventory-updated" | "iq" | "key" | "keyboard" | "keyboard-filled" | "keyboard-hide" | "keypad" | "label-printer" | "language" | "language-translate" | "layout-block" | "layout-buy-button" | "layout-buy-button-horizontal" | "layout-buy-button-vertical" | "layout-column-1" | "layout-columns-2" | "layout-columns-3" | "layout-footer" | "layout-header" | "layout-logo-block" | "layout-popup" | "layout-rows-2" | "layout-section" | "layout-sidebar-left" | "layout-sidebar-right" | "lightbulb" | "link-list" | "list-bulleted" | "list-bulleted-filled" | "list-numbered" | "live" | "live-critical" | "live-none" | "location" | "location-none" | "lock" | "map" | "markets" | "markets-euro" | "markets-rupee" | "markets-yen" | "maximize" | "measurement-size" | "measurement-size-list" | "measurement-volume" | "measurement-volume-list" | "measurement-weight" | "measurement-weight-list" | "media-receiver" | "megaphone" | "mention" | "menu" | "menu-filled" | "menu-horizontal" | "menu-vertical" | "merge" | "metafields" | "metaobject" | "metaobject-list" | "metaobject-reference" | "microphone" | "microphone-muted" | "minimize" | "minus" | "minus-circle" | "mobile" | "money-none" | "money-split" | "moon" | "nature" | "note" | "note-add" | "notification" | "number-one" | "order-batches" | "order-draft" | "order-filled" | "order-first" | "order-fulfilled" | "order-repeat" | "order-unfulfilled" | "orders-status" | "organization" | "outdent" | "outgoing" | "package" | "package-cancel" | "package-fulfilled" | "package-on-hold" | "package-reassign" | "package-returned" | "page" | "page-add" | "page-attachment" | "page-clock" | "page-down" | "page-heart" | "page-list" | "page-reference" | "page-remove" | "page-report" | "page-up" | "pagination-end" | "pagination-start" | "paint-brush-flat" | "paint-brush-round" | "paper-check" | "partially-complete" | "passkey" | "paste" | "pause-circle" | "payment" | "payment-capture" | "payout" | "payout-dollar" | "payout-euro" | "payout-pound" | "payout-rupee" | "payout-yen" | "person" | "person-add" | "person-exit" | "person-filled" | "person-list" | "person-lock" | "person-remove" | "person-segment" | "personalized-text" | "phablet" | "phone" | "phone-down" | "phone-down-filled" | "phone-in" | "phone-out" | "pin" | "pin-remove" | "plan" | "play" | "play-circle" | "plus" | "plus-circle" | "plus-circle-down" | "plus-circle-filled" | "plus-circle-up" | "point-of-sale" | "point-of-sale-register" | "price-list" | "print" | "product-add" | "product-cost" | "product-filled" | "product-list" | "product-reference" | "product-remove" | "product-return" | "product-unavailable" | "profile" | "profile-filled" | "question-circle" | "question-circle-filled" | "radio-control" | "receipt" | "receipt-dollar" | "receipt-euro" | "receipt-folded" | "receipt-paid" | "receipt-pound" | "receipt-refund" | "receipt-rupee" | "receipt-yen" | "receivables" | "redo" | "referral-code" | "refresh" | "remove-background" | "reorder" | "replay" | "reset" | "return" | "reward" | "rocket" | "rotate-left" | "rotate-right" | "sandbox" | "save" | "savings" | "scan-qr-code" | "search-add" | "search-list" | "search-recent" | "search-resource" | "send" | "settings" | "share" | "shield-check-mark" | "shield-none" | "shield-pending" | "shield-person" | "shipping-label" | "shipping-label-cancel" | "shopcodes" | "slideshow" | "smiley-happy" | "smiley-joy" | "smiley-neutral" | "smiley-sad" | "social-ad" | "social-post" | "sort" | "sort-ascending" | "sort-descending" | "sound" | "sports" | "star" | "star-circle" | "star-filled" | "star-half" | "star-list" | "status" | "status-active" | "stop-circle" | "store" | "store-import" | "store-managed" | "store-online" | "sun" | "table" | "table-masonry" | "tablet" | "target" | "tax" | "team" | "text" | "text-align-center" | "text-align-left" | "text-align-right" | "text-block" | "text-bold" | "text-color" | "text-font" | "text-font-list" | "text-grammar" | "text-in-columns" | "text-in-rows" | "text-indent" | "text-indent-remove" | "text-italic" | "text-quote" | "text-title" | "text-underline" | "text-with-image" | "theme" | "theme-edit" | "theme-store" | "theme-template" | "three-d-environment" | "thumbs-down" | "thumbs-up" | "tip-jar" | "toggle-off" | "toggle-on" | "transaction" | "transaction-fee-add" | "transaction-fee-dollar" | "transaction-fee-euro" | "transaction-fee-pound" | "transaction-fee-rupee" | "transaction-fee-yen" | "transfer" | "transfer-in" | "transfer-internal" | "transfer-out" | "truck" | "undo" | "unknown-device" | "unlock" | "upload" | "variant-list" | "video" | "video-list" | "view" | "viewport-narrow" | "viewport-short" | "viewport-tall" | "viewport-wide" | "wallet" | "wand" | "watch" | "wifi" | "work" | "work-list" | "wrench" | "x" | "x-circle" | "x-circle-filled"
required

An icon displayed inside the button, typically positioned before the button text. Use icons to help users quickly identify the button's action or to improve scannability. Accepts any icon name from the icon library or a custom string identifier.

Anchor to loading
loading
boolean
Default: false
required

Whether to replace the button content with a loading indicator while a background action is being performed.

This also disables the button component.

Anchor to variant
variant
"auto" | "primary" | "secondary" | "tertiary"
Default: 'auto'
required

The visual appearance of the button component.

  • auto: The variant is automatically determined by the button component's context.
  • primary: High emphasis button for the primary action on the page. Should be used sparingly.
  • secondary: Medium emphasis button for secondary actions.
  • tertiary: Low emphasis button for less important actions.
"critical" | "auto" | "neutral"
Default: 'auto'
required

The semantic meaning and color treatment of the component.

  • critical: Urgent problems or destructive actions.
  • auto: Automatically determined based on context.
  • neutral: General information without specific intent.
Anchor to target
target
"auto" | | "_blank" | "_self" | "_parent" | "_top"
Default: 'auto'
required

The browsing context where the linked URL should be displayed.

  • auto: The target is automatically determined based on the origin of the URL.
  • _blank: Opens the URL in a new window or tab.
  • _self: Opens the URL in the same browsing context as the current one.
  • _parent: Opens the URL in the parent browsing context of the current one. If there is no parent, behaves as _self.
  • _top: Opens the URL in the topmost browsing context (the highest ancestor of the current one). If there is no ancestor, behaves as _self.
string
required

The URL to navigate to when clicked. The click event fires first, then navigation occurs. If commandFor is also set, the command executes instead of navigation.

Anchor to download
download
string
required

Prompts the browser to download the linked URL rather than navigate to it. When set, the value specifies the suggested filename for the downloaded file.

The filename suggestion is only respected for same-origin URLs, blob:, and data: schemes. Cross-origin URLs can still trigger downloads, but browsers might ignore the suggested filename.

Learn more about the download attribute.

"button" | "reset" | "submit"
Default: 'button'
required

The behavior of the button component.

  • button: Used to indicate the component acts as a button, meaning it has no default action.
  • reset: Used to indicate the component acts as a reset button, meaning it resets the closest form (returning fields to their default values).
  • submit: Used to indicate the component acts as a submit button, meaning it submits the closest form.

This property is ignored if the component supports href or commandFor/command and one of them is set.

Anchor to accessibilityLabel
accessibilityLabel
string
required

A label that describes the purpose or content of the component for assistive technologies like screen readers. Use this to provide additional context when the visible content alone doesn't clearly convey the component's purpose.

Anchor to command
command
'--auto' | '--show' | '--hide' | '--toggle'
Default: '--auto'
required

The action that command should take when this component is activated.

  • --auto: A default action for the target component.
  • --show: Shows the target component.
  • --hide: Hides the target component.
  • --toggle: Toggles the visibility of the target component.
Anchor to commandFor
commandFor
string
required

The component that commandFor should act on when this component is activated.

Anchor to interestFor
interestFor
string
required

The ID of the component to show when users hover over or focus on this component. Use this to connect interactive components to popovers or tooltips that provide additional context or information.

The button component provides event callbacks for handling user interactions. Learn more about handling events.

<typeof tagName> | null
required

A callback fired when the button loses focus.

Learn more about the blur event.

Anchor to click
click
<typeof tagName> | null
required

A callback fired when the button is clicked.

Learn more about the click event.

Anchor to focus
focus
<typeof tagName> | null
required

A callback fired when the button receives focus.

Learn more about the focus event.

The button component supports slots for additional content placement within the component. Learn more about using slots.

Anchor to children
children
HTMLElement

The label text or elements displayed inside the button component, describing the action that will be performed when clicked.


Create a button with a text label to let merchants trigger an action. This example shows the basic button component with default styling.

Preview

html

<s-button>Save</s-button>

Anchor to Add primary and secondary buttonsAdd primary and secondary buttons

Create buttons for actions like saving, creating, or navigating. This example shows primary and secondary buttons with clear, action-oriented labels.

Preview

html

<s-button variant="primary">Add Product</s-button>
<s-button variant="secondary">Save Theme</s-button>

Anchor to Set visual emphasis with variantsSet visual emphasis with variants

Use variants to establish a clear visual hierarchy between primary, secondary, and supplementary actions. This example shows all four variant options: primary, secondary, tertiary, and auto.

Preview

html

<s-stack direction="inline" gap="base">
<s-button variant="primary">Primary</s-button>
<s-button variant="secondary">Secondary</s-button>
<s-button variant="tertiary">Tertiary</s-button>
<s-button variant="auto">Auto</s-button>
</s-stack>

Anchor to Communicate intent with tonesCommunicate intent with tones

Apply tones to signal the purpose and potential impact of an action through color. This example shows critical tone for destructive actions, neutral tone for less prominent actions, and the default auto tone.

Preview

html

<s-stack direction="inline" gap="base">
<s-button tone="critical">Delete</s-button>
<s-button tone="neutral">Save draft</s-button>
<s-button>Continue</s-button>
</s-stack>

Anchor to Add an icon alongside a text labelAdd an icon alongside a text label

Combine an icon with a text label to help merchants identify what a button does. This example shows a button with both a text label and an icon to reinforce the action.

Preview

html

<s-button icon="plus">Add product</s-button>

Anchor to Create compact icon-only buttons for toolbarsCreate compact icon-only buttons for toolbars

Create icon-only buttons to save space in dense interfaces like toolbars and action bars. This example shows multiple icon-only buttons with an accessibilityLabel for screen reader support.

Preview

html

<s-stack direction="inline" gap="base">
<s-button
icon="duplicate"
variant="tertiary"
accessibilityLabel="Duplicate product"
></s-button>
<s-button
icon="view"
variant="tertiary"
accessibilityLabel="Preview product"
></s-button>
<s-button
icon="menu-horizontal"
variant="tertiary"
accessibilityLabel="More actions"
></s-button>
</s-stack>

Anchor to Show loading feedback during async operationsShow loading feedback during async operations

Add a loading state to prevent duplicate submissions and reassure merchants that an action is being processed. This example shows buttons with the loading prop across different variants.

Preview

html

<!-- Product save operation -->
<s-button loading variant="primary">Saving product...</s-button>

<!-- Bulk inventory update -->
<s-button loading variant="secondary">Updating 247 variants...</s-button>

<!-- Order fulfillment -->
<s-button loading tone="neutral">Processing shipment...</s-button>

Anchor to Disable buttons and submit formsDisable buttons and submit forms

Disable buttons to prevent interaction when prerequisites are not met, and set type to submit to integrate with HTML forms. This example shows a disabled button alongside a submit button.

Preview

html

<s-stack direction="inline" gap="base">
<s-button disabled>Save draft</s-button>
<s-button type="submit" variant="primary">Save product</s-button>
</s-stack>

Anchor to Use buttons for navigation and downloadsUse buttons for navigation and downloads

Set the href property to make buttons navigate like links while maintaining button styling. This example shows internal navigation, opening external URLs in new tabs, and triggering file downloads.

Preview

html

<s-stack direction="inline" gap="base">
<s-button href="javascript:void(0)">View products</s-button>
<s-button href="javascript:void(0)" target="_blank">Help docs</s-button>
<s-button href="javascript:void(0)" download="sales-report.csv">
Export data
</s-button>
</s-stack>

Anchor to Confirm destructive actions with critical toneConfirm destructive actions with critical tone

Pair a cancel button with a critical-toned action button to help merchants avoid accidental destructive operations. This example shows a confirmation pattern for deleting a resource.

Preview

html

<s-stack direction="inline" gap="base">
<s-button variant="secondary">Cancel</s-button>
<s-button variant="primary" tone="critical">Delete variant</s-button>
</s-stack>

Anchor to Trigger actions on other componentsTrigger actions on other components

Use commandFor to connect a button to another component by ID, triggering built-in actions like toggling a popover or showing a modal. This example shows a button that opens a popover with a list of additional actions.

Preview

html

<s-button commandFor="actions-popover">More actions</s-button>

<s-popover id="actions-popover">
<s-stack direction="block">
<s-button variant="tertiary">Export products</s-button>
<s-button variant="tertiary">Import products</s-button>
<s-button variant="tertiary">Print labels</s-button>
</s-stack>
</s-popover>

  • Label buttons clearly: Use strong, actionable verbs that clearly and accurately describe the action (like Save, Edit, or Add tags). Write labels in sentence case and avoid unnecessary words and articles (like a, an, the). Don't use punctuation.
  • Use appropriate button tones: Apply established button tones appropriately. Use critical tone only for destructive actions that are difficult or impossible to undo. Match the tone to the action's impact and importance.
  • Establish clear hierarchy: Prioritize the most important actions to avoid confusion. Use primary buttons for main actions, secondary buttons for supporting actions, and tertiary buttons for supplementary actions.
  • Position consistently: Place buttons in consistent locations throughout the interface to create predictable interaction patterns.
  • Icon-only buttons: For icon-only buttons, always use accessibilityLabel to describe the action for screen reader users.

  • When using href for navigation, external URLs (domains outside Shopify admin) might be blocked or show security warnings depending on the extension context and merchant's browser security settings.
  • Setting loading={true} provides visual feedback and prevents form submission or multiple clicks. You must implement additional logic to debounce or disable the button action during async operations.
  • Icon-only buttons have a minimum touch target size but don't expand to fill available space. They maintain a fixed size based on the icon and padding, which might create layout inconsistencies if mixed with text buttons in the same container.
  • Disabled buttons (disabled={true}) are removed from the tab order and can't receive keyboard focus. If you disable a button temporarily (for example, while waiting for form validation), then provide visible text explaining why it's disabled. For async operations, use loading over disabled because loading communicates that an action is in progress.

Was this page helpful?