> ## Documentation Index
> Fetch the complete documentation index at: https://docs.synapsebuilder.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Extension Standards

> Shopify quality guidelines and best practices

## Overview

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

## Quality Requirements

<CardGroup cols={2}>
  <Card title="Performance" icon="gauge-high">
    Fast loading and responsive

    * Load in under 500ms
    * No blocking operations
    * Optimized bundle size
    * Efficient re-renders
  </Card>

  <Card title="Accessibility" icon="universal-access">
    Usable by everyone

    * Keyboard navigation
    * Screen reader support
    * Sufficient color contrast
    * Clear focus states
  </Card>

  <Card title="User Experience" icon="face-smile">
    Intuitive and helpful

    * Clear messaging
    * Proper error handling
    * Loading states
    * Mobile-optimized
  </Card>

  <Card title="Security" icon="shield">
    Safe and compliant

    * Data validation
    * Secure API calls
    * No sensitive data exposure
    * GDPR compliant
  </Card>
</CardGroup>

## Shopify's Extension Guidelines

### 1. Performance Standards

Extensions must meet these performance benchmarks:

| Metric                  | Requirement | Best Practice |
| ----------------------- | ----------- | ------------- |
| **Initial Load**        | \< 500ms    | \< 300ms      |
| **Bundle Size**         | \< 50KB     | \< 30KB       |
| **Time to Interactive** | \< 1s       | \< 500ms      |
| **Memory Usage**        | \< 5MB      | \< 3MB        |

<Tabs>
  <Tab title="What Synapse Does">
    ✅ Generates minimal, optimized code

    ✅ Only imports used components

    ✅ Avoids unnecessary dependencies

    ✅ Uses React.memo for expensive renders

    ✅ Lazy loads non-critical features
  </Tab>

  <Tab title="What You Should Avoid">
    ❌ Large dependencies (lodash, moment, etc.)

    ❌ Inline large data sets

    ❌ Synchronous blocking operations

    ❌ Unnecessary re-renders

    ❌ Multiple API calls on load
  </Tab>
</Tabs>

### 2. Accessibility (A11y)

Extensions must be accessible to all users:

<AccordionGroup>
  <Accordion title="Keyboard Navigation" icon="keyboard">
    All interactive elements must be keyboard accessible:

    ```tsx theme={null}
    // 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
  </Accordion>

  <Accordion title="Screen Readers" icon="volume">
    Content must be readable by screen readers:

    ```tsx theme={null}
    // 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
  </Accordion>

  <Accordion title="Color Contrast" icon="palette">
    Text must have sufficient contrast:

    | Element       | Min Contrast | WCAG Level |
    | ------------- | ------------ | ---------- |
    | Body text     | 4.5:1        | AA         |
    | Large text    | 3:1          | AA         |
    | UI components | 3:1          | AA         |

    **Synapse automatically:**

    * Uses Shopify UI components (compliant by default)
    * Avoids custom colors
    * Tests contrast ratios
  </Accordion>

  <Accordion title="Focus States" icon="bullseye">
    Interactive elements must show focus:

    ```tsx theme={null}
    // 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
  </Accordion>
</AccordionGroup>

### 3. User Experience

<Steps>
  <Step title="Clear Messaging">
    Tell users what your extension does:

    ```tsx theme={null}
    <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
  </Step>

  <Step title="Loading States">
    Show when processing:

    ```tsx theme={null}
    {loading ? (
      <SkeletonText />
    ) : (
      <Text>{deliveryDate}</Text>
    )}
    ```

    * Use skeleton loaders
    * Show progress bars
    * Don't block interaction
  </Step>

  <Step title="Error Handling">
    Handle failures gracefully:

    ```tsx theme={null}
    {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
  </Step>

  <Step title="Mobile Optimization">
    70%+ of checkout is mobile:

    * Touch targets ≥ 44×44px
    * Readable text (≥ 16px)
    * No horizontal scroll
    * Thumb-friendly layout
  </Step>
</Steps>

### 4. Security & Privacy

<CardGroup cols={2}>
  <Card title="Data Validation" icon="filter">
    Validate all inputs:

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

  <Card title="Secure API Calls" icon="lock">
    Use HTTPS and authentication:

    ```tsx theme={null}
    const response = await fetch(
      'https://your-api.com/endpoint',
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json'
        }
      }
    );
    ```
  </Card>

  <Card title="No Sensitive Data" icon="eye-slash">
    Don't log or expose:

    * Credit card numbers
    * Passwords
    * API keys
    * Personal information
  </Card>

  <Card title="GDPR Compliance" icon="scale-balanced">
    Respect privacy:

    * Get consent for data collection
    * Allow data deletion
    * Provide privacy policy
    * Honor do-not-track
  </Card>
</CardGroup>

## Code Quality Standards

### TypeScript

All extensions must use TypeScript:

```tsx theme={null}
// 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:

```tsx theme={null}
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:

```tsx theme={null}
// 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:

<Steps>
  <Step title="Static Analysis">
    Checks code quality:

    * TypeScript compilation
    * ESLint rules
    * Import validation
    * Bundle size
  </Step>

  <Step title="API Validation">
    Verifies Shopify APIs:

    * Valid extension targets
    * Allowed components
    * Correct GraphQL queries
    * Proper hooks usage
  </Step>

  <Step title="Runtime Testing">
    Tests execution:

    * Loads without errors
    * Handles edge cases
    * Performance benchmarks
    * Memory leaks
  </Step>

  <Step title="Accessibility Audit">
    Checks A11y compliance:

    * Keyboard navigation
    * Screen reader support
    * Color contrast
    * Focus management
  </Step>
</Steps>

## Common Violations

Issues Synapse prevents:

<AccordionGroup>
  <Accordion title="Using Unsupported APIs">
    ❌ **Problem:** Calling APIs not in Shopify's allowlist

    ```tsx theme={null}
    // 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
  </Accordion>

  <Accordion title="Missing Error Handling">
    ❌ **Problem:** Unhandled promise rejections

    ```tsx theme={null}
    // 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
  </Accordion>

  <Accordion title="Performance Issues">
    ❌ **Problem:** Large bundles, blocking operations

    ```tsx theme={null}
    // Bad: Large dependency
    import _ from 'lodash';

    // Good: Use native methods
    const unique = [...new Set(array)];
    ```

    ✅ **Solution:** Synapse optimizes dependencies and code
  </Accordion>

  <Accordion title="Accessibility Failures">
    ❌ **Problem:** Missing labels, poor contrast

    ```tsx theme={null}
    // Bad: No label
    <input type="text" />

    // Good: Proper label
    <TextField label="Email address" />
    ```

    ✅ **Solution:** Synapse uses semantic components
  </Accordion>
</AccordionGroup>

## 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

<CardGroup cols={2}>
  <Card title="Validation" icon="check-circle" href="/concepts/validation">
    Learn how Synapse validates extensions
  </Card>

  <Card title="Debugging" icon="bug" href="/advanced/debugging">
    Debug issues and optimize performance
  </Card>

  <Card title="Best Practices" icon="star" href="/advanced/best-practices">
    Advanced optimization techniques
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/advanced/troubleshooting">
    Fix common issues
  </Card>
</CardGroup>
