--- title: Button description: >- The button component triggers actions or events, such as submitting forms, opening dialogs, or navigating to other pages. Use buttons 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](/docs/api/app-home//web-components/actions/link). For grouping multiple related buttons, use [button group](/docs/api/app-home//web-components/actions/button-group). api_name: app-home source_url: html: 'https://shopify.dev/docs/api/app-home/web-components/actions/button' md: 'https://shopify.dev/docs/api/app-home/web-components/actions/button.md' --- # Button The button component triggers actions or events, such as submitting forms, opening dialogs, or navigating to other pages. Use buttons 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](https://shopify.dev/docs/api/app-home/web-components/actions/link). For grouping multiple related buttons, use [button group](https://shopify.dev/docs/api/app-home/web-components/actions/button-group). #### Use cases * **Form submission:** Create submit buttons for forms that save product configurations or settings. * **Primary actions:** Implement primary actions like "Save changes," "Create resource," or "Apply settings." * **Secondary actions:** Provide supporting actions such as "Cancel," "Reset," or "View details." * **Loading states:** Show loading indicators during API calls while preventing duplicate submissions. ## Properties Configure the following properties on the button component. * **accessibilityLabel** **string** 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. * **command** **'--auto' | '--show' | '--hide' | '--toggle'** **Default: '--auto'** The action that [command](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#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. * **commandFor** **string** The component that [commandFor](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#commandfor) should act on when this component is activated. * **disabled** **boolean** **Default: false** Whether the button is disabled, preventing it from being clicked or receiving focus. * **download** **string** 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](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download). * **href** **string** 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. * **icon** **"" | "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"** 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. * **interestFor** **string** 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. * **loading** **boolean** **Default: false** Whether to replace the button content with a loading indicator while a background action is being performed. This also disables the button component. * **target** **"auto" | AnyString | "\_blank" | "\_self" | "\_parent" | "\_top"** **Default: 'auto'** 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`. * **tone** **"critical" | "auto" | "neutral"** **Default: 'auto'** 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. * **type** **"button" | "reset" | "submit"** **Default: 'button'** 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. * **variant** **"auto" | "primary" | "secondary" | "tertiary"** **Default: 'auto'** 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. ### AnyString A utility type that enables autocomplete for specific string literals while still accepting any string value. By intersecting \`string\` with an empty object type, this prevents TypeScript from widening literal types, preserving IDE suggestions for known values while maintaining flexibility for custom strings. ```ts string & {} ``` ## Events The button component provides event callbacks for handling user interactions. Learn more about [handling events](https://shopify.dev/docs/api/app-ui/using-web-components#handling-events). * **blur** **CallbackEventListener\ | null** A callback fired when the button loses focus. Learn more about the [blur event](https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event). * **click** **CallbackEventListener\ | null** A callback fired when the button is clicked. Learn more about the [click event](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event). * **focus** **CallbackEventListener\ | null** A callback fired when the button receives focus. Learn more about the [focus event](https://developer.mozilla.org/en-US/docs/Web/API/Element/focus_event). ### CallbackEventListener A function that handles events from UI components. This type represents an event listener callback that receives a \`CallbackEvent\` with a strongly-typed \`currentTarget\`. Use this for component event handlers like \`click\`, \`focus\`, \`blur\`, and other DOM events. ```ts (EventListener & { (event: CallbackEvent): void; }) | null ``` ### CallbackEvent An event object with a strongly-typed \`currentTarget\` property that references the specific HTML element that triggered the event. This type extends the standard DOM \`Event\` interface and ensures type safety when accessing the element that fired the event. ```ts Event & { currentTarget: HTMLElementTagNameMap[T]; } ``` ## Slots The button component supports slots for additional content placement within the component. Learn more about [using slots](https://shopify.dev/docs/api/app-ui/using-web-components#slots). * **children** **HTMLElement** The label text or elements displayed inside the button component, describing the action that will be performed when clicked. Examples ### Examples * #### Add a basic button ##### Description Create a button with a text label to let merchants trigger an action. This example shows the basic button component with default styling. ##### html ```html Save ``` * #### Add primary and secondary buttons ##### Description Create buttons for actions like saving, creating, or navigating. This example shows primary and secondary buttons with clear, action-oriented labels. ##### html ```html Add Product Save Theme ``` * #### Set visual emphasis with variants ##### Description 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. ##### html ```html Primary Secondary Tertiary Auto ``` * #### Communicate intent with tones ##### Description 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. ##### html ```html Delete Save draft Continue ``` * #### Add an icon alongside a text label ##### Description 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. ##### html ```html Add product ``` * #### Create compact icon-only buttons for toolbars ##### Description 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. ##### html ```html ``` * #### Show loading feedback during async operations ##### Description 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. ##### html ```html Saving product... Updating 247 variants... Processing shipment... ``` * #### Disable buttons and submit forms ##### Description 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. ##### html ```html Save draft Save product ``` * #### Use buttons for navigation and downloads ##### Description 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. ##### html ```html View products Help docs Export data ``` * #### Confirm destructive actions with critical tone ##### Description 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. ##### html ```html Cancel Delete variant ``` * #### Trigger actions on other components ##### Description 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. ##### html ```html More actions Export products Import products Print labels ``` ## Best practices * **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. ## Limitations * 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.