Discussing Shopify Functions development, deployment, and usage in Shopify apps.
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?
Solved! Go to the solution
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
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
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
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>
);
}
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
Oh Cool, thanks Scott!
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!