Skip to main content

Overview

In this tutorial, you’ll create a checkout extension that displays estimated delivery dates based on the customer’s shipping address.

What You’ll Build

A checkout extension that:
  • Shows a delivery estimate banner
  • Updates based on shipping address
  • Uses Shopify UI components
  • Follows best practices

Step 1: Write Your Prompt

Go to your Synapse dashboard and enter this prompt:
Create a checkout extension that displays estimated delivery dates 
based on the customer's shipping address. Show a banner with:
- An icon for visual appeal
- The delivery date range (5-7 business days)
- Different messaging for US vs international addresses
- Professional styling that matches Shopify's checkout

Step 2: Review Generated Code

Synapse will generate TypeScript/React code like this:
import {
  Banner,
  useShippingAddress,
  useApi,
} from '@shopify/ui-extensions-react/checkout';

export default function DeliveryEstimate() {
  const address = useShippingAddress();
  const { i18n } = useApi();
  
  // Calculate delivery window
  const getDeliveryEstimate = () => {
    if (!address?.countryCode) {
      return null;
    }
    
    const isDomestic = address.countryCode === 'US';
    const days = isDomestic ? '5-7' : '10-14';
    const deliveryDate = new Date();
    deliveryDate.setDate(deliveryDate.getDate() + (isDomestic ? 7 : 14));
    
    return {
      days,
      date: i18n.formatDate(deliveryDate, { dateStyle: 'long' })
    };
  };
  
  const estimate = getDeliveryEstimate();
  
  if (!estimate) return null;
  
  return (
    <Banner title="Estimated Delivery">
      Your order will arrive in {estimate.days} business days 
      (by {estimate.date})
    </Banner>
  );
}

Step 3: Validation

Synapse automatically validates your code:
✅ All Shopify UI components exist and are imported correctly
✅ React hooks are used properly (no conditional calls)
✅ Any GraphQL queries match Shopify’s schema
✅ Type safety and proper imports

Step 4: Self-Correction

If validation finds issues, Synapse automatically fixes them: Example Issue Found:
- import { Banner } from '@shopify/ui-extensions-react';
+ import { Banner } from '@shopify/ui-extensions-react/checkout';
Correction Applied:
  • ✅ Fixed in attempt 1
  • Validation score: 95/100

Step 5: Deployment

Click “Deploy” and Synapse will:
  1. Push to GitHub: Code is committed to your repository
  2. Create Fly.io Service: Container is built automatically
  3. Run Shopify CLI: Extension is deployed to your dev store
  4. Auto-Release: Latest version is released
🚀 Deploying delivery-estimate to Shopify...
🔗 Linking to Shopify app...
📦 Installing dependencies...
 Extension deployed successfully!
📦 Version: 2024.10.30.1
🔗 View in Partner Dashboard

Step 6: Test in Checkout

  1. Go to your Shopify dev store admin
  2. Navigate to Settings → Checkout
  3. Click Customize
  4. Add your “Delivery Estimate” extension from the sidebar
  5. Click Save
Now test the checkout:
  • Add a product to cart
  • Go to checkout
  • Enter different shipping addresses (US vs international)
  • See the delivery estimate update automatically

Next Steps

Customize Styling

Learn about Shopify’s design system

Add Settings

Make your extension configurable

Build Functions

Create discount or shipping functions

Deploy to Production

Launch on real stores

Common Variations

Add a Countdown Timer

const [timeLeft, setTimeLeft] = useState('');

useEffect(() => {
  const timer = setInterval(() => {
    const cutoff = new Date();
    cutoff.setHours(15, 0, 0, 0); // 3 PM cutoff
    
    const diff = cutoff - new Date();
    if (diff > 0) {
      const hours = Math.floor(diff / (1000 * 60 * 60));
      const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
      setTimeLeft(`${hours}h ${minutes}m`);
    }
  }, 1000);
  
  return () => clearInterval(timer);
}, []);

Show Shipping Method Impact

import { useShippingLine } from '@shopify/ui-extensions-react/checkout';

const shippingLine = useShippingLine();
const isExpedited = shippingLine?.code.includes('express');

return (
  <Banner>
    {isExpedited 
      ? 'Express delivery: 2-3 business days'
      : 'Standard delivery: 5-7 business days'
    }
  </Banner>
);

Troubleshooting

Make sure you’ve added it in the checkout editor at Settings → Checkout → Customize
Check that useShippingAddress() is imported from the correct package and the address object has a countryCode