dist/cursor/saleor-commerce/skills/saleor-apps/SKILL.md
Develop Saleor Apps — App manifest, saleor-app-sdk, Next.js template, permissions, token exchange, APL, App Bridge, and lifecycle management. Use when building Saleor App extensions.
npx skillsauth add orcaqubits/agentic-commerce-claude-plugins saleor-appsInstall 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:
https://docs.saleor.io/docs/developer/extending/apps/overview for Apps architecturesite:docs.saleor.io saleor app manifest structure for manifest referencesite:docs.saleor.io saleor-app-sdk token exchange APL for SDK utilitiessite:github.com saleor/saleor-app-template for latest Next.js App templatesite:docs.saleor.io app permissions for permission enumerationsite:docs.saleor.io app bridge dashboard extensions for Bridge APISaleor Apps are standalone web applications that extend Saleor functionality. They are not monolithic plugins embedded in the core -- each App is an independent service that communicates with Saleor via GraphQL and webhooks.
| Aspect | Detail | |--------|--------| | Deployment | Standalone web app (any host) | | Communication | GraphQL API + webhooks | | Framework | Any (official template uses Next.js) | | Registration | Installed via manifest URL | | Authentication | App token issued during installation | | Dashboard UI | Rendered in an iframe via App Bridge |
Saleor's legacy plugin system (Python classes in saleor/plugins/) is deprecated. All new extensions should be built as Apps. Legacy plugins will be removed in a future major version.
The manifest is a JSON document served at a public URL that describes the App:
| Field | Type | Purpose |
|-------|------|---------|
| id | string | Unique identifier for the App |
| version | string | Semantic version |
| name | string | Display name |
| about | string | Short description |
| permissions | string[] | Required Saleor permissions |
| appUrl | string | Main App URL (loaded in Dashboard iframe) |
| configurationUrl | string | App settings page URL |
| tokenTargetUrl | string | URL that receives the auth token during install |
| dataPrivacyUrl | string | Privacy policy URL |
| homepageUrl | string | App homepage URL |
| supportUrl | string | Support contact URL |
| webhooks | object[] | Webhook subscriptions |
| extensions | object[] | Dashboard mounting points |
The manifest URL is provided when installing the App via the Dashboard or the appInstall mutation.
The official TypeScript SDK provides core utilities for building Saleor Apps:
| Utility | Purpose |
|---------|---------|
| SaleorApp | Main App class coordinating APL, manifest, handlers |
| createManifestHandler | Next.js API route handler for manifest endpoint |
| createAppRegisterHandler | Handler for the token exchange callback |
| withRegisteredSaleorDomainHeader | Middleware to verify request origin |
| verifyJWT | Verify Saleor-issued JWTs in webhook requests |
| getAppId | Retrieve the App's ID from the token |
| SALEOR_API_URL_HEADER | Standard header name for Saleor instance URL |
| SALEOR_AUTHORIZATION_BEARER_HEADER | Standard header for App auth token |
Install via npm install @saleor/app-sdk -- fetch live docs for the current version.
The APL stores the mapping between Saleor instance URLs and the App's auth tokens:
| APL Type | Storage | Use Case |
|----------|---------|----------|
| FileAPL | Local JSON file | Development only |
| UpstashAPL | Upstash Redis | Serverless production |
| SaleorCloudAPL | Saleor Cloud | Apps deployed to Saleor Cloud |
| EnvAPL | Environment variable | Single-tenant simple deployments |
| Custom | Any store | Implement the APL interface |
The APL is critical -- without it, the App cannot authenticate requests from Saleor after a server restart.
| Step | Actor | Action |
|------|-------|--------|
| 1 | Admin | Provides manifest URL in Dashboard |
| 2 | Saleor | Fetches manifest, validates permissions |
| 3 | Saleor | Sends auth token to tokenTargetUrl |
| 4 | App | Stores token in APL |
| 5 | Saleor | Marks App as installed |
| 6 | App | Uses stored token for all future API calls |
| Permission | Scope |
|------------|-------|
| MANAGE_PRODUCTS | Create, update, delete products |
| MANAGE_ORDERS | View and manage orders |
| MANAGE_CHECKOUTS | Manage checkout sessions |
| MANAGE_USERS | View and manage customers |
| MANAGE_SHIPPING | Configure shipping methods |
| MANAGE_DISCOUNTS | Create and manage promotions |
| MANAGE_CHANNELS | Configure channels |
| MANAGE_APPS | Install and manage other Apps |
| HANDLE_PAYMENTS | Process payment transactions |
| HANDLE_TAXES | Calculate taxes for checkout |
Request only the permissions your App actually needs -- the principle of least privilege.
The official saleor-app-template scaffolds a Next.js App with all SDK wiring:
| File | Purpose |
|------|---------|
| pages/api/manifest.ts | Serves the App manifest |
| pages/api/register.ts | Handles token exchange |
| pages/api/webhooks/*.ts | Webhook handler endpoints |
| pages/index.tsx | Main App page (Dashboard iframe) |
| saleor-app.ts | SaleorApp instance and APL configuration |
| lib/saleor-client.ts | Authenticated GraphQL client factory |
Scaffold with npx @saleor/cli app create -- fetch live docs for current template version.
| Task | Command / Tool |
|------|---------------|
| Start dev server | npm run dev (Next.js on port 3000) |
| Expose locally | saleor app tunnel or ngrok |
| Install in Saleor | Provide tunnel URL as manifest URL |
| View logs | Check terminal output and Saleor Dashboard App logs |
| Test webhooks | Use tunnel + Saleor triggers |
The tunnel is required because Saleor must reach your App over HTTPS to deliver webhooks and fetch the manifest.
After installation, use the stored auth token to call the Saleor API:
// lib/saleor-client.ts
// Fetch live docs for current client setup pattern
import { createGraphQLClient } from "@saleor/apps-shared"
export function createClient(saleorApiUrl: string, token: string) {
return createGraphQLClient({ saleorApiUrl, token })
}
saleor app tunnel during development for reliable webhook deliverySALEOR_API_URL_HEADER to support multi-tenant App installationsFetch the Saleor Apps documentation for exact manifest fields, SDK method signatures, and APL configuration patterns 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.