Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
vtex avatar

Sales App Extensibility

  • 4 installs
  • 39 repo stars
  • Updated June 16, 2026
  • vtex/ai-skills

Builds and deploys VTEX Sales App extensions for cart, PDP, and menu using React hooks and typed API integrations generated from OpenAPI specs.

About

Covers building, customizing, and deploying extensions for VTEX Sales App via a 7-step workflow. A developer uses it to add cart, PDP, and menu features using hooks like useCart and usePDP and to generate typed API integrations from OpenAPI or inline specs.

  • Extension points for cart, PDP, and menu with useCart/usePDP/useCartItem hooks
  • API documentation ingestion (OpenAPI/URLs/inline) to generate typed integrations

Sales App Extensibility by the numbers

  • 4 all-time installs (skills.sh)
  • +1 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #1,817 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/vtex/ai-skills --skill sales-app-extensibility

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs4
repo stars39
Last updatedJune 16, 2026
Repositoryvtex/ai-skills

What it does

Builds and deploys VTEX Sales App extensions for cart, PDP, and menu using React hooks and typed API integrations generated from OpenAPI specs.

Files

SKILL.mdMarkdownGitHub ↗

Sales App Extensibility

When this skill applies

Use this skill when building, customizing, or deploying extensions for VTEX Sales App.

  • Adding features to the cart page (promotions, loyalty, services)
  • Adding features to the Product Detail Page (badges, recommendations, warranties)
  • Adding features to the menu (user profile, navigation, metrics)
  • Integrating external APIs into Sales App extensions
  • Generating, scaffolding, or validating extension code for Sales App

Do not use this skill for:

  • Regular FastStore storefront customization (use faststore-storefront)
  • Building VTEX IO apps (use vtex-io-* skills)
  • Sales App core development or framework modifications

Prerequisite: FastStore project

The project root must contain: biome.json, faststore.json, package.json, tsconfig.json, turbo.json.

If any are missing, STOP. The user must install FastStore first:

npx @vtex/fsp-cli init
# Prompt: "What is the application name?" → enter name or press Enter for default
cd <application-name> && yarn

Documentation: https://beta.fast.store/getting-started

Prerequisite: Sales App module

Inside the FastStore project, a Sales App workspace must exist (typically at packages/sales-app) with src/, package.json, and tsconfig.json. Check root package.json "workspaces" for a path containing sales-app. If missing, STOP:

yarn add @vtex/sales-app -D -W
npx fsp create
# Prompts: account name → "Sales App" → path (default or custom)
# Then add the path to root package.json "workspaces" array
yarn install

Documentation: https://beta.fast.store/sales-app/setting-up

Do NOT proceed to discovery or code generation until both prerequisites are confirmed.

Decision rules

Follow the mandatory 7-step workflow (Steps 0–6) in order. Do not skip steps.

StepPurposeGate
0Check prerequisitesFastStore + Sales App installed → proceed; otherwise STOP
1DiscoveryUnderstand what the user wants to build
2Requirements & PlanMap requirements → generate plan → wait for user approval
3Code Generation & ValidationGenerate Component.tsx + Component.css (plain CSS, never .module.css) + index.tsx → validate
4DocumentationGenerate docs/<ExtensionName>.md explaining the extension
5Local TestingProvide dev commands and URLs
6Build & DeployBuild command → deployment guide

Extension point selection

Extension PointCategoryAvailable HooksLayout Shift
cart.cart-list.afterCartuseCart, useExtensionNo
cart.cart-item.afterCartuseCart, useCartItem, useExtensionYes
cart.order-summary.afterCartuseCart, useExtensionYes
pdp.sidebar.beforePDPusePDP, useCart, useExtensionYes
pdp.sidebar.afterPDPusePDP, useCart, useExtensionYes
pdp.content.afterPDPusePDP, useCart, useExtensionYes
menu.itemMenuuseExtensionNo
menu.drawer-contentMenuuseCurrentUser, useExtensionNo

Hook availability

  • useCart → all cart + PDP extensions
  • useCartItemcart.cart-item.after only
  • useCurrentUsermenu.drawer-content only
  • usePDP → PDP extensions only
  • useExtension → all extension points

Template selection

  • No API + no hooks → simple template
  • No API + hooks → hook template
  • API + no auth → API template
  • API + VTEX IO proxy → IO proxy template (recommended)
  • API + direct auth → direct auth template (insecure, warn user)
  • API doc provided → generate TypeScript interfaces from extracted response shapes; no API doc → use ${DATA_INTERFACE} placeholder

API authentication strategy

1. Recommended: VTEX IO Proxy App — IO app stores keys server-side. Extension uses credentials: 'include' with a relative path (/_v/my-api/data). 2. Insecure: Direct Auth — Keys in frontend code, visible in browser. Testing/development only.

Hard constraints

Constraint: Component must return JSX.Element, never null

defineExtensions expects ExtensionPointComponent which returns Element, not Element | null.

Why this matters Returning null causes a TypeScript compilation error. The build will fail.

Detection return null in any component registered with defineExtensions.

Correct

export function MyExtension(): JSX.Element {
  if (!data) return (<></>);
  return <div>{data.value}</div>;
}

Wrong

export function MyExtension(): JSX.Element | null {
  if (!data) return null;
  return <div>{data.value}</div>;
}

Constraint: Guard optional properties before use

CartItem.manualPrice (number | undefined), CartItem.productRefId (string | undefined), CartItem.attachments (Attachment[] | undefined) must be guarded.

Why this matters TypeScript strict mode rejects accessing possibly-undefined values.

Detection item.manualPrice, item.productRefId, or item.attachments without ?., ??, &&, or != null.

Correct

const price = item.manualPrice ?? item.sellingPrice;
const refId = item.productRefId ?? 'N/A';
const count = item.attachments?.length ?? 0;

Wrong

const price = item.manualPrice;
const refId = item.productRefId.toUpperCase();
const count = item.attachments.length;

Constraint: useCartItem().item may be undefined

item from useCartItem() is CartItem | undefined.

Why this matters Accessing properties on undefined causes a runtime crash.

Detection Destructured item from useCartItem() used without if (!item) guard.

Correct

const { item } = useCartItem();
if (!item) return (<></>);
return <div>{item.name}</div>;

Wrong

const { item } = useCartItem();
return <div>{item.name}</div>;

Constraint: defineExtensions is required in index.tsx

Entry point must use defineExtensions from @vtex/sales-app.

Why this matters Without it, the build succeeds but no extensions render.

Detection Missing defineExtensions import or call in index.tsx.

Correct

import { defineExtensions } from '@vtex/sales-app';
import { MyExtension } from './components/MyExtension';
export default defineExtensions({ 'cart.cart-list.after': MyExtension });

Wrong

import { MyExtension } from './components/MyExtension';
export default { 'cart.cart-list.after': MyExtension };

Constraint: Extension point names must match exactly

IDs are a fixed set. Non-existent names silently fail.

Why this matters The extension renders nowhere. No build error — invisible at runtime.

Detection Any name not in: cart.cart-list.after, cart.cart-item.after, cart.order-summary.after, pdp.sidebar.before, pdp.sidebar.after, pdp.content.after, menu.item, menu.drawer-content.

Correct

defineExtensions({ 'cart.cart-list.after': MyExtension });

Wrong

defineExtensions({ 'cart.list.after': MyExtension });

Constraint: Hooks must be used in compatible extension points

Each hook has an available_in restriction.

Why this matters Hook context is only mounted for specific extension points. Using elsewhere throws runtime errors.

Detection useCartItem in PDP/menu. useCurrentUser in cart. usePDP in menu/cart-list.

Correct

// useCartItem in cart.cart-item.after ✓
defineExtensions({ 'cart.cart-item.after': ItemWarranty });

Wrong

// useCartItem in pdp.sidebar.after ✗ — will fail at runtime
defineExtensions({ 'pdp.sidebar.after': ItemWarranty });

Preferred pattern

Workflow overview

Step 0 — Check FastStore + Sales App prerequisites. STOP if missing.

Step 1 — Discovery. Detect use case from keywords, ask follow-up questions, determine API auth strategy. If the user provides API documentation (URL, OpenAPI/Swagger file, Markdown, or inline text), ingest it to extract endpoint details and response shapes — skip the equivalent manual questions. Validate extracted information with the user. Load the discovery reference for detailed question flows and the API Documentation Ingestion section.

Step 2 — Map requirements to extension point + hooks + template. Present plan listing the files to be created: components/<ComponentName>.tsx, components/<ComponentName>.css (plain CSS — never .module.css), and index.tsx. Wait for approval.

Step 3 — Generate <ComponentName>.tsx, <ComponentName>.css (plain CSS, never .module.css), and index.tsx.

Required references for this step (load before generating):

  • code-templates-and-patterns.md — all component templates, the CSS template (with the full Sales App design system inlined: tokens, typography, spacing, responsive), the index.tsx template, type generation rules, and the custom fetch hook pattern.
  • extension-points-hooks-and-types.md — hook return types and TypeScript definitions.
  • static-analysis-rules.md — sandbox security, CSS containment, and React performance rules from @vtex/fsp-analyzer. Run these checks on all generated files.
  • design-guidelines.md — load when the extension renders any UI text (sentence case rule) or uses icons (Phosphor Icons).

If API documentation was ingested in Step 1, generate TypeScript interfaces from the extracted response shapes and use them in the component instead of the ${DATA_INTERFACE} placeholder. If the extension calls 2+ endpoints, extract fetch logic into custom hook(s). Validate against the 12-point checklist in code-templates-and-patterns.md. Fix all violations before presenting code; surface warnings to the user.

Step 4 — Generate docs/<ExtensionName>.md inside the Sales App package (create the docs/ folder if needed). Load the documentation template reference for the required 9-section structure and the markdown skeleton to fill in.

Step 5 — Provide local dev commands and test URLs. Load the dev/build/deploy reference.

Step 6 — Build command and deployment guide. Load the dev/build/deploy reference.

Reference Files

Load these on demand based on what the task requires. Do not load all of them upfront.

FileLoad when…
references/extension-points-hooks-and-types.mdChoosing an extension point, selecting hooks, looking up TypeScript types (CartItem, ProductSku, Totalizers, Attachment), or checking hook return values and availability per extension point
references/code-templates-and-patterns.mdGenerating extension code — simple, hook, API, IO Proxy, or Direct Auth templates; CSS template with the full Sales App design system inlined (tokens, typography, spacing, responsive); index.tsx with defineExtensions; hook initialization; validation checklist
references/discovery-and-use-cases.mdRunning Step 1 (Discovery) — use case detection keywords, follow-up questions, API auth decision tree, IO Proxy vs Direct Auth flow
references/local-dev-build-and-deploy.mdRunning Steps 5–6 — dev server commands, test URLs, build command, common build errors, FastStore WebOps deployment, monitoring, rollback
references/static-analysis-rules.mdValidating generated code (Step 3) — sandbox security, CSS containment, and React performance rules from @vtex/fsp-analyzer; full rule catalog with violation IDs, detection patterns, and correct/wrong examples
references/design-guidelines.mdWriting UI text (sentence case rule) or using icons (Phosphor Icons). CSS-related design rules — tokens, typography, spacing, responsive — are inlined directly in the CSS template inside code-templates-and-patterns.md, so this file is not needed for CSS generation.
references/documentation-template.mdWriting the docs/<ExtensionName>.md file in Step 4 — the 9-section structure and markdown skeleton

Common failure modes

  • Skipping prerequisite checks — Generating code without FastStore/Sales App installed. Always confirm both before Step 1.
  • Not presenting plan — User may want a different approach. Always confirm at Step 2 before generating code.
  • Skipping documentation — Extension generated without docs/<ExtensionName>.md. Load documentation-template.md for the required structure.
  • Inventing API response types — Generated interface doesn't match actual API. If documentation was provided, derive types from it; if not, ask the user for a sample JSON response.
  • Ignoring provided API documentation — User provided a URL or file but agent asked manual questions anyway. Always check for documentation first and use the API Documentation Ingestion flow.
  • Inline fetch with 2+ endpoints — Multiple fetch calls inside the component body. Extract into custom hook(s) in hooks/use{Purpose}.ts.
  • Placing code outside packages/sales-app/src/ — Files outside this path are not included in the build.
Code-level violations (DOM APIs, Node imports, eval, CSS containment, React performance, design tokens) are enforced by @vtex/fsp-analyzer and caught during Step 3 validation. See static-analysis-rules.md and design-guidelines.md.

Review checklist

Workflow gates

  • [ ] FastStore installed (biome.json, faststore.json, package.json, tsconfig.json, turbo.json)?
  • [ ] Sales App module installed (src/, package.json, tsconfig.json in sales-app directory)?
  • [ ] Discovery completed and use case identified?
  • [ ] Execution plan approved by user?
  • [ ] Extension point is valid (from the 8-point reference)?
  • [ ] Hooks compatible with chosen extension point?
  • [ ] Documentation generated at docs/<ExtensionName>.md (9 sections, using documentation-template.md)?
  • [ ] If API documentation was provided, TypeScript interfaces match the documented response shape?
  • [ ] If 2+ API endpoints used, fetch logic extracted into custom hook(s) in hooks/?
  • [ ] Build passes: yarn fsp build {account} sales-app?
  • [ ] Tested locally: yarn fsp dev {account}?

TypeScript / runtime guards (not caught by fsp-analyzer)

  • [ ] Component returns JSX.Element, never null?
  • [ ] Optional properties guarded (manualPrice, productRefId, attachments)?
  • [ ] useCartItem().item checked for undefined?
  • [ ] defineExtensions configured in index.tsx?
All other code-level rules (sandbox APIs, CSS containment, React performance, design tokens) are enforced by @vtex/fsp-analyzer and checked during Step 3. See static-analysis-rules.md and design-guidelines.md.

Related skills

  • faststore-storefront — storefront customization outside Sales App
  • vtex-io-app-contract — building VTEX IO proxy apps for secure API integration

Reference

  • Sales App setup: https://beta.fast.store/sales-app/setting-up
  • FastStore getting started: https://beta.fast.store/getting-started
  • VTEX Sales App documentation: https://help.vtex.com/en/tracks/instore-getting-started-and-setting-up
  • VTEX IO app development: https://developers.vtex.com/docs/guides/vtex-io-documentation-developing-an-app

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.