Skip to main content

Overview

Shopify has quality standards for extensions that appear in the Shopify App Store. Synapse generates code that follows these standards automatically.

Quality Requirements

Performance

Fast loading and responsive
  • Load in under 500ms
  • No blocking operations
  • Optimized bundle size
  • Efficient re-renders

Accessibility

Usable by everyone
  • Keyboard navigation
  • Screen reader support
  • Sufficient color contrast
  • Clear focus states

User Experience

Intuitive and helpful
  • Clear messaging
  • Proper error handling
  • Loading states
  • Mobile-optimized

Security

Safe and compliant
  • Data validation
  • Secure API calls
  • No sensitive data exposure
  • GDPR compliant

Shopify’s Extension Guidelines

1. Performance Standards

Extensions must meet these performance benchmarks:
MetricRequirementBest Practice
Initial Load< 500ms< 300ms
Bundle Size< 50KB< 30KB
Time to Interactive< 1s< 500ms
Memory Usage< 5MB< 3MB
  • What Synapse Does
  • What You Should Avoid
✅ Generates minimal, optimized code✅ Only imports used components✅ Avoids unnecessary dependencies✅ Uses React.memo for expensive renders✅ Lazy loads non-critical features

2. Accessibility (A11y)

Extensions must be accessible to all users:
All interactive elements must be keyboard accessible:
// Good: Uses Button component with built-in keyboard support
<Button onPress={handleClick}>
  Submit
</Button>

// Bad: Custom div without keyboard handling
<div onClick={handleClick}>Submit</div>
Requirements:
  • Tab through all interactive elements
  • Enter/Space to activate buttons
  • Escape to close modals
  • Arrow keys for lists
Content must be readable by screen readers:
// Good: Semantic components with labels
<TextField
  label="Gift message"
  value={message}
  onChange={setMessage}
/>

// Good: Icon with accessible label
<Icon source="delivery" accessibilityLabel="Delivery truck" />

// Bad: Icon without label
<Icon source="delivery" />
Requirements:
  • Label all form inputs
  • Describe icons and images
  • Use semantic HTML
  • Announce dynamic changes
Text must have sufficient contrast:
ElementMin ContrastWCAG Level
Body text4.5:1AA
Large text3:1AA
UI components3:1AA
Synapse automatically:
  • Uses Shopify UI components (compliant by default)
  • Avoids custom colors
  • Tests contrast ratios
Interactive elements must show focus:
// Good: Shopify components have focus states
<Button onPress={handleClick}>Click me</Button>

// Focus appears as visible outline automatically
Requirements:
  • Visible focus indicator
  • Consistent across extension
  • Not removed with CSS

3. User Experience

1

Clear Messaging

Tell users what your extension does:
<Banner title="Estimated Delivery">
  <Text>
    Your order will arrive between Nov 5-8, 2025 
    based on your shipping address.
  </Text>
</Banner>
  • Use plain language
  • Be specific
  • Set expectations
2

Loading States

Show when processing:
{loading ? (
  <SkeletonText />
) : (
  <Text>{deliveryDate}</Text>
)}
  • Use skeleton loaders
  • Show progress bars
  • Don’t block interaction
3

Error Handling

Handle failures gracefully:
{error ? (
  <Banner status="critical">
    Unable to calculate delivery. Please try again.
    <Button onPress={retry}>Retry</Button>
  </Banner>
) : (
  <Content />
)}
  • Explain what went wrong
  • Offer solutions
  • Allow retry
4

Mobile Optimization

70%+ of checkout is mobile:
  • Touch targets ≥ 44×44px
  • Readable text (≥ 16px)
  • No horizontal scroll
  • Thumb-friendly layout

4. Security & Privacy

Data Validation

Validate all inputs:
const validateMessage = (msg: string) => {
  if (msg.length > 200) {
    return "Message too long";
  }
  if (/<script>/i.test(msg)) {
    return "Invalid characters";
  }
  return null;
};

Secure API Calls

Use HTTPS and authentication:
const response = await fetch(
  'https://your-api.com/endpoint',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    }
  }
);

No Sensitive Data

Don’t log or expose:
  • Credit card numbers
  • Passwords
  • API keys
  • Personal information

GDPR Compliance

Respect privacy:
  • Get consent for data collection
  • Allow data deletion
  • Provide privacy policy
  • Honor do-not-track

Code Quality Standards

TypeScript

All extensions must use TypeScript:
// Good: Fully typed
interface DeliveryEstimate {
  start: string;
  end: string;
  confidence: number;
}

function calculateDelivery(
  address: Address
): DeliveryEstimate {
  // Implementation
}

// Bad: Any types
function calculateDelivery(address: any): any {
  // Implementation
}

Error Boundaries

Catch and handle errors:
import { ErrorBoundary } from '@shopify/ui-extensions-react/checkout';

export default reactExtension(
  'purchase.checkout.block.render',
  () => (
    <ErrorBoundary
      onError={(error) => {
        console.error('Extension error:', error);
      }}
    >
      <Extension />
    </ErrorBoundary>
  )
);

Testing

Include tests for critical logic:
// Checkout.test.tsx
import { describe, it, expect } from 'vitest';
import { calculateDelivery } from './utils';

describe('calculateDelivery', () => {
  it('calculates correct dates', () => {
    const result = calculateDelivery({
      country: 'US',
      province: 'CA'
    });
    
    expect(result.start).toBeDefined();
    expect(result.end).toBeDefined();
  });
  
  it('handles invalid addresses', () => {
    const result = calculateDelivery({
      country: 'XX'
    });
    
    expect(result.error).toBe('Invalid country');
  });
});

Validation Process

Synapse validates extensions before deployment:
1

Static Analysis

Checks code quality:
  • TypeScript compilation
  • ESLint rules
  • Import validation
  • Bundle size
2

API Validation

Verifies Shopify APIs:
  • Valid extension targets
  • Allowed components
  • Correct GraphQL queries
  • Proper hooks usage
3

Runtime Testing

Tests execution:
  • Loads without errors
  • Handles edge cases
  • Performance benchmarks
  • Memory leaks
4

Accessibility Audit

Checks A11y compliance:
  • Keyboard navigation
  • Screen reader support
  • Color contrast
  • Focus management

Common Violations

Issues Synapse prevents:
Problem: Calling APIs not in Shopify’s allowlist
// Bad: Direct DOM manipulation
document.getElementById('checkout').style.color = 'red';

// Good: Use Shopify components
<Text appearance="critical">Error message</Text>
Solution: Synapse only generates code using approved APIs
Problem: Unhandled promise rejections
// Bad: No error handling
const data = await fetch('/api/data').then(r => r.json());

// Good: Try-catch with fallback
try {
  const data = await fetch('/api/data').then(r => r.json());
} catch (error) {
  console.error('Failed to fetch:', error);
  return <ErrorState />;
}
Solution: Synapse wraps API calls in error handlers
Problem: Large bundles, blocking operations
// Bad: Large dependency
import _ from 'lodash';

// Good: Use native methods
const unique = [...new Set(array)];
Solution: Synapse optimizes dependencies and code
Problem: Missing labels, poor contrast
// Bad: No label
<input type="text" />

// Good: Proper label
<TextField label="Email address" />
Solution: Synapse uses semantic components

App Store Requirements

If publishing to Shopify App Store:

Listing Requirements

  • Clear Description: Explain what your extension does
  • Screenshots: Show extension in action (3-5 images)
  • Privacy Policy: Link to privacy policy
  • Support Contact: Email or support URL

Technical Requirements

  • GDPR Compliance: Handle user data properly
  • Error Handling: Graceful failures
  • Documentation: User guide and setup instructions
  • Localization: Support multiple languages (if applicable)

Review Process

  1. Automated Testing: Shopify runs automated checks
  2. Manual Review: Human reviewers test functionality
  3. Approval: App is approved or feedback is provided
  4. Publication: Live in App Store

Best Practices Checklist

Before deploying extensions:
  • Loads in under 500ms
  • Bundle size under 50KB
  • All inputs are validated
  • Error states are handled
  • Loading states are shown
  • Keyboard accessible
  • Screen reader compatible
  • Sufficient color contrast
  • Works on mobile devices
  • No console errors
  • No memory leaks
  • Tests pass
  • TypeScript types complete
  • Documentation added

Next Steps