Skip to content

Instantly share code, notes, and snippets.

@quantizor
Created February 26, 2025 20:32
Show Gist options
  • Save quantizor/dddbc02f37e727c7e61eec43c90e4719 to your computer and use it in GitHub Desktop.
Save quantizor/dddbc02f37e727c7e61eec43c90e4719 to your computer and use it in GitHub Desktop.
Shopify "Buy Button" JS Types
// Derived these from looking through their docs and some of the source code
// Type definitions for Shopify Buy Button SDK
// Based on https://shopify.github.io/buy-button-js/
declare global {
interface Window {
/**
* The global ShopifyBuy object provided by the Shopify Buy Button SDK.
* Available after loading the SDK script.
* @see https://shopify.github.io/buy-button-js/
*/
ShopifyBuy: {
/**
* Creates a new ShopifyBuy client instance for interacting with a specific store.
* @param config Configuration object with store credentials
* @returns A client instance for the specified store
*/
buildClient(config: {
domain: string
storefrontAccessToken: string
}): ShopifyBuyClient
/**
* The UI namespace that provides methods for creating and managing Buy Button components.
*/
UI: {
/**
* Initializes the UI library with a client.
* @param client ShopifyBuyClient instance
* @returns Promise that resolves with the UI instance
*/
onReady(client: ShopifyBuyClient): Promise<ShopifyBuyUI>
}
}
}
}
/**
* Client interface for the Shopify Buy SDK.
* Provides methods for interacting with Shopify's Storefront API.
* @see https://www.npmjs.com/package/shopify-buy
*/
interface ShopifyBuyClient {
/**
* Client configuration details
*/
config: {
domain: string
storefrontAccessToken: string
}
/**
* Checkout resource for creating and manipulating checkout objects.
* Used for cart functionality, line item management, and completing purchases.
*/
checkout: {
/**
* Creates a new empty checkout.
* @returns Promise that resolves with the new checkout
*/
create(): Promise<any>
/**
* Fetches an existing checkout by its ID.
* @param checkoutId ID of the checkout to fetch
* @returns Promise that resolves with the checkout
*/
fetch(checkoutId: string): Promise<any>
/**
* Updates attributes on an existing checkout.
* @param checkoutId ID of the checkout to update
* @param input Attributes to update (e.g., customAttributes)
* @returns Promise that resolves with the updated checkout
*/
updateAttributes(checkoutId: string, input: any): Promise<any>
/**
* Adds line items to an existing checkout.
* @param checkoutId ID of the checkout
* @param lineItems Array of line items to add (with variantId, quantity, etc.)
* @returns Promise that resolves with the updated checkout
*/
addLineItems(checkoutId: string, lineItems: any[]): Promise<any>
/**
* Updates line items in an existing checkout.
* @param checkoutId ID of the checkout
* @param lineItems Array of line items to update (with id and quantity)
* @returns Promise that resolves with the updated checkout
*/
updateLineItems(checkoutId: string, lineItems: any[]): Promise<any>
/**
* Removes line items from an existing checkout.
* @param checkoutId ID of the checkout
* @param lineItemIds Array of line item IDs to remove
* @returns Promise that resolves with the updated checkout
*/
removeLineItems(checkoutId: string, lineItemIds: string[]): Promise<any>
/**
* Adds a discount code to an existing checkout.
* @param checkoutId ID of the checkout
* @param discountCode Discount code to apply
* @returns Promise that resolves with the updated checkout
*/
addDiscount(checkoutId: string, discountCode: string): Promise<any>
/**
* Removes the applied discount from an existing checkout.
* @param checkoutId ID of the checkout
* @returns Promise that resolves with the updated checkout
*/
removeDiscount(checkoutId: string): Promise<any>
/**
* Updates the shipping address for an existing checkout.
* @param checkoutId ID of the checkout
* @param shippingAddress Shipping address details
* @returns Promise that resolves with the updated checkout
*/
updateShippingAddress(
checkoutId: string,
shippingAddress: any,
): Promise<any>
}
/**
* Shop resource for fetching shop information.
*/
shop: {
/**
* Fetches shop information.
* @returns Promise that resolves with the shop
*/
fetch(): Promise<any>
}
/**
* Collection resource for fetching collection data.
*/
collection: {
/**
* Fetches all collections, including their products.
* @returns Promise that resolves with an array of collections
*/
fetchAllWithProducts(): Promise<any[]>
/**
* Fetches a single collection by ID, including its products.
* @param collectionId ID of the collection to fetch
* @param options Optional parameters like productsFirst for pagination
* @returns Promise that resolves with the collection and its products
*/
fetchWithProducts(
collectionId: string,
options?: { productsFirst?: number },
): Promise<any>
}
/**
* Product resource for fetching product data.
*/
product: {
/**
* Fetches all products in the shop.
* @returns Promise that resolves with an array of products
*/
fetchAll(): Promise<any[]>
/**
* Fetches a single product by ID.
* @param productId ID of the product to fetch
* @returns Promise that resolves with the product
*/
fetch(productId: string): Promise<any>
/**
* Fetches a single product by handle (URL slug).
* @param handle Handle (URL slug) of the product to fetch
* @returns Promise that resolves with the product
*/
fetchByHandle(handle: string): Promise<any>
}
/**
* GraphQL client for making custom queries to the Storefront API.
* Only available in the unoptimized version of the SDK.
*/
graphQLClient?: {
/**
* Creates a new GraphQL query.
* @param queryBuilder Function to build the query
* @returns GraphQL query object
*/
query(queryBuilder: (root: any) => void): any
/**
* Sends a GraphQL query to the Storefront API.
* @param query GraphQL query object
* @returns Promise that resolves with the query results
*/
send(query: any): Promise<{ model: any; data: any }>
}
}
/**
* The main UI interface for creating and managing Buy Button components.
* Obtained from ShopifyBuy.UI.onReady().
*/
interface ShopifyBuyUI {
/**
* Creates a component of the specified type with the given configuration.
*
* @param type The type of component to create: 'product', 'productSet', 'collection', 'cart', or 'toggle'
* @param config The configuration object for the component
* @returns Promise that resolves to the created component instance
*
* @example
* ```javascript
* ui.createComponent('product', {
* id: 1234567,
* node: document.getElementById('product-container'),
* moneyFormat: '%24%7B%7Bamount%7D%7D',
* options: {
* product: {
* buttonDestination: 'modal'
* }
* }
* });
* ```
*/
createComponent(
type: 'product' | 'productSet' | 'collection' | 'cart' | 'toggle',
config: ShopifyBuyComponentConfig,
): Promise<ShopifyBuyComponent>
/**
* Tracks a component for analytics purposes.
* Internally used by createComponent.
*
* @param type Component type
* @param component Component to track
*/
trackComponent(
type: 'product' | 'productSet' | 'collection' | 'cart' | 'toggle',
component: ShopifyBuyComponent | any,
): void
/**
* Destroys a component of the specified type with the given ID.
*
* @param type Component type to destroy
* @param id ID of the component to destroy (optional)
*/
destroyComponent(
type: 'product' | 'productSet' | 'collection' | 'cart' | 'toggle',
id?: string | number,
): void
/**
* Creates a cart object to be shared between components.
* If a cart already exists, returns the existing cart.
*
* @param config Configuration object for the cart
* @returns Promise that resolves with the cart instance
*/
createCart(
config: ShopifyBuyComponentConfig,
): Promise<ShopifyBuyCartComponent>
/**
* Closes any open cart.
*/
closeCart(): void
/**
* Opens any cart.
*/
openCart(): void
/**
* Toggle visibility of cart.
* @param visibility Desired state of cart
*/
toggleCart(visibility?: boolean): void
/**
* Creates a modal object to be shared between components.
* If a modal already exists, returns the existing modal.
*
* @param config Configuration object for the modal
* @returns The modal instance
*/
createModal(config: ShopifyBuyComponentConfig): ShopifyBuyModalComponent
/**
* Closes any open modals.
*/
closeModal(): void
/**
* Sets the active element to restore focus to when a modal or cart closes.
*
* @param el Element to focus on after modal/cart close
*/
setActiveEl(el: HTMLElement): void
/**
* Restores focus to the previously active element.
* Called automatically when closing a modal or cart.
*/
restoreFocus(): void
/**
* Whether any modal is currently open.
*/
readonly modalOpen: boolean
/**
* Whether any cart is currently open.
*/
readonly cartOpen: boolean
/**
* Client instance associated with this UI
*/
client: ShopifyBuyClient
/**
* Configuration for this UI instance
*/
config: {
domain: string
[key: string]: any
}
/**
* Collection of all component instances created by this UI instance.
* Grouped by component type.
*/
components: {
product: ShopifyBuyProductComponent[]
cart: ShopifyBuyCartComponent[]
collection: ShopifyBuyProductSetComponent[]
productSet: ShopifyBuyProductSetComponent[]
toggle: ShopifyBuyToggleComponent[]
modal: ShopifyBuyModalComponent[]
}
/**
* Component type constructors
*/
componentTypes: {
product: any
cart: any
collection: any
productSet: any
toggle: any
}
/**
* Error reporter for logging issues
*/
errorReporter: any
/**
* Tracking instance for analytics
*/
tracker: any
/**
* Additional styles to be applied
*/
styleOverrides: string
/**
* Components that use iframes
*/
iframeComponents: any[]
}
/**
* Configuration object for creating a new Buy Button component.
*/
interface ShopifyBuyComponentConfig {
/**
* The ID of the Shopify resource (product, collection) to display.
*/
id: string
/**
* The DOM element where the component will be mounted.
*/
node: HTMLElement | null
/**
* The money format string to use for displaying prices.
*/
moneyFormat: string
/**
* Options object containing component-specific configurations.
*/
options?: ShopifyBuyOptions
}
/**
* Container for component-specific configuration options.
* Each property corresponds to a different component type or sub-component.
*/
interface ShopifyBuyOptions {
/** Configuration for the product component */
product?: ShopifyBuyProductOptions
/** Configuration for the cart component */
cart?: ShopifyBuyCartOptions
/** Configuration for the toggle component */
toggle?: ShopifyBuyToggleOptions
/** Configuration for the modal component */
modal?: ShopifyBuyModalOptions
/** Configuration for the collection/product set component */
productSet?: ShopifyBuyProductSetOptions
/** Configuration for the product within a modal */
modalProduct?: ShopifyBuyProductOptions
/** Configuration for the variant option selectors */
option?: ShopifyBuyOptionOptions
/** Configuration for individual line items in the cart */
lineItem?: ShopifyBuyLineItemOptions
/** Configuration for the checkout popup window */
window?: ShopifyBuyWindowOptions
}
/**
* Common configuration options that apply to all component types.
*/
interface ShopifyBuyCommonOptions {
/**
* Whether to render the component inside an iframe.
*
* Iframes isolate the embed in a "sandbox" so that other parts of your website
* don't interact with it in unwanted ways. Setting to `false` gives you full
* control over the appearance but requires custom CSS.
*
* @default true for top-level components, false for nested components
*/
iframe?: boolean
/**
* Order in which to render the elements within the component.
* You must list all elements you wish to include.
*
* @example
* ```
* order: ['title', 'price', 'options', 'quantity', 'button']
* ```
*/
order?: string[]
/**
* Whether or not to render each element within the component.
* Contains a key for each element in the component, set to either true or false.
*/
contents?: Record<string, boolean | undefined>
/**
* Values for all text visible in embeds.
* Does not include text defined in the product itself (e.g., product title).
*/
text?: Record<string, string | undefined>
/**
* Custom styles for a component. Format is based on CSS.
* The styles object is nested, with keys representing elements within the component.
*/
styles?: Record<string, any>
/**
* Determines class names added to elements within components.
* Only edit these if you're opting out of the iframe sandboxing.
*/
classes?: Record<string, string | undefined>
/**
* Determines the HTML template for each element in a component.
* Templates use the Mustache templating syntax.
*/
templates?: Record<string, string>
/**
* Binds custom events to DOM nodes by selector.
* Format is 'eventName selector': callback.
*
* @example
* ```
* DOMEvents: {
* 'click .button': function(event) {
* myAnalyticsLibrary.track()
* }
* }
* ```
*/
DOMEvents?: Record<string, (event: Event, target: HTMLElement) => void>
/**
* Lifecycle event hooks for component initialization and rendering.
*/
events?: ShopifyBuyComponentEvents
}
/**
* Component lifecycle event hooks that are available for all components.
* These can be used for custom functionality such as tracking or advanced DOM manipulation.
*/
interface ShopifyBuyComponentEvents {
/** Called before component is initialized */
beforeInit?: (component: ShopifyBuyComponent) => void
/** Called after component is initialized */
afterInit?: (component: ShopifyBuyComponent) => void
/** Called before component is rendered, after it has a model defined */
beforeRender?: (component: ShopifyBuyComponent) => void
/** Called after component is rendered */
afterRender?: (component: ShopifyBuyComponent) => void
/** Called before events are bound to the DOM */
beforeDelegateEvents?: (component: ShopifyBuyComponent) => void
/** Called after events are bound to the DOM */
afterDelegateEvents?: (component: ShopifyBuyComponent) => void
/** Called before configuration is updated */
beforeUpdateConfig?: (component: ShopifyBuyComponent) => void
/** Called after configuration is updated */
afterUpdateConfig?: (component: ShopifyBuyComponent) => void
}
/**
* Configuration options specific to the Product component.
* The Product component displays information about your product and an "Add to cart" button.
*/
interface ShopifyBuyProductOptions extends ShopifyBuyCommonOptions {
/**
* Determines what happens when the buy button is clicked:
* - 'cart': Adds product to cart and opens cart
* - 'modal': Opens a modal window with further details about the product
* - 'checkout': Opens a pop-up window directly to checkout
* - 'onlineStore': Open product in your online store
*
* @default 'cart'
*/
buttonDestination?: 'cart' | 'modal' | 'checkout' | 'onlineStore'
/**
* Whether to orient the product vertically (with image on top) or horizontally (with image to the side).
* Vertically oriented products have a set width (defaults to 240px) configurable by the `width` property.
* Horizontally oriented products take up the full width of their container.
*
* @default 'vertical'
*/
layout?: 'vertical' | 'horizontal'
/**
* Sets the maximum width for a product embed with vertical layout.
* Specified in pixels (e.g., '400px').
*
* @default '240px'
*/
width?: string
/**
* Whether or not the entire product should be clickable.
* Useful for hiding the button and treating the image as a button.
*
* @default false
*/
isButton?: boolean
/**
* Configures which elements of the product to display.
* Default contents include: img, title, variantTitle, price, options, button, description.
*/
contents?: {
img?: boolean
imgWithCarousel?: boolean
title?: boolean
variantTitle?: boolean
price?: boolean
options?: boolean
quantity?: boolean
quantityIncrement?: boolean
quantityDecrement?: boolean
quantityInput?: boolean
button?: boolean
buttonWithQuantity?: boolean
description?: boolean
[key: string]: boolean | undefined
}
/**
* Configurable text in the product component.
*/
text?: {
/** Text for the buy button */
button?: string
/** Text for out of stock products */
outOfStock?: string
/** Text for unavailable products */
unavailable?: string
[key: string]: string | undefined
}
/**
* Product-specific event handlers.
*/
events?: ShopifyBuyProductEvents
}
/**
* Event handlers specific to the Product component.
*/
interface ShopifyBuyProductEvents extends ShopifyBuyComponentEvents {
/** Called when a variant is added to the cart */
addVariantToCart?: (product: ShopifyBuyProductComponent) => void
/** Called when quantity is updated */
updateQuantity?: (product: ShopifyBuyProductComponent) => void
/** Called when the modal is opened */
openModal?: (product: ShopifyBuyProductComponent) => void
/** Called when redirecting to the online store */
openOnlineStore?: (product: ShopifyBuyProductComponent) => void
/** Called when checkout is opened */
openCheckout?: (product: ShopifyBuyProductComponent) => void
}
/**
* Configuration options specific to the Cart component.
* The Cart component is a shopping cart for product and collection embeds.
* Only one cart exists per page.
*/
interface ShopifyBuyCartOptions extends ShopifyBuyCommonOptions {
/**
* Whether cart should be visible or not when initialized.
*
* @default false
*/
startOpen?: boolean
/**
* Whether or not the checkout process is in a pop-up or the same window.
*
* @default true
*/
popup?: boolean
/**
* Controls which elements are displayed in the cart.
*/
contents?: {
/** Cart title */
title?: boolean
/** Line items in the cart */
lineItems?: boolean
/** Cart footer with totals and checkout button */
footer?: boolean
/** Order notes field */
note?: boolean
/** Discount codes section */
discounts?: boolean
[key: string]: boolean | undefined
}
/**
* Configurable text in the cart component.
*/
text?: {
/** Cart title text */
title?: string
/** Text shown when cart is empty */
empty?: string
/** Checkout button text */
button?: string
/** Total label text */
total?: string
/** Currency code */
currency?: string
/** Notice text about shipping and discount codes */
notice?: string
/** Description for the order notes field */
noteDescription?: string
[key: string]: string | undefined
}
/**
* Cart-specific event handlers.
*/
events?: ShopifyBuyCartEvents
}
/**
* Event handlers specific to the Cart component.
*/
interface ShopifyBuyCartEvents extends ShopifyBuyComponentEvents {
/** Called when checkout is opened */
openCheckout?: (cart: ShopifyBuyCartComponent) => void
/** Called when an item's quantity is updated */
updateItemQuantity?: (cart: ShopifyBuyCartComponent) => void
}
/**
* Configuration options specific to the ProductSet (Collection) component.
* This component displays either a collection of products or a custom set of products.
*/
interface ShopifyBuyProductSetOptions extends ShopifyBuyCommonOptions {
/**
* Controls which elements are displayed in the collection.
*/
contents?: {
/** Product items */
products?: boolean
/** Pagination controls */
pagination?: boolean
[key: string]: boolean | undefined
}
/**
* Configurable text in the collection component.
*/
text?: {
/** Text for the next page button */
nextPageButton?: string
[key: string]: string | undefined
}
/**
* Collection-specific event handlers.
*/
events?: ShopifyBuyProductSetEvents
}
/**
* Event handlers specific to the ProductSet component.
*/
interface ShopifyBuyProductSetEvents extends ShopifyBuyComponentEvents {
/** Called when the next page of products is loaded */
loadNextPage?: (productSet: ShopifyBuyProductSetComponent) => void
}
/**
* Configuration options specific to the Toggle component.
* The Toggle component is a small tab at the right side of the screen
* which opens and closes the cart.
*/
interface ShopifyBuyToggleOptions extends ShopifyBuyCommonOptions {
/**
* Controls which elements are displayed in the toggle.
*/
contents?: {
/** Item count indicator */
count?: boolean
/** Cart icon */
icon?: boolean
/** Cart title */
title?: boolean
[key: string]: boolean | undefined
}
/**
* Configurable text in the toggle component.
*/
text?: {
/** Cart title text (read by screen readers) */
title?: string
[key: string]: string | undefined
}
}
/**
* Configuration options specific to the Modal component.
* Created when a Product's buttonDestination is set to 'modal'.
*/
interface ShopifyBuyModalOptions extends ShopifyBuyCommonOptions {
/**
* Modal-specific event handlers.
*/
events?: ShopifyBuyModalEvents
}
/**
* Event handlers specific to the Modal component.
*/
interface ShopifyBuyModalEvents extends ShopifyBuyComponentEvents {
/** Called when the modal is closed */
closeModal?: (modal: ShopifyBuyModalComponent) => void
}
/**
* Configuration options specific to the Option component.
* This component configures the variant option selectors within a product.
*/
interface ShopifyBuyOptionOptions extends ShopifyBuyCommonOptions {
/**
* Custom styles for option component elements.
*/
styles?: {
/** Styles for the option label */
label?: Record<string, any>
/** Styles for the select dropdown */
select?: Record<string, any>
[key: string]: Record<string, any> | undefined
}
/**
* CSS classes for option component elements.
*/
classes?: {
/** Class for the option label */
label?: string
/** Class for the select dropdown */
select?: string
[key: string]: string | undefined
}
}
/**
* Configuration options specific to the LineItem component.
* This component configures line items within cart.
*/
interface ShopifyBuyLineItemOptions extends ShopifyBuyCommonOptions {
/**
* Controls which elements are displayed in line items.
*/
contents?: {
/** Product image */
image?: boolean
/** Variant title */
variantTitle?: boolean
/** Product title */
title?: boolean
/** Original price */
price?: boolean
/** Price with discounts applied */
priceWithDiscounts?: boolean
/** Quantity selector */
quantity?: boolean
/** Button to increase quantity */
quantityIncrement?: boolean
/** Button to decrease quantity */
quantityDecrement?: boolean
/** Input field to directly set quantity */
quantityInput?: boolean
[key: string]: boolean | undefined
}
}
/**
* Configuration options for the checkout popup window.
*/
interface ShopifyBuyWindowOptions {
/** Window height in pixels */
height?: number
/** Window width in pixels */
width?: number
/** Whether to show the toolbar (0 = no, 1 = yes) */
toolbar?: number
/** Whether to show scrollbars (0 = no, 1 = yes) */
scrollbars?: number
/** Whether to show the status bar (0 = no, 1 = yes) */
status?: number
/** Whether the window is resizable (0 = no, 1 = yes) */
resizable?: number
/** Left position in pixels */
left?: number
/** Top position in pixels */
top?: number
/** Whether to center the window (0 = no, 1 = yes) */
center?: number
/** Whether to create a new window (0 = no, 1 = yes) */
createnew?: number
/** Whether to show the location field (0 = no, 1 = yes) */
location?: number
/** Whether to show the menu bar (0 = no, 1 = yes) */
menubar?: number
/** Function to call when window is closed */
onUnload?: (() => void) | null
}
/**
* Base interface for all Shopify Buy Button components.
*/
interface ShopifyBuyComponent {
/** Component ID */
id: string
/** DOM node where the component is mounted */
node: HTMLElement
/** Component configuration options */
options: ShopifyBuyOptions
/** Data model for the component */
model: any
/** HTML templates used to render the component */
templates: Record<string, string>
/** CSS styles for the component */
styles: Record<string, any>
/** CSS classes for the component */
classes: Record<string, string>
/** Reference to iframe element if component is rendered in iframe */
iframe?: {
el: HTMLIFrameElement
}
/** Tracking information for analytics */
trackingInfo: any
/** Destroys the component and removes it from the DOM */
destroy(): void
/** Updates the component's configuration */
updateConfig(config: Partial<ShopifyBuyOptions>): void
/** Initializes the component */
init(): Promise<any>
}
/**
* Interface for the Product component.
* Displays product information and an "Add to cart" button.
*/
interface ShopifyBuyProductComponent extends ShopifyBuyComponent {
/**
* Updates the selected variant based on an option value.
*
* @param optionName The name of the option (e.g., "Size", "Color")
* @param value The value to select (e.g., "Small", "Red")
*/
updateVariant(optionName: string, value: string): void
/**
* View object for rendering and updating the component's UI
*/
view: {
/** Resizes the component */
resize(): void
}
}
/**
* Interface for the Cart component.
* Displays the shopping cart with products and checkout button.
*/
interface ShopifyBuyCartComponent extends ShopifyBuyComponent {
/**
* Toggles the visibility of the cart (open/close).
* @param visibility Optional boolean to explicitly set visibility state
*/
toggleVisibility(visibility?: boolean): void
/**
* Opens the cart.
*/
open(): void
/**
* Closes the cart.
*/
close(): void
/**
* Whether the cart is currently visible
*/
isVisible: boolean
/**
* Collection of toggle components for this cart
*/
toggles: ShopifyBuyToggleComponent[]
/**
* Creates toggle components for this cart
* @param config Cart configuration
*/
createToggles(config: ShopifyBuyComponentConfig): Promise<any>
}
/**
* Interface for the ProductSet (Collection) component.
* Displays a collection of products or a custom set of products.
*/
interface ShopifyBuyProductSetComponent extends ShopifyBuyComponent {
/**
* Loads the next page of products in the collection.
*/
nextPage(): void
/**
* View object for rendering and updating the component's UI
*/
view: {
/** Resizes the component */
resize(): void
}
}
/**
* Interface for the Toggle component.
* Small tab that opens and closes the cart.
*/
interface ShopifyBuyToggleComponent extends ShopifyBuyComponent {
/**
* Toggles the visibility of the cart.
*/
toggleVisibility(): void
}
/**
* Interface for the Modal component.
* Pop-up window that displays detailed product information.
*/
interface ShopifyBuyModalComponent extends ShopifyBuyComponent {
/**
* Closes the modal.
*/
close(): void
/**
* Whether the modal is currently visible
*/
isVisible: boolean
}
export {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment