Shopify

Building Shopify Checkout UI Extensions with React

By Mohd Baquir Qureshi
Point of Sale Terminal Checkout

For years, modifying the Shopify Checkout meant dealing with the brittle and often dangerous checkout.liquid file. With the introduction of Checkout Extensibility, Shopify Plus merchants can now customize their checkout flow using React-based Checkout UI Extensions. This approach is significantly more secure, future-proof, and natively supported across all devices, including the Shop app.

Why Use Checkout UI Extensions?

  • Upgrade Safe: Unlike editing liquid files, UI extensions run in a sandboxed Web Worker environment and render native components. When Shopify pushes checkout updates, your extensions will not break.
  • High Performance: They run securely and asynchronously, meaning they don't block the critical rendering path of the checkout.
  • Access to Checkout State: Extensions can hook into the checkout state to read the cart contents, shipping lines, and buyer identity, allowing for highly personalized experiences.

Building a Post-Purchase Upsell Component

One of the most common requirements for Shopify Plus merchants is offering a last-minute upsell product right before the payment step. Here is how you build a basic upsell component using React and the @shopify/ui-extensions-react/checkout library.

import {
  render,
  useCartLines,
  useApplyCartLinesChange,
  BlockStack,
  Button,
  Text,
  Image,
  InlineLayout
} from '@shopify/ui-extensions-react/checkout';

render('Checkout::Dynamic::Render', () => );

function UpsellOffer() {
  const lines = useCartLines();
  const applyCartLinesChange = useApplyCartLinesChange();

  // Simple logic: If they don't have the premium warranty, offer it.
  const hasWarranty = lines.some(line => line.merchandise.title.includes('Warranty'));

  if (hasWarranty) {
    return null;
  }

  const handleAddWarranty = async () => {
    const result = await applyCartLinesChange({
      type: 'addCartLine',
      merchandiseId: 'gid://shopify/ProductVariant/123456789',
      quantity: 1,
    });
    if (result.type === 'error') {
      console.error(result.message);
    }
  };

  return (
    
      Protect your purchase!
      
        
        Add a 2-year premium warranty for only $19.99
        
      
    
  );
}

Understanding the Security Sandbox

Because extensions run in a Web Worker, you do not have access to the standard DOM. You cannot use document.getElementById(), inject CSS, or use external UI libraries like Tailwind or Material UI. You must use the strictly defined UI components provided by Shopify (like BlockStack, InlineLayout, and Text) which map natively to the checkout's visual design.

Network Requests and Storefront API

If your extension needs to fetch product details dynamically (e.g., querying related products), you must make authenticated requests to your app's backend or the Storefront API. Shopify provides the useSessionToken() hook to verify the identity of the buyer and securely authenticate calls to your backend infrastructure.