Apply when building, customizing, or deploying extensions for VTEX Sales App. Covers the complete 7-step workflow from prerequisite checks through code generation to deployment, including extension points (cart, PDP, menu), React hooks (useCart, usePDP, useCartItem, useCurrentUser, useExtension), TypeScript types, secure API integration patterns, and API documentation ingestion (OpenAPI, URLs, or inline specs) to generate typed integrations.
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. Wait for approval.
Step 3 — Generate component, CSS, and index.tsx. Validate against the 10-point checklist. 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). Load the code templates reference for all template patterns, the type generation rules, the custom fetch hook pattern, and the types reference for hook return types and TypeScript definitions.
Step 4 — Generate documentation file at
docs/<ExtensionName>.md
inside the Sales App package. Create the
docs/
folder if it does not exist. The document must contain:
Extension name — title matching the component name.
Overview — one-paragraph summary of what the extension does and why it was built.
Extension point — which extension point it registers on (e.g.,
cart.cart-list.after
) and why that point was chosen.
Hooks used — list each hook (
useCart
,
usePDP
, etc.) with a brief explanation of what data it provides to this extension.
Component structure — description of the component tree, props, and state management.
Styling — CSS module file name and summary of key classes.
API integration (if applicable) — endpoint, auth strategy (IO Proxy or direct), request/response shape.
Source documentation: URL or file path of the original API documentation, if provided.
Generated types: list of TypeScript interfaces generated from the API documentation.
Note which fields are optional (
?
) vs required per the documentation.
How to test — dev server command and URL to reach the extension.
Known constraints — any guards, edge cases, or limitations (e.g.,
useCartItem().item
may be undefined).
Template for the documentation file:
markdown
# <ExtensionName>## Overview<One-paragraphdescriptionoftheextensionpurposeandvalue.>## Extension point-**Point:**`<extension.point.name>`-**Rationale:**<Whythisextensionpointwasselected.>## Hooks used| Hook | Purpose ||------|---------||`useCart`|<Whatdataitprovideshere>|## Component structure<Describethecomponenttree,keyprops,andinternalstate.>## Styling-**File:**`<ComponentName>.module.css`-<SummaryofkeyCSSclassesanddesigndecisions.>## API integration-**Endpoint:**`/_v/...`-**Auth strategy:** IO Proxy / Direct / None
-**Request/Response:**<Briefshapedescription.>## How to testRun `yarn fsp dev {account}` and navigate to `https://{account}.myvtex.com/sales-app/...` to verify the extension renders.
## Known constraints-<Guardorlimitation1>-<Guardorlimitation2>
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.
File
Load when…
references/extension-points-hooks-and-types.md
Choosing 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.md
Generating extension code — simple, hook, API, IO Proxy, or Direct Auth templates; CSS module pattern;
index.tsx
with
defineExtensions
; hook initialization; validation checklist
references/discovery-and-use-cases.md
Running 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.md
Running Steps 5–6 — dev server commands, test URLs, build command, common build errors, FastStore WebOps deployment, monitoring, rollback
Common failure modes
Returning null instead of empty fragment —
return null
not allowed; use
return (<></>)
. Build fails.
Accessing item.manualPrice without guard — TypeScript "possibly undefined" error. Use
??
.
Using useCartItem outside cart.cart-item.after — Hook context only exists there. Runtime error.
Hardcoding auth tokens in frontend fetch — Keys visible in browser. Use VTEX IO proxy.
Using full URL with IO Proxy — Bypasses internal proxy. Use relative path
/_v/...
.
Placing code outside packages/sales-app/src/ — Not included in build.
Missing defineExtensions in index.tsx — Extension compiles but never renders.
Skipping prerequisite checks — Generating code without FastStore/Sales App installed.
Not presenting plan — User may want a different approach. Always confirm.
Invented extension point names —
cart.list.after
instead of
cart.cart-list.after
fails silently.
Skipping documentation — Extension generated without
docs/<ExtensionName>.md
. Future developers won't understand the extension's purpose, hooks, or constraints.
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