--- name: shopify-polaris-design description: Design and implement Shopify Admin interfaces using the Polaris Design System. Use this skill when building Shopify Apps, Admin extensions, or any interface that needs to feel native to Shopify. --- This skill ensures that interfaces are built using Shopify's Polaris Design System (React implementation v13.x), guaranteeing a native, accessible, and professional look and feel for Shopify Merchants. > **Note (2025-2026)**: Polaris React (`@shopify/polaris`) is in **maintenance mode**. Shopify has introduced Polaris Web Components for new development. However, Polaris React remains fully functional and supported for existing applications. This guide covers the React implementation. ## Core Principles 1. **Merchant-Focused**: Design for efficiency and clarity. Merchants use these tools to run their business. 2. **Native Feel**: The app should feel like a natural extension of the Shopify Admin. Do not introduce foreign design patterns (e.g. Material Design shadows, distinct bootstappy buttons) unless absolutely necessary. 3. **Accessibility**: Polaris is built with accessibility in mind. Maintain this by using semantic components (e.g., `Button`, `Link`, `TextField`) rather than custom `div` implementations. 4. **Predictability**: Follow standard Shopify patterns. Save buttons go in the App Bridge Save Bar. Page actions go in the top right. Primary content is centered. ## Technical Implementation ### Dependencies (v13.x - 2025-2026) ```json { "@shopify/polaris": "^13.9.0", "@shopify/polaris-icons": "^9.x", "@shopify/app-bridge-react": "^4.x" } ``` ### App Bridge Integration (Critical for v13.x) Many UI components are now handled by **App Bridge** instead of Polaris React: | Deprecated Polaris Component | Use App Bridge Instead | |------------------------------|------------------------| | `Modal` | `@shopify/app-bridge-react` Modal API | | `Navigation` | App Bridge Navigation Menu API | | `Toast` | App Bridge Toast API | | `ContextualSaveBar` | App Bridge `useSaveBar()` hook | | `TopBar` | App Bridge Title Bar API | | `Loading` | App Bridge Loading API | ```jsx // Example: Using App Bridge for Modal (instead of deprecated Polaris Modal) import { Modal, TitleBar } from '@shopify/app-bridge-react'; function MyComponent() { return (

Are you sure you want to proceed?

); } // Example: Using App Bridge for Toast import { useAppBridge } from '@shopify/app-bridge-react'; function showToast() { shopify.toast.show('Product saved successfully'); } // Example: Using App Bridge Save Bar import { useSaveBar } from '@shopify/app-bridge-react'; function SettingsForm() { const saveBar = useSaveBar(); useEffect(() => { if (hasChanges) { saveBar.show(); } else { saveBar.hide(); } }, [hasChanges]); } ``` ### Fundamental Components - **AppProvider**: All Polaris apps must be wrapped in ``. - **Page**: The top-level container for a route. Always set `title` and `primaryAction` (if applicable). ```jsx ``` > **v13.x Note**: `backAction` prop in `Page.Header` is deprecated. Use App Bridge navigation instead for complex navigation patterns. - **Layout**: Use `Layout` and `Layout.Section` to structure content. - `Layout.AnnotatedSection`: For settings pages (Title/Description on left, Card on right). - `Layout.Section`: Standard Full (default), 1/2 (`variant="oneHalf"`), or 1/3 (`variant="oneThird"`) width columns. - **Card**: The primary container for content pieces. Group related information in a Card. - Use `BlockStack` (vertical) or `InlineStack` (horizontal) for internal layout within a Card. - **Do not** use `LegacyCard` - it is deprecated. Use `Card` with layout primitives. ### Layout Primitives (Modern Pattern) ```jsx import { Box, BlockStack, InlineStack, InlineGrid, Bleed, Divider } from '@shopify/polaris'; // Box - Low-level layout primitive with full token access Content here // BlockStack - Vertical stacking with gap // InlineStack - Horizontal layout with alignment Label // InlineGrid - Responsive grid layout ... ... ... // Bleed - Negative margin for edge-to-edge content ``` ### Data Display - **IndexTable**: For lists of objects (Products, Orders) with bulk actions and filtering. ```jsx import { IndexTable, Card, Text, Badge, useIndexResourceState } from '@shopify/polaris'; function ProductList({ products }) { const { selectedResources, allResourcesSelected, handleSelectionChange } = useIndexResourceState(products); const rowMarkup = products.map((product, index) => ( {product.name} {product.sku} {product.status} )); return ( {rowMarkup} ); } ``` - **DataTable**: For simple, non-interactive data grids (e.g., analytics data). - **ResourceList**: For simpler lists without table structure (use `ResourceItem` for each item). ### Form Design ```jsx import { Form, FormLayout, TextField, Select, Checkbox, ChoiceList, RadioButton, RangeSlider, ColorPicker, DropZone, Tag, Autocomplete } from '@shopify/polaris'; function ProductForm() { const [formState, setFormState] = useState({ title: '', description: '', status: 'draft', tags: [], }); const [errors, setErrors] = useState({}); return (
setFormState({...formState, title: value})} error={errors.title} autoComplete="off" helpText="This will be displayed to customers" /> setFormState({...formState, description: value})} multiline={4} autoComplete="off" />