Skip to content

Add messages to mini cart

This tutorial shows you how to add inline and overlay feedback messages that appear in the mini cart when products are added or updated to the cart. These messages provide visual feedback to shoppers about their cart actions.

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

Minicart inline message

Minicart inline message

Overlay messages are displayed at the top center of the mini cart with a semi-transparent background when the same events occur.

Minicart overlay message

Minicart overlay message

You can customize the appearance and behavior of the inline and overlay messages by modifying the following:

  • Message text: Update the translations in the the content placeholders sheet under the Cart.MiniCart.Message namespace.

  • 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. Overlays can be customized as follows:

    • Background opacity using the alpha value in the overlay’s background-color (default is 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).

Prerequisites

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.

Events

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

Implementation

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

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 Cart.MiniCart.Message namespace
const MESSAGES = {
ADDED: placeholders?.Cart?.MiniCart?.Message?.added,
UPDATED: placeholders?.Cart?.MiniCart?.Message?.updated,
};

Create the appropriate message containers

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

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);
};

Add event listeners for cart updates

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

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);
}

Update the CSS styles

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;
}

Complete example

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, fetchPlaceholders } from '../../scripts/aem.js';
import { rootLink } from '../../scripts/scripts.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?.Cart?.MiniCart?.Message?.added,
UPDATED: placeholders?.Cart?.MiniCart?.Message?.updated,
};
// 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;
}