Build consistent UI using Polaris Web Components patterns for common page layouts like index pages, detail pages, forms, and empty states. Use this skill when creating new pages or refactoring existing UI components.
View on GitHubsarojpunde/shopify-dev-toolkit-claude-plugins
shopify-pattern-enforcer
shopify-app-development/skills/polaris-ui-patterns/SKILL.md
January 21, 2026
Select agents to install to:
npx add-skill https://github.com/sarojpunde/shopify-dev-toolkit-claude-plugins/blob/main/shopify-app-development/skills/polaris-ui-patterns/SKILL.md -a claude-code --skill polaris-ui-patternsInstallation paths:
.claude/skills/polaris-ui-patterns/# Polaris UI Patterns Skill
## Purpose
This skill provides reusable UI patterns and templates for common page layouts in Shopify apps using Polaris Web Components.
## When to Use This Skill
- Creating new pages (index, detail, form)
- Implementing common UI patterns
- Building consistent layouts
- Adding empty states
- Creating modals and forms
- Implementing tables with actions
## Core Patterns
### Pattern 1: Index/List Page
**Use for**: Products, Orders, Customers, Custom Entities
```tsx
import type { LoaderFunctionArgs } from "react-router";
import { useLoaderData } from "react-router";
import { authenticate } from "../shopify.server";
import { db } from "../db.server";
import { json } from "@remix-run/node";
export const loader = async ({ request }: LoaderFunctionArgs) => {
const { session } = await authenticate.admin(request);
const shop = await db.shop.findUnique({
where: { shopDomain: session.shop }
});
const items = await db.item.findMany({
where: { shopId: shop.id },
orderBy: { createdAt: 'desc' },
take: 50,
});
const stats = {
total: items.length,
active: items.filter(i => i.isActive).length,
};
return json({ items, stats });
};
export default function ItemsIndexPage() {
const { items, stats } = useLoaderData<typeof loader>();
return (
<s-page heading="Items">
{/* Stats Section */}
<s-section>
<s-grid columns="3">
<s-box border="base" borderRadius="base" padding="400">
<s-stack gap="200" direction="vertical">
<s-text variant="headingMd" as="h3">Total Items</s-text>
<s-text variant="heading2xl" as="p">{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" as="h3">Active</s-text>
<s-text variant="heading2xl" as="p">{stats.active}</s-text>