Polaris composition patterns and page templates for common Shopify app layouts. Provides index tables, settings pages, dashboards, and resource management patterns. Auto-invoked when building page layouts.
Install
npx skillscat add sarojpunde/shopify-dev-toolkit-claude-plugins/polaris-compositions Install via the SkillsCat registry.
SKILL.md
Polaris Compositions Skill
Purpose
Provides complete page templates and composition patterns for common Shopify app layouts using Polaris Web Components.
When This Skill Activates
- Creating new pages or views
- Building index/list pages
- Implementing settings interfaces
- Designing dashboards
- Creating resource management UIs
Available Patterns
Reference: polaris-web-components/patterns/compositions/
Composition Patterns
- App Card - Application summary cards with actions
- Resource List - Filterable, sortable resource lists
- Settings - Settings page layouts with sections
- Callout Card - Promotional or informational cards
- Account Connection - Third-party service integrations
- Details - Detailed information displays
- Index Table - Data tables with bulk actions
- Metrics Card - Statistics and KPI displays
- Setup Guide - Onboarding checklists
- Homepage - App homepage/dashboard layouts
- Sticky Pagination - Persistent pagination controls
- Interstitial Nav - Multi-step navigation flows
- Footer Help - Contextual help sections
- Media Card - Rich media content cards
- Empty State - No content placeholders
Complete Page Templates
Index/List Page Template
Use for: Products, Orders, Customers, Collections
<s-page
heading="Products"
primaryAction={{ content: "Add Product", url: "/products/new" }}
>
{/* Stats Cards */}
<s-section>
<s-grid columns="1" md-columns="3" gap="400">
<s-box border="base" borderRadius="base" padding="400">
<s-stack gap="200" direction="vertical">
<s-text variant="headingMd">Total Products</s-text>
<s-text variant="heading2xl">{stats.total}</s-text>
</s-stack>
</s-box>
<s-box border="base" borderRadius="base" padding="400">
<s-stack gap="200" direction="vertical">
<s-text variant="headingMd">Active</s-text>
<s-text variant="heading2xl">{stats.active}</s-text>
<s-badge tone="success">+12%</s-badge>
</s-stack>
</s-box>
<s-box border="base" borderRadius="base" padding="400">
<s-stack gap="200" direction="vertical">
<s-text variant="headingMd">Draft</s-text>
<s-text variant="heading2xl">{stats.draft}</s-text>
</s-stack>
</s-box>
</s-grid>
</s-section>
{/* Filters */}
<s-section>
<s-card>
<s-stack gap="300" alignment="space-between">
<s-search-field
placeholder="Search products..."
value={searchQuery}
/>
<s-select
label="Status"
options={[
{ label: "All", value: "all" },
{ label: "Active", value: "active" },
{ label: "Draft", value: "draft" },
]}
/>
</s-stack>
</s-card>
</s-section>
{/* Data Table */}
<s-section>
{products.length === 0 ? (
<s-card>
<s-empty-state
heading="No products found"
image="https://cdn.shopify.com/..."
>
<s-text>Try adjusting your filters or add a new product</s-text>
<s-button variant="primary" url="/products/new">
Add Product
</s-button>
</s-empty-state>
</s-card>
) : (
<s-card>
<s-table>
<s-table-head>
<s-table-row>
<s-table-cell as="th">Product</s-table-cell>
<s-table-cell as="th">Status</s-table-cell>
<s-table-cell as="th">Inventory</s-table-cell>
<s-table-cell as="th">Price</s-table-cell>
<s-table-cell as="th">Actions</s-table-cell>
</s-table-row>
</s-table-head>
<s-table-body>
{products.map(product => (
<s-table-row key={product.id}>
<s-table-cell>
<s-stack gap="200">
<s-thumbnail source={product.image} size="small" />
<s-text>{product.title}</s-text>
</s-stack>
</s-table-cell>
<s-table-cell>
<s-badge tone={product.active ? "success" : undefined}>
{product.active ? "Active" : "Draft"}
</s-badge>
</s-table-cell>
<s-table-cell>{product.inventory} in stock</s-table-cell>
<s-table-cell>${product.price}</s-table-cell>
<s-table-cell>
<s-button-group>
<s-button variant="plain" url={`/products/${product.id}`}>
Edit
</s-button>
<s-button variant="plain" tone="critical">
Delete
</s-button>
</s-button-group>
</s-table-cell>
</s-table-row>
))}
</s-table-body>
</s-table>
{/* Pagination */}
<s-box padding="400">
<s-stack gap="200" alignment="center">
<s-button disabled={page === 1}>Previous</s-button>
<s-text>Page {page} of {totalPages}</s-text>
<s-button disabled={page === totalPages}>Next</s-button>
</s-stack>
</s-box>
</s-card>
)}
</s-section>
</s-page>Settings Page Template
<s-page heading="Settings">
{/* General Settings */}
<s-section>
<s-card>
<s-stack gap="400" direction="vertical">
<s-heading>General</s-heading>
<s-text-field
label="Store Name"
value={settings.storeName}
helpText="This appears in your emails and online store"
/>
<s-text-field
label="Contact Email"
type="email"
value={settings.contactEmail}
/>
<s-text-field
label="Customer Support Email"
type="email"
value={settings.supportEmail}
/>
</s-stack>
</s-card>
</s-section>
{/* Notifications */}
<s-section>
<s-card>
<s-stack gap="400" direction="vertical">
<s-heading>Notifications</s-heading>
<s-text tone="subdued">
Choose which notifications you want to receive
</s-text>
<s-divider />
<s-checkbox
label="Email notifications"
checked={settings.emailNotifications}
helpText="Receive updates via email"
/>
<s-checkbox
label="Order notifications"
checked={settings.orderNotifications}
helpText="Get notified about new orders"
/>
<s-checkbox
label="Customer messages"
checked={settings.customerMessages}
helpText="Receive customer inquiries"
/>
</s-stack>
</s-card>
</s-section>
{/* Advanced Settings */}
<s-section>
<s-card>
<s-stack gap="400" direction="vertical">
<s-heading>Advanced</s-heading>
<s-banner tone="warning">
<s-text>
These settings can affect your store's functionality.
Change with caution.
</s-text>
</s-banner>
<s-divider />
<s-checkbox
label="Enable API access"
checked={settings.apiEnabled}
/>
<s-checkbox
label="Debug mode"
checked={settings.debugMode}
/>
</s-stack>
</s-card>
</s-section>
{/* Save Section */}
<s-section>
<s-stack gap="300" alignment="trailing">
<s-button>Reset to Defaults</s-button>
<s-button variant="primary">Save Settings</s-button>
</s-stack>
</s-section>
</s-page>Dashboard/Homepage Template
<s-page heading="Dashboard">
{/* Welcome Message */}
<s-section>
<s-banner tone="info">
<s-stack gap="200" direction="vertical">
<s-text variant="headingMd">Welcome back!</s-text>
<s-text>
You have 3 orders to fulfill and 2 customer messages.
</s-text>
</s-stack>
</s-banner>
</s-section>
{/* Key Metrics */}
<s-section>
<s-grid columns="1" md-columns="2" lg-columns="4" gap="400">
<s-box border="base" borderRadius="base" padding="400">
<s-stack gap="200" direction="vertical">
<s-text variant="headingMd">Today's Sales</s-text>
<s-text variant="heading2xl">$2,453</s-text>
<s-badge tone="success">+15% from yesterday</s-badge>
</s-stack>
</s-box>
<s-box border="base" borderRadius="base" padding="400">
<s-stack gap="200" direction="vertical">
<s-text variant="headingMd">Orders</s-text>
<s-text variant="heading2xl">34</s-text>
<s-badge>5 pending</s-badge>
</s-stack>
</s-box>
<s-box border="base" borderRadius="base" padding="400">
<s-stack gap="200" direction="vertical">
<s-text variant="headingMd">Conversion Rate</s-text>
<s-text variant="heading2xl">3.2%</s-text>
<s-badge tone="success">+0.3%</s-badge>
</s-stack>
</s-box>
<s-box border="base" borderRadius="base" padding="400">
<s-stack gap="200" direction="vertical">
<s-text variant="headingMd">Average Order</s-text>
<s-text variant="heading2xl">$72.15</s-text>
<s-badge tone="warning">-2%</s-badge>
</s-stack>
</s-box>
</s-grid>
</s-section>
{/* Quick Actions */}
<s-section>
<s-grid columns="1" md-columns="3" gap="400">
<s-card>
<s-stack gap="300" direction="vertical">
<s-heading>Orders</s-heading>
<s-text tone="subdued">5 orders need fulfillment</s-text>
<s-button url="/orders">Manage Orders</s-button>
</s-stack>
</s-card>
<s-card>
<s-stack gap="300" direction="vertical">
<s-heading>Products</s-heading>
<s-text tone="subdued">3 products low in stock</s-text>
<s-button url="/products">View Inventory</s-button>
</s-stack>
</s-card>
<s-card>
<s-stack gap="300" direction="vertical">
<s-heading>Customers</s-heading>
<s-text tone="subdued">2 messages waiting</s-text>
<s-button url="/customers">View Messages</s-button>
</s-stack>
</s-card>
</s-grid>
</s-section>
{/* Recent Activity */}
<s-section>
<s-card>
<s-stack gap="400" direction="vertical">
<s-heading>Recent Orders</s-heading>
<s-table>
<s-table-head>
<s-table-row>
<s-table-cell as="th">Order</s-table-cell>
<s-table-cell as="th">Customer</s-table-cell>
<s-table-cell as="th">Total</s-table-cell>
<s-table-cell as="th">Status</s-table-cell>
</s-table-row>
</s-table-head>
<s-table-body>
{recentOrders.map(order => (
<s-table-row key={order.id}>
<s-table-cell>#{order.number}</s-table-cell>
<s-table-cell>{order.customer}</s-table-cell>
<s-table-cell>${order.total}</s-table-cell>
<s-table-cell>
<s-badge tone={order.fulfilled ? "success" : "warning"}>
{order.fulfilled ? "Fulfilled" : "Pending"}
</s-badge>
</s-table-cell>
</s-table-row>
))}
</s-table-body>
</s-table>
</s-stack>
</s-card>
</s-section>
</s-page>Pattern Components Reference
For detailed pattern documentation, see:
polaris-web-components/patterns/compositions/- All composition patternspolaris-web-components/patterns/templates/- Complete page templates
Quick Pattern Reference
| Pattern | File | Use Case |
|---|---|---|
| Index Table | index-table.md |
Product lists, order lists |
| Settings | settings.md |
App configuration pages |
| Homepage | homepage.md |
Dashboard layouts |
| Empty State | empty-state.md |
No content states |
| Metrics Card | metrics-card.md |
KPI displays |
| Resource List | resource-list.md |
Filterable lists |
| Setup Guide | setup-guide.md |
Onboarding flows |
Best Practices
- Follow Templates - Use established templates for common pages
- Consistent Layout - Maintain consistent structure across pages
- Progressive Disclosure - Show advanced options only when needed
- Clear Hierarchy - Use sections to organize content logically
- Actionable CTAs - Make primary actions obvious
- Empty States - Always provide guidance when no data exists
- Loading States - Show skeletons during data fetch
- Error Handling - Display clear, actionable error messages
- Mobile Responsive - All patterns work on mobile devices
- Accessibility - Ensure keyboard navigation and screen readers work
Remember: Using established patterns improves UX consistency and reduces development time.