Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Notify Me CTA

When a product or selected variant is out of stock, the primary Call to Action (CTA) button on the Product Detail Page (PDP) can display “Notify Me” instead of “Add to Cart”. This applies to both simple products and configurable products with multiple options (for example, size and color). When the shopper switches to a different variant, the CTA updates dynamically based on that variant’s stock status.

Prerequisites

Before following these steps, you should understand:

  • Eventspdp/data, pdp/valid, and subscription patterns
  • FunctionsgetProductConfigurationValues for reading selected options
  • Cart Eventscart/data for detecting when the product is already in the cart

This how-to uses the basic tools exposed by the Product Details drop-in: the event bus and a CTA element in your block. For a full implementation reference example in the Commerce boilerplate, see hlxsites/aem-boilerplate-commerce#1116.

Overview

These are the basic steps to implement the “Notify Me” CTA:

  1. Target a DOM element for the primary CTA (in many PDP blocks, this is the Add to Cart button).
  2. Subscribe to eventspdp/data, pdp/valid, and cart/data — to know when product data, validation state, or cart state changes.
  3. In each callback, update the CTA text and enabled/disabled state based on stock status, configuration validity, and whether the item is already in the cart.

Implementation steps

Implement a CTA update function

Create a function that updates the CTA element based on stock status, update mode (item in cart), and labels. When out of stock, set the button text to “Notify Me”, remove the cart icon, and keep the button enabled. When in stock, show “Add to Cart” or “Update in Cart” with the cart icon based on cart context.

The following examples use variable names from the boilerplate; adjust to match your block’s structure.

function updatePrimaryCTA(buttonInstance, { isOutOfStock, isUpdateMode, labels }) {
if (!buttonInstance) return;
if (isOutOfStock) {
buttonInstance.setProps((prev) => ({
...prev,
children: labels.Global?.NotifyMe || 'Notify Me',
icon: null,
disabled: false,
}));
} else {
const buttonText = isUpdateMode
? labels.Global?.UpdateProductInCart
: labels.Global?.AddProductToCart;
buttonInstance.setProps((prev) => ({
...prev,
children: buttonText,
icon: h(Icon, { source: 'Cart' }),
}));
}
}

Track stock and update mode state

Maintain state variables for the currently selected product’s stock status and whether the item is in the cart (update mode). These drive the CTA update logic.

let isUpdateMode = false;
let isOutOfStock = false;

Subscribe to pdp/data for stock status

Subscribe to pdp/data with { eager: true } so the handler runs on initial load and whenever the product or variant changes. Read inStock from the payload and update the CTA accordingly.

Why: Product data (including stock) changes when the page loads or when the shopper selects a different variant. You need to react to both.

events.on('pdp/data', (data) => {
isOutOfStock = data?.inStock === false;
updatePrimaryCTA(addToCart, { isOutOfStock, isUpdateMode, labels });
}, { eager: true });

See the pdp/data event reference for the full event payload.

Subscribe to pdp/valid for configuration validity

Subscribe to pdp/valid with { eager: true }. When the product is in stock, disable the button if the configuration is invalid (for example, required options not selected). When out of stock, keep the “Notify Me” button enabled regardless of configuration validity.

Why: For Add to Cart, the button should be disabled until the shopper completes required selections. For Notify Me, the button can stay enabled so the shopper can request notification even before selecting options.

events.on('pdp/valid', (valid) => {
if (!isOutOfStock) {
addToCart.setProps((prev) => ({ ...prev, disabled: !valid }));
}
}, { eager: true });

Handle out-of-stock clicks in the button handler

At the top of the CTA’s onClick handler, check isOutOfStock. When true, run your custom notify-me logic and return early so no cart logic executes.

onClick: async () => {
if (isOutOfStock) {
const values = pdpApi.getProductConfigurationValues();
// Replace with your logic: open modal, call back-in-stock API, emit custom event, etc.
console.log('Notify Me', { sku: product?.sku, values });
return;
}
// ... Add to Cart / Update in Cart logic
}

Subscribe to cart/data for update mode

Subscribe to cart/data with { eager: true }. When the cart data changes, determine whether the current product is already in the cart. If so, set isUpdateMode and call updatePrimaryCTA so the button shows “Update in Cart” instead of “Add to Cart”.

Why: The CTA text and behavior differ when the item is already in the cart. Cart data changes when items are added, updated, or removed.

events.on(
'cart/data',
(data) => {
// Determine if current product/variant is in cart...
isUpdateMode = itemIsInCart;
updatePrimaryCTA(addToCart, { isOutOfStock, isUpdateMode, labels });
},
{ eager: true },
);

Reset the CTA after cart actions

After an add-to-cart or update-in-cart action completes (for example, in the finally block of your click handler), call updatePrimaryCTA to restore the correct button state.

finally {
updatePrimaryCTA(addToCart, { isOutOfStock, isUpdateMode, labels });
addToCart.setProps((prev) => ({
...prev,
disabled: false,
}));
}