Skip to content
Tutorials

Add messages to mini cart

The mini cart block already includes inline feedback messages by default: a brief message flashes at the top of the mini cart when a shopper adds or updates a product, then disappears automatically. This tutorial explains how those default messages work, then shows you how to build a custom overlay-style alternative that displays the same feedback centered over the mini cart with a semi-transparent background.

  • Edit the mini cart block — blocks/commerce-mini-cart/commerce-mini-cart.js (to add the overlay variant)
  • Edit the mini cart styles — blocks/commerce-mini-cart/commerce-mini-cart.css (to add overlay styles)
  • Create an overlay version of the showMessage() function
  • Reuse the existing message placeholders — Global.MiniCartAddedMessage / Global.MiniCartUpdatedMessage

By the end of this tutorial, you’ll have:

  • An understanding of the inline messages that already ship by default in commerce-mini-cart.js, flashing at the top of the mini cart for a few seconds after a cart update.
  • A custom overlay variant of the same messages, styled through commerce-mini-cart.css, that appears centered over the mini cart instead of inline.
  • Message text and display duration driven by the content placeholders sheet and the cart/product/added and cart/product/updated events, for either variant.

Inline messages already appear at the top of the mini cart by default for a brief period (three seconds) and then automatically disappear, providing immediate feedback to users about their cart actions.

Minicart inline message

Minicart inline message

If you’d rather show that same feedback as an overlay, build a custom variant that displays a message at the top center of the mini cart with a semi-transparent background instead:

Minicart overlay message

Minicart overlay message

You can customize the appearance and behavior of either variant by modifying the following:

  • Message text: Update the translations in the content placeholders sheet under the Global.MiniCartAddedMessage and Global.MiniCartUpdatedMessage keys.

  • Message styling: Modify the CSS classes in commerce-mini-cart.css. The styles use design tokens (prefixed with --) to maintain consistency with the design system. The overlay variant can be customized as follows:

    • Background opacity using the alpha value in the overlay’s background-color (the sample below uses 50%)
    • Message position using the top, left, and transform properties
    • Colors, spacing, shadows, and other visual properties using design tokens
  • Message position: For inline messages, change where the message appears in the mini cart by modifying the insertion point in the DOM.

  • Display duration: Change the timeout value in the showMessage function (default is 3000ms).

Before implementing inline messages, ensure you have:

  • Access to the content folder to manage message localization through placeholders.
  • Understanding of the design system tokens used in the Commerce boilerplate template.
  • The commerce-mini-cart.css file in your blocks/commerce-mini-cart/ directory.

The inline and overlay messages respond to two cart events:

  • cart/product/added: Triggered when products are added to the cart
  • cart/product/updated: Triggered when products in the cart are updated

To add inline or overlay messages to your mini cart, follow these steps:

Retrieve translations for message texts using placeholders

Section titled “Retrieve translations for message texts using placeholders”

Get translations for custom messages from the content folder.

const placeholders = await fetchPlaceholders();
// Access the message texts from the Global placeholders sheet
const MESSAGES = {
ADDED: placeholders?.Global?.MiniCartAddedMessage,
UPDATED: placeholders?.Global?.MiniCartUpdatedMessage,
};

Inline messages require a container for the update message and a shadow wrapper to display the message. Overlay messages require an overlay container and a message container.

// Create a container for the update message
const updateMessage = document.createElement('div');
updateMessage.className = 'commerce-mini-cart__update-message';
// Create a shadow wrapper
const shadowWrapper = document.createElement('div');
shadowWrapper.className = 'commerce-mini-cart__message-wrapper';
shadowWrapper.appendChild(updateMessage);

Create a function to show and hide messages

Section titled “Create a function to show and hide messages”

Create a function that displays the message in the container and then hides it after a specified duration, such as three seconds.

const showMessage = (message) => {
updateMessage.textContent = message;
updateMessage.classList.add('commerce-mini-cart__update-message--visible');
shadowWrapper.classList.add('commerce-mini-cart__message-wrapper--visible');
setTimeout(() => {
updateMessage.classList.remove('commerce-mini-cart__update-message--visible');
shadowWrapper.classList.remove('commerce-mini-cart__message-wrapper--visible');
}, 3000);
};

Listen for the cart/product/added and cart/product/updated events and display the appropriate message.

import { events } from '/@dropins/tools/event-bus.js';
events.on('cart/product/added', () => showMessage(MESSAGES.ADDED), {
eager: true,
});
events.on('cart/product/updated', () => showMessage(MESSAGES.UPDATED), {
eager: true,
});

Insert the message container into the mini cart block

Section titled “Insert the message container into the mini cart block”

Add the message container to the mini cart block to display the messages.

// Find the products container and add the message div at the top
const productsContainer = block.querySelector('.cart-mini-cart__products');
if (productsContainer) {
productsContainer.insertBefore(shadowWrapper, productsContainer.firstChild);
} else {
console.info('Products container not found, appending message to block');
block.appendChild(shadowWrapper);
}

Add styles to your commerce-mini-cart.css file.

.commerce-mini-cart__update-message {
display: none;
font: var(--type-body-2-default-font);
letter-spacing: var(--type-body-2-default-letter-spacing);
}
.commerce-mini-cart__message-wrapper {
background-color: var(--color-positive-200);
border-radius: var(--shape-border-radius-1);
padding: var(--spacing-xsmall);
display: none;
margin-bottom: var(--spacing-small);
}
.commerce-mini-cart__message-wrapper--visible,
.commerce-mini-cart__update-message--visible {
display: block;
}

Here’s a complete example of implementing inline and overlay messages in your commerce-mini-cart.js block file:

import { render as provider } from '/@dropins/storefront-cart/render.js';
import MiniCart from '/@dropins/storefront-cart/containers/MiniCart.js';
import { events } from '/@dropins/tools/event-bus.js';
// Initializers
import '/scripts/initializers/cart.js';
import { readBlockConfig } from '/scripts/aem.js';
import { fetchPlaceholders, rootLink } from '/scripts/commerce.js';
export default async function decorate(block) {
const {
'start-shopping-url': startShoppingURL = '',
'cart-url': cartURL = '',
'checkout-url': checkoutURL = '',
} = readBlockConfig(block);
// Get translations for custom messages
const placeholders = await fetchPlaceholders();
const MESSAGES = {
ADDED: placeholders?.Global?.MiniCartAddedMessage,
UPDATED: placeholders?.Global?.MiniCartUpdatedMessage,
};
// Create a container for the update message
const updateMessage = document.createElement('div');
updateMessage.className = 'commerce-mini-cart__update-message';
// Create shadow wrapper
const shadowWrapper = document.createElement('div');
shadowWrapper.className = 'commerce-mini-cart__message-wrapper';
shadowWrapper.appendChild(updateMessage);
const showMessage = (message) => {
updateMessage.textContent = message;
updateMessage.classList.add('commerce-mini-cart__update-message--visible');
shadowWrapper.classList.add('commerce-mini-cart__message-wrapper--visible');
setTimeout(() => {
updateMessage.classList.remove('commerce-mini-cart__update-message--visible');
shadowWrapper.classList.remove('commerce-mini-cart__message-wrapper--visible');
}, 3000);
};
// Add event listeners for cart updates
events.on('cart/product/added', () => showMessage(MESSAGES.ADDED), {
eager: true,
});
events.on('cart/product/updated', () => showMessage(MESSAGES.UPDATED), {
eager: true,
});
block.innerHTML = '';
// Render MiniCart first
await provider.render(MiniCart, {
routeEmptyCartCTA: startShoppingURL ? () => rootLink(startShoppingURL) : undefined,
routeCart: cartURL ? () => rootLink(cartURL) : undefined,
routeCheckout: checkoutURL ? () => rootLink(checkoutURL) : undefined,
routeProduct: (product) => rootLink(`/products/${product.url.urlKey}/${product.topLevelSku}`),
})(block);
// Find the products container and add the message div at the top
const productsContainer = block.querySelector('.cart-mini-cart__products');
if (productsContainer) {
productsContainer.insertBefore(shadowWrapper, productsContainer.firstChild);
} else {
console.info('Products container not found, appending message to block');
block.appendChild(shadowWrapper);
}
return block;
}

And here’s the accompanying CSS file (commerce-mini-cart.css):

.commerce-mini-cart__update-message {
display: none;
font: var(--type-body-2-default-font);
letter-spacing: var(--type-body-2-default-letter-spacing);
}
.commerce-mini-cart__message-wrapper {
background-color: var(--color-positive-200);
border-radius: var(--shape-border-radius-1);
padding: var(--spacing-xsmall);
display: none;
margin-bottom: var(--spacing-small);
}
.commerce-mini-cart__message-wrapper--visible,
.commerce-mini-cart__update-message--visible {
display: block;
}