Help us improve
Share bugs, ideas, or general feedback.
From saleor-commerce
Build Next.js/React apps for Saleor storefronts/Apps with App Router conventions, server/client components, GraphQL integration, MacawUI, and Tailwind CSS.
npx claudepluginhub orcaqubits/agentic-commerce-skills-plugins --plugin saleor-commerceHow this skill is triggered — by the user, by Claude, or both
Slash command
/saleor-commerce:nextjs-reactThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Fetch live docs**:
Builds Next.js storefronts for Saleor with GraphQL client setup (urql/Apollo), channel routing, Tailwind CSS, server components, checkout flow, and SEO.
Provides best practices, UI/UX patterns, and guidance for ecommerce storefronts: checkout, cart, products, navigation, homepage. Integrates Medusa backend; framework-agnostic (Next.js, React, Vue).
Provides patterns for Next.js 15 storefronts with Medusa v2: App Router structure, server/client components, JS SDK integration, data fetching, caching, server actions.
Share bugs, ideas, or general feedback.
Fetch live docs:
site:nextjs.org docs app for current Next.js App Router documentationsite:docs.saleor.io storefront for Saleor storefront development guidesite:github.com saleor storefront for the official Saleor storefront template sourcesite:github.com saleor macaw-ui for MacawUI component library referencesaleor app template Next.js saleor-app-sdk for App development patternshttps://docs.saleor.io/docs/developer/app-store/apps/overview for App architecture| File | Purpose | Rendering |
|---|---|---|
layout.tsx | Shared layout wrapping child routes | Server component (default) |
page.tsx | Unique UI for a route segment | Server component (default) |
loading.tsx | Loading UI (React Suspense) | Server component |
error.tsx | Error boundary for route segment | Client component (required) |
not-found.tsx | 404 UI for route segment | Server component |
template.tsx | Re-rendered layout (no state persistence) | Server component |
route.ts | API route handler | Server-only |
| Route | Segment | Purpose |
|---|---|---|
/[channel] | Dynamic channel | Multi-channel routing |
/[channel]/products | Product listing | Category/collection pages |
/[channel]/products/[slug] | Product detail | Single product page |
/[channel]/cart | Cart | Shopping cart |
/[channel]/checkout | Checkout | Checkout flow |
/[channel]/account | Account | Customer dashboard |
/[channel]/search | Search | Product search results |
[channel] for multi-channel support(storefront) and (dashboard) to organize layouts| Criterion | Server Component | Client Component |
|---|---|---|
| Data fetching | Fetch directly (no waterfall) | Use useQuery hooks |
| SEO critical | Yes (HTML in response) | No (client-rendered) |
| Interactivity | None (static output) | Click, input, state |
| Hooks | Cannot use hooks | useState, useEffect, etc. |
| Bundle size | Zero JS sent to client | Included in JS bundle |
| Component | Type | Reason |
|---|---|---|
| Product list page | Server | SEO, data fetching |
| Product detail page | Server | SEO, data fetching |
| Add to cart button | Client | Interactivity, state |
| Cart sidebar | Client | State management, animation |
| Checkout form | Client | Form state, validation |
| Search bar | Client | Input handling, debounce |
| Navigation | Server | Static, SEO links |
| Price display | Server | Channel-aware, static |
"use client" only when needed; pass server-fetched data as props to client components| Package | Purpose |
|---|---|
@urql/core | Core urql client |
@urql/next | Next.js App Router integration |
graphql | GraphQL parsing (peer dependency) |
| Concern | Implementation |
|---|---|
| Server client | Create urql client in server utility, use in server components |
| Client provider | Wrap client components with UrqlProvider in layout |
| Auth header | Add Authorization: Bearer <token> via fetchOptions |
| Channel header | Add saleor-channel: <slug> via fetchOptions |
| SSR | Use @urql/next for SSR data hydration |
@apollo/client with @apollo/experimental-nextjs-app-support| Pattern | Where | How |
|---|---|---|
| Server component fetch | page.tsx, layout.tsx | await client.query() directly |
| Client query hook | "use client" components | useQuery(Document, { variables }) |
| Server action | Form submissions | "use server" functions calling GraphQL |
| Route handler | route.ts | API endpoint calling Saleor GraphQL |
| Parallel fetching | Server component | Promise.all([query1, query2]) |
Promise.all for parallel independent queries| Strategy | Scope | Configuration |
|---|---|---|
| Static | Build time | export const revalidate = false |
| ISR | Time-based revalidation | export const revalidate = 60 (seconds) |
| On-demand | Webhook-triggered | revalidatePath() or revalidateTag() |
| No cache | Always fresh | export const dynamic = "force-dynamic" |
| Page | Strategy | Rationale |
|---|---|---|
| Product listing | ISR (60s) | Content changes infrequently |
| Product detail | ISR (60s) + on-demand | Revalidate on product webhook |
| Cart / Checkout | No cache | User-specific, transactional |
| Static pages | Static | CMS content, rarely changes |
| Variable | Where | Purpose |
|---|---|---|
NEXT_PUBLIC_SALEOR_API_URL | Client + Server | Saleor GraphQL endpoint |
SALEOR_API_URL | Server only | Server-side GraphQL endpoint |
NEXT_PUBLIC_DEFAULT_CHANNEL | Client + Server | Default channel slug |
SALEOR_APP_TOKEN | Server only | App token for authenticated queries |
NEXT_PUBLIC_ for client-accessible variables| Step | Action |
|---|---|
| Install | npm install -D tailwindcss @tailwindcss/postcss postcss |
| Configure | Add @tailwindcss/postcss to postcss.config.js |
| Content paths | Set content in tailwind.config.ts to include all component files |
| Global import | Add @import "tailwindcss" to globals.css |
MacawUI is the Saleor Dashboard component library used in Saleor Apps:
| Component Category | Examples |
|---|---|
| Layout | Box, Layout, Sidebar |
| Forms | Input, Select, Checkbox, Multiselect |
| Data display | List, Table, Chip, Tag |
| Feedback | Alert, Banner, Skeleton |
| Actions | Button, IconButton, Dropdown |
| Context | UI Library | Reason |
|---|---|---|
| Saleor App (Dashboard iframe) | MacawUI | Consistent Dashboard look and feel |
| Storefront | Tailwind CSS / custom | Brand-specific design |
npm install @saleor/macaw-ui<ThemeProvider> from MacawUI| Feature | Configuration |
|---|---|
| next/image | Use for all product and media images |
| Remote patterns | Add Saleor media domain to next.config.js images.remotePatterns |
| Sizes | Set sizes attribute for responsive images |
| Priority | Add priority to above-the-fold images (hero, first product) |
| Formats | Next.js auto-serves WebP/AVIF when supported |
"use client" only for interactivitypage.tsx, layout.tsx, error.tsx) consistentlysaleor-channel header in all GraphQL client configurationsnext/image and configure remote patterns for Saleor mediaFetch the Next.js and Saleor storefront documentation for current App Router patterns, GraphQL client setup, and component conventions before implementing.