Skip to content

CartBadge

The header count.

import { CartBadge } from "@evolve-storefront/feature-cart/cart-badge";

Renders inside CartProvider.

Design notes

One badge source. It reads totalQuantity off the same cart entity the cart page renders, so the two cannot disagree and there is no separate ["cart", "quantity"] family to invalidate in lockstep — which is exactly what this replaces.

Renders nothing while the query is pending: a badge that flashes "0" and then corrects itself is worse than one that appears a moment later.

"use client", and it has to be here rather than on the caller. It reads the cart query, so it is the client leaf — and without the directive it only worked inside someone else's boundary, which forced a header link that is otherwise a Link and an icon to become a client component for the badge's sake. That is the "client reference in a route that didn't need one" problem the ./hooks vs ./queries split exists to prevent.

Preview

DefaultOpen in Storybook ↗

Usage

// In the header link: the count comes from the same query the cart page reads.
<Link href="/cart">
<Icon name="cart" />
{t("cart")}
<CartBadge />
</Link>;

Props

PropTypeDescription
showZero?boolean

Render at zero too. Off by default — an empty badge is visual noise.

Any other props go to the root element, like on a plain HTML element.

Examples

EmptyNo cart at all: hidden by default, a "0" with showZero.
// Hidden at zero by default; showZero keeps a fixed slot in the header.
<CartBadge />;
<CartBadge showZero />;
Open in Storybook ↗