--- id: wiki-2026-0508-shopify-polaris title: Shopify Polaris category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Polaris, Shopify Design System, Polaris React] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [design-system, shopify, polaris, react, admin-ui] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: TypeScript framework: React + @shopify/polaris --- # Shopify Polaris ## 매 한 줄 > **"매 Polaris 는 Shopify 의 admin/merchant facing design system"**. React component lib + design guidelines + token (SCSS/CSS vars) 패키지. App Bridge 와 함께 매 Shopify embedded app 의 standard UI. 2026 기준 v13 — modular import + CSS vars + dark mode 지원, App Bridge React 4.x 와 통합. ## 매 핵심 ### 매 패키지 - `@shopify/polaris`: React components + tokens - `@shopify/app-bridge-react`: 매 embedded app 의 host iframe API - `@shopify/polaris-icons`: SVG icon set ### 매 design principles - "Built for Shopify" — merchant 가 Shopify Admin 에 익숙 - Workflow centric (page · card · resource list · index table) - Accessibility first (WCAG 2.1 AA) ### 매 응용 1. Shopify Admin custom app (embedded). 2. Shopify storefront builder tools. 3. Internal merchant ops dashboards. ## 💻 패턴 ### App provider + i18n ```tsx import { AppProvider, Page, Card, Text } from "@shopify/polaris"; import "@shopify/polaris/build/esm/styles.css"; import enTranslations from "@shopify/polaris/locales/en.json"; export default function App() { return ( 매 orders here ); } ``` ### Embedded app with App Bridge ```tsx // app/providers.tsx "use client"; import { AppProvider } from "@shopify/polaris"; import { Provider as AppBridge } from "@shopify/app-bridge-react"; import enTranslations from "@shopify/polaris/locales/en.json"; export function Providers({ children, apiKey, host, }: { children: React.ReactNode; apiKey: string; host: string }) { return ( {children} ); } ``` ### IndexTable (Shopify-style data grid) ```tsx import { IndexTable, Text, useIndexResourceState } from "@shopify/polaris"; const orders = [ { id: "1001", customer: "Alice", total: "$120" }, { id: "1002", customer: "Bob", total: "$45" }, ]; export function OrdersTable() { const { selectedResources, allResourcesSelected, handleSelectionChange } = useIndexResourceState(orders); return ( {orders.map((o, i) => ( #{o.id} {o.customer} {o.total} ))} ); } ``` ### Form + Banner + Toast ```tsx import { Form, FormLayout, TextField, Button, Banner, Frame, Toast } from "@shopify/polaris"; import { useState, useCallback } from "react"; export function ProductForm() { const [name, setName] = useState(""); const [error, setError] = useState(); const [toast, setToast] = useState(false); const submit = useCallback(async () => { if (!name.trim()) { setError("매 name required"); return; } setError(undefined); // await api.create({ name }); setToast(true); }, [name]); return ( {error && {error}}
{toast && setToast(false)} />} ); } ``` ### Resource picker via App Bridge ```tsx "use client"; import { useAppBridge } from "@shopify/app-bridge-react"; import { Button } from "@shopify/polaris"; export function PickProduct() { const shopify = useAppBridge(); async function open() { const selected = await shopify.resourcePicker({ type: "product", multiple: true }); if (selected) console.log("picked", selected); } return ; } ``` ### Navigation ```tsx import { Frame, Navigation } from "@shopify/polaris"; import { HomeIcon, OrderIcon, ProductIcon } from "@shopify/polaris-icons"; export function Shell({ children }: { children: React.ReactNode }) { const nav = ( ); return {children}; } ``` ### Polaris tokens in custom CSS ```css .custom-card { background: var(--p-color-bg-surface); color: var(--p-color-text); padding: var(--p-space-400); border-radius: var(--p-border-radius-200); } ``` ### Server Action with Polaris UI feedback ```tsx "use client"; import { Button, Toast, Frame } from "@shopify/polaris"; import { useState, useTransition } from "react"; import { syncProducts } from "./actions"; export function SyncButton() { const [pending, start] = useTransition(); const [done, setDone] = useState(false); return ( {done && setDone(false)} />} ); } ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Shopify embedded app | **Polaris + App Bridge** | | Public storefront | Hydrogen (다른 stack) | | Non-Shopify admin | shadcn/ui or other DS | | Shopify ecosystem reuse | Polaris (familiarity) | **기본값**: Shopify embedded app → Polaris v13 + App Bridge React 4.x. Storefront 는 Hydrogen. ## 🔗 Graph - 부모: [[Design System]] - 변형: [[shadcn/ui]] ## 🤖 LLM 활용 **언제**: Shopify embedded app scaffold, Shopify admin tooling, merchant-facing UX. **언제 X**: Non-Shopify product (merchant-context UX 가 어색), 매 storefront (Hydrogen). ## ❌ 안티패턴 - **Polaris outside Shopify**: 매 brand bleed — non-Shopify product 에 Polaris UI. - **Skipping AppProvider**: i18n / theme 깨짐. - **Custom UI for embedded**: 매 merchant 혼동 — Polaris 우선. - **Forgetting App Bridge**: embedded app 에서 navigation/resource picker 못함. - **Bypassing tokens**: hex code 직접 → dark mode 깨짐. ## 🧪 검증 / 중복 - Verified (polaris.shopify.com docs, App Bridge React docs, 2026). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — Shopify Polaris full content |