dist/codex/saleor-commerce/skills/nextjs-react/SKILL.md
Build Next.js and React applications for Saleor — App Router, server and client components, GraphQL client integration, MacawUI in Apps, and Tailwind CSS. Use when building Saleor storefronts or Apps with Next.js.
npx skillsauth add orcaqubits/agentic-commerce-claude-plugins nextjs-reactInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
development
Build with Spree's headless Next.js storefront — the official `spree/storefront` repo (Next.js 16 App Router with Server Actions and Turbopack, React 19 Server Components, Tailwind CSS 4, TypeScript 5, `@spree/sdk`, Sentry), server-only auth (httpOnly JWT cookies + publishable key), MeiliSearch faceted catalog, one-page checkout with Apple/Google Pay/Klarna/Affirm/SEPA, multi-region market routing, GA4 + JSON-LD SEO, and Vercel/Docker deployment. Use when forking or customizing the storefront, or evaluating headless adoption.
tools
Build Spree extensions as Rails engines — gem scaffolding, `bin/rails g spree:extension`, mounting routes/migrations/assets, the modern `prepend` decorator pattern (`*_decorator.rb` with `self.prepended(base)`), generators (`spree:model_decorator`, `spree:controller_decorator`), the four customization surfaces in preference order (Events > Webhooks > Dependencies > Decorators), Spree::Dependencies for swapping service objects, gem release/versioning, and the deprecated Deface engine. Use when building a reusable Spree extension or adding non-trivial customization to an app.
development
Build with Spree's event bus and Webhooks 2.0 — `Spree::Events` publication, `Spree::Subscriber` DSL with `subscribes_to` and `on`, wildcard matching, lifecycle events (`{model}.created/.updated/.deleted` via `publishes_lifecycle_events`), the canonical event catalog (order.*, payment.*, shipment.*, product.*), Webhooks 2.0 endpoints, HMAC-SHA256 signing (`X-Spree-Webhook-Signature`), exponential-backoff retries, and Sidekiq job orchestration. Use when wiring event-driven business logic, building webhook consumers, or replacing ActiveSupport callback chains.
tools
Cross-cutting Spree development patterns — the customization preference hierarchy (Events > Webhooks > Dependencies > Decorators), `Spree::Dependencies` service-object swapping, the `_decorator.rb` + `prepend` + `self.prepended` idiom, idempotent subscribers and webhook receivers, multi-store scoping discipline, prefixed IDs, calculator polymorphism (shipping/promotion/tax share the base), service-object composition with `dry-monads` or simple results, why to avoid `class_eval` reopening and Deface, and Spree-on-Rails idioms (Hotwire/Turbo Stimulus, ActiveStorage, Action Cable, Sidekiq). Use when designing the architecture of a Spree extension or solving cross-cutting concerns.