Solved

Conditionally display message banner if Cart totalQuantity is greater than X

nealmckinney
Shopify Partner
3 0 0

Just getting started with Checkout Extensions and Functions trying to replicate some customizations in the old checkout.liquid. In the liquid file I could simply check the carts item_count and show a custom message pertaining to shipping on the Shipping Method step. This will simply be a message about shipping taking longer for orders container over X amount of items. Is this possible with the new checkout to conditionally show a message banner?

Accepted Solutions (2)

SBD_
Shopify Staff
1829 269 409

This is an accepted solution.

Hey @nealmckinney,

 

You should be able to do this by using the `useCartLines` hook to count the cart items.

 

I'd recommend running through this tutorial to get started. Let me know if you get stuck!

Scott | Developer Advocate @ Shopify 

View solution in original post

SBD_
Shopify Staff
1829 269 409

This is an accepted solution.

Hey @nealmckinney 

 

You should be able to skip the API call by using the `useCartLines` hook. Try this:

 

import {
  Banner,
  reactExtension,
  useCartLines,
} from "@shopify/ui-extensions-react/checkout";

export default reactExtension("purchase.checkout.block.render", () => (
  <Extension />
));

function Extension() {
  const cartLines = useCartLines();

  const totalLineItems = cartLines.reduce(
    (sum, line) => sum + line.quantity,
    0
  );

  return (
    <Banner title="checkout-ui">
      There are {totalLineItems} item(s) in the cart!
    </Banner>
  );
}

 

Scott | Developer Advocate @ Shopify 

View solution in original post

Replies 5 (5)

SBD_
Shopify Staff
1829 269 409

This is an accepted solution.

Hey @nealmckinney,

 

You should be able to do this by using the `useCartLines` hook to count the cart items.

 

I'd recommend running through this tutorial to get started. Let me know if you get stuck!

Scott | Developer Advocate @ Shopify 

nealmckinney
Shopify Partner
3 0 0

Thanks Scott, did some research and playing around with Chat GPT, and it looks like in order to do an API call to get that info the extension needs to be hosted, and the app needs to store an access token etc... all things that seem like a big hurdle for such a simple checkout message, so the client has decided to abort on making it conditional and just go static. If it's helpful for anyone else that wants to do something like this, here's the code example from Chat GPT for Checkout.jsx to access the number of items in the cart from within a Message Banner extension. 

import React, { useState, useEffect } from "react";
import {
  reactExtension,
  Banner,
  useSettings,
} from "@shopify/ui-extensions-react/checkout";

// Set the entry points for the extension
const checkoutBlock = reactExtension("purchase.checkout.block.render", () => (
  <App />
));
export { checkoutBlock };

const deliveryAddress = reactExtension(
  "purchase.checkout.delivery-address.render-before",
  () => <App />
);
export { deliveryAddress };

function App() {
  // Use the merchant-defined settings to retrieve the extension's content
  const { title: merchantTitle, description, collapsible, status: merchantStatus } = useSettings();

  // Use state to manage cart item count
  const [cartItemCount, setCartItemCount] = useState(0);

  // Function to fetch the cart item count from Shopify's Cart Lines API
  const fetchCartItemCount = async () => {
    try {
      const accessToken = "your_access_token_here"; // Replace with your actual access token
      const headers = {
        "X-Shopify-Storefront-Access-Token": accessToken,
        "Content-Type": "application/json",
      };

      const response = await fetch("/api/2023-10/cart-lines", {
        headers,
      }); // Adjust the API endpoint accordingly
      const data = await response.json();
      // Calculate the total item count based on the cart lines
      const totalItemCount = data.reduce((acc, line) => acc + line.quantity, 0);
      setCartItemCount(totalItemCount);
    } catch (error) {
      console.error("Error fetching cart item count:", error);
    }
  };

  useEffect(() => {
    fetchCartItemCount();
  }, []); // Fetch the cart item count when the component mounts

  // Set a default status for the banner if a merchant didn't configure the banner in the checkout editor
  const status = merchantStatus ?? "info";
  const title = merchantTitle ?? "Custom Banner";

  // Conditional rendering based on cart item count
  if (cartItemCount === 0) {
    return null; // Hide the banner when the cart is empty
  }

  // Render the banner with the cart item count
  return (
    <Banner title={title} status={status} collapsible={collapsible}>
      {description}
      <div className="cart-item-count">
        You have {cartItemCount} {cartItemCount === 1 ? 'item' : 'items'} in your cart.
      </div>
    </Banner>
  );
}

 

SBD_
Shopify Staff
1829 269 409

This is an accepted solution.

Hey @nealmckinney 

 

You should be able to skip the API call by using the `useCartLines` hook. Try this:

 

import {
  Banner,
  reactExtension,
  useCartLines,
} from "@shopify/ui-extensions-react/checkout";

export default reactExtension("purchase.checkout.block.render", () => (
  <Extension />
));

function Extension() {
  const cartLines = useCartLines();

  const totalLineItems = cartLines.reduce(
    (sum, line) => sum + line.quantity,
    0
  );

  return (
    <Banner title="checkout-ui">
      There are {totalLineItems} item(s) in the cart!
    </Banner>
  );
}

 

Scott | Developer Advocate @ Shopify 

nealmckinney
Shopify Partner
3 0 0

Oh Cool, thanks Scott!

bluewhippet
Visitor
2 0 0

Hello - What if we do not have Shopify Plus? Is there an app you could recommend that would do the same thing? We are looking to add a cart banner that shows only if the cart is ≥ $ or total number of items in cart. 

 

Thank you!