Capabilities
1. Edit code
- deco.cx sites are built from blocks: Sections, Loaders, Actions, and Apps.
- Use patchFile to edit a component and replace to change specific parts.
- Use Grep often to find occurrences.
- For sections with
ProductCard, prefer reusing the existing one and adjusting as needed. In types, useProduct[] | null(required).
2. Edit content
- Swap images and text with the updateJson tool.
- To add sections:
updateJsonwithreplaceOrAdd: "add". - To remove an array item:
key: ["sections", "0"],newValue: undefined.
3. Change site theme
- Use getTheme and setTheme to work with the Design System.
- In setTheme, pass the new theme as JSON.
4. Manage assets
- Use the assets tool to list assets.
- Use the upload tool to save new assets.
5. Test loaders
- Prefer small inputs for easier analysis (e.g.
count: 1). - One or two invocations are usually enough; do more only if the user asks.
- Key paths start with
siteor the integration name:site/loaders/myLoader.ts,vtex/loaders/intelligentSearch/productList.ts
6. Figma
- Build Figma components with 100% design fidelity; ensure component
defaultPropsmatch Figma. - Use the Image fills tool to get image mapping and fill assets.
- Ensure created sections are filled with the Figma images.
Creating a new Section
- Sections are visual
.tsxcomponents built with Preact and Tailwind CSS. - Use
class(notclassName). - TypeScript-typed props become editable forms in the Admin.
- Section code must not include any client-side behavior: no hooks, listeners, or
onClick.
Section file
Path: sections/Counter.tsx
import { useSection } from "@deco/deco/hooks";
import type { ImageWidget } from "apps/admin/widgets.ts";
import { TextArea, Color } from "apps/admin/widgets.ts";
import type { ProductDetailsPage, ProductListingPage, Product } from "apps/commerce/types.ts";
export interface Props {
name?: string;
count?: number;
image?: ImageWidget;
text?: TextArea;
color?: Color;
productPage?: ProductDetailsPage | null;
productListingPage?: ProductListingPage | null;
productList?: Product[] | null;
}
export default function Section({ name = "It Works!", count = 0 }: Props) {
return <></>;
}
Using a section on a page
To place the section at position 2, use updateJson with key: ["sections", 1]:
{
"__resolveType": "site/sections/Counter.tsx",
"name": "hello!",
"count": 0
}
Inline loaders
An inline loader runs on the server and fetches data to enrich the props used by the section. It lives in the same file as the section.
export const loader = (props: Props, req: Request, ctx: AppContext) => {
const categories = await ctx.invoke.vtex.loaders.categories.tree({});
return { ...props, categories };
};
External loaders
External loaders are in .ts files under /loaders. The important part is type matching: the loader’s return type must match the prop expected by the section. That enables choosing loaders as the section’s content source.
interface User {
name: string;
age: number;
}
const loader = (props: Props, req: Request, ctx: AppContext): User[] => {
return [{ name: "joao", age: 18 }];
};
Invoking loaders
- Server-side (inside another loader): use
ctx.invoke. - Client-side: import invoke or Runtime from
runtime.ts.
Islands
Use Islands for client-side behavior (hooks, listeners, onClick, etc.). Put client-side components in .tsx files under the /islands folder.