# Custom events

STOQ emits custom events that you can listen to for custom integrations. All events are dispatched on the `window` object (except where noted) and include detailed information in the `event.detail` property.

### `stoq:loaded`

**Event name:** `stoq:loaded`

**Description:** Event triggered when STOQ's app embed is loaded on any page supported by the app. Pages supported: Product, Collection, Home, Search.

**Event target:** `window`

**Event detail:**

* `pageType` (string): The type of page where the app loaded. Possible values: `'product'`, `'collection'`, `'index'`, `'search'`, `'page'`
* `enabled` (boolean): Whether the app is enabled for this page
* `settings` (object): Complete app settings object containing all configuration options

**Example:**

```javascript
window.addEventListener('stoq:loaded', (event) => {
  const { pageType, enabled, settings } = event.detail;
  if (pageType === 'product' && enabled) {
    console.log('Stoq loaded on product page', settings);
    // Handle product page customizations
  }
});
```

***

### `stoq:restock-modal:opened`

**Event name:** `stoq:restock-modal:opened`

**Description:** Event triggered when the restock notification modal is opened. This occurs when a customer clicks the "Notify Me" button for an out-of-stock product.

**Event target:** `window`

**Event detail:**

* `action` (string): Always `'opened'`
* `product` (object): Product data object containing product information
* `variant` (object): Variant data object containing variant information

**Example:**

```javascript
window.addEventListener('stoq:restock-modal:opened', (event) => {
  const { product, variant } = event.detail;
  console.log('Restock modal opened for:', product.title, variant.title);
  // Track analytics or perform custom actions
});
```

***

### `stoq:restock-modal:submitted`

**Event name:** `stoq:restock-modal:submitted`

**Description:** Event triggered when a customer successfully submits the restock notification form. This occurs after the form validation passes and the notification request is created.

**Event target:** `window`

**Event detail:**

* `action` (string): Always `'submitted'`
* `product` (object): Product data object containing product information
* `variant` (object): Variant data object containing variant information
* `customer` (object): Customer information object
  * `email` (string|null): Customer email address if provided
  * `phone` (string|null): Customer phone number if provided

**Example:**

```javascript
window.addEventListener('stoq:restock-modal:submitted', (event) => {
  const { product, variant, customer } = event.detail;
  console.log('Restock notification submitted:', {
    product: product.title,
    variant: variant.title,
    email: customer.email,
    phone: customer.phone
  });
  // Track conversion or send to analytics
});
```

***

### `stoq:restock-modal:closed`

**Event name:** `stoq:restock-modal:closed`

**Description:** Event triggered when the restock notification modal is closed, either by the user clicking the close button or clicking outside the modal.

**Event target:** `window`

**Event detail:**

* `action` (string): Always `'closed'`
* `product` (object): Product data object containing product information
* `variant` (object): Variant data object containing variant information

**Example:**

```javascript
window.addEventListener('stoq:restock-modal:closed', (event) => {
  const { product, variant } = event.detail;
  console.log('Restock modal closed for:', product.title);
  // Track abandonment or perform cleanup
});
```

***

### `stoq:preorder-modal:opened`

**Event name:** `stoq:preorder-modal:opened`

**Description:** Event triggered when the preorder modal is opened. This occurs when a customer clicks a preorder button or attempts to add a preorder product to cart.

**Event target:** `window`

**Event detail:**

* `productData` (object): Complete product data object
* `variantId` (string|number): ID of the selected variant
* `sellingPlan` (object|null): Selling plan object if a specific plan is selected, null otherwise

**Example:**

```javascript
window.addEventListener('stoq:preorder-modal:opened', (event) => {
  const { productData, variantId, sellingPlan } = event.detail;
  console.log('Preorder modal opened:', {
    product: productData.title,
    variant: variantId,
    plan: sellingPlan?.name
  });
  // Track preorder interest
});
```

***

### `stoq:preorder-modal:closed`

**Event name:** `stoq:preorder-modal:closed`

**Description:** Event triggered when the preorder modal is closed. This can occur in two scenarios: when the customer accepts the preorder (adds to cart) or when they reject/close the modal.

**Event target:** `window`

**Event detail:**

* `action` (string): Either `'accepted'` or `'rejected'` indicating how the modal was closed
* `productData` (object): Complete product data object
* `variantId` (string|number): ID of the selected variant
* `selectedSellingPlanId` (number|null): ID of the selected selling plan if accepted, null if rejected
* `sellingPlan` (object|null): Selling plan object
* `quantity` (number): Quantity selected (only present when `action === 'accepted'`)
* `acknowledgedPreorder` (boolean): Whether the customer acknowledged the preorder terms (only present when `action === 'accepted'`)

**Example:**

```javascript
window.addEventListener('stoq:preorder-modal:closed', (event) => {
  const { action, productData, variantId, selectedSellingPlanId, quantity } = event.detail;

  if (action === 'accepted') {
    console.log('Preorder accepted:', {
      product: productData.title,
      variant: variantId,
      plan: selectedSellingPlanId,
      quantity: quantity
    });
    // Track successful preorder
  } else {
    console.log('Preorder rejected:', productData.title);
    // Track abandonment
  }
});
```

***

### `stoq:preorder-payment-option:selected`

**Event name:** `stoq:preorder-payment-option:selected`

**Description:** Event triggered when a customer selects a different payment option (selling plan) in the preorder payment widget. This event bubbles from the payment widget element.

**Event target:** Payment widget element (bubbles to `window`)

**Event detail:**

* `paymentWidget` (HTMLElement): The DOM element containing the payment widget
* `variantId` (string|number): ID of the variant for which the payment option was selected
* `selectedSellingPlanId` (number): ID of the newly selected selling plan

**Example:**

```javascript
// Listen on the payment widget element
const paymentWidget = document.querySelector('.restock-rocket-payment-widget');
if (paymentWidget) {
  paymentWidget.addEventListener('stoq:preorder-payment-option:selected', (event) => {
    const { variantId, selectedSellingPlanId } = event.detail;
    console.log('Payment option changed:', {
      variant: variantId,
      plan: selectedSellingPlanId
    });
    // Update UI or pricing based on selected plan
  });
}

// Or listen on window (event bubbles)
window.addEventListener('stoq:preorder-payment-option:selected', (event) => {
  const { variantId, selectedSellingPlanId } = event.detail;
  // Handle payment option change
});
```

***

### `stoq:product-changed`

**Event name:** `stoq:product-changed`

**Description:** Event triggered when the product context changes, such as when navigating to a different product or when the variant selection changes significantly. This is useful for tracking product views and updating custom integrations.

**Event target:** `document`

**Event detail:**

* `productHandle` (string): The Shopify product handle (URL slug)
* `productId` (string|number): The Shopify product ID
* `variantId` (string|number): The currently selected variant ID

**Example:**

```javascript
document.addEventListener('stoq:product-changed', (event) => {
  const { productHandle, productId, variantId } = event.detail;
  console.log('Product context changed:', {
    handle: productHandle,
    product: productId,
    variant: variantId
  });
  // Update custom integrations or track product views
});
```

***

### Integration examples

#### Track all modal interactions

```javascript
// Track when modals open
window.addEventListener('stoq:restock-modal:opened', (event) => {
  analytics.track('restock_modal_opened', {
    product_id: event.detail.product.id,
    variant_id: event.detail.variant.id
  });
});

window.addEventListener('stoq:preorder-modal:opened', (event) => {
  analytics.track('preorder_modal_opened', {
    product_id: event.detail.productData.id,
    variant_id: event.detail.variantId
  });
});

// Track when modals close
window.addEventListener('stoq:restock-modal:closed', (event) => {
  analytics.track('restock_modal_closed', {
    product_id: event.detail.product.id
  });
});

window.addEventListener('stoq:preorder-modal:closed', (event) => {
  analytics.track('preorder_modal_closed', {
    action: event.detail.action,
    product_id: event.detail.productData.id
  });
});
```

#### Update custom UI on product change

```javascript
document.addEventListener('stoq:product-changed', (event) => {
  const { productHandle, variantId } = event.detail;

  // Update custom product display
  updateCustomProductDisplay(productHandle, variantId);

  // Fetch additional product data
  fetchCustomProductData(productHandle).then(data => {
    displayCustomData(data);
  });
});
```

#### React to payment option changes

```javascript
window.addEventListener('stoq:preorder-payment-option:selected', (event) => {
  const { selectedSellingPlanId } = event.detail;

  // Update custom pricing display
  const plan = getSellingPlanDetails(selectedSellingPlanId);
  updatePriceDisplay(plan.price, plan.discount);

  // Update shipping estimates
  updateShippingEstimate(plan.estimatedDelivery);
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.stoqapp.com/custom-events.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
