Data Model
ChamevoJS uses a three-level hierarchy: Product -> Views -> Elements.
Hierarchy
CVProduct
├── id?: string
├── title?: string
├── thumbnail?: string
├── options?: Partial<ChamevoOptions>
├── namesNumbers?: NamesNumbersEntry[] ← shared roster across all views
└── views: CVView[]
├── id?: string
├── title: string
├── thumbnail?: string
├── options?: Partial<ChamevoViewOptions>
├── locked?: boolean
├── elements: CVElementData[]
│ ├── id?: string
│ ├── type: ElementType
│ ├── title: string
│ ├── source: string
│ └── parameters: ElementParameters
└── printAreas?: CVPrintAreaConfig[]
├── id?: string
├── printingBox: PrintingBox
├── output?: PrintAreaOutput
├── mask?: PrintAreaMask
└── printProfile?: Partial<ChamevoPrintAreaOptions>
Types
All types are defined in @chamevo/types and can be imported:
import type {
CVProduct,
CVView,
CVElementData,
CVPrintAreaConfig,
ElementParameters,
TextParameters,
ImageParameters,
ChamevoOptions,
ChamevoEvents,
} from '@chamevo/types';
Serialization
getProduct() returns the complete product data as a serializable CVProduct:
const product = chamevo.getProduct();
const json = JSON.stringify(product);
// Later: restore the product
await chamevo.loadProduct(JSON.parse(json));
ID Generation
When id is omitted, ChamevoJS auto-generates a URL-friendly slug:
"Front View" → "front-view"
"Custom T-Shirt" → "custom-t-shirt"
Legacy Format
loadProduct() accepts both formats:
// New format
await chamevo.loadProduct({
title: 'T-Shirt',
views: [{ title: 'Front', elements: [...] }],
});
// Legacy format (flat array)
await chamevo.loadProduct([
{ title: 'Front', productTitle: 'T-Shirt', elements: [...] },
]);
Legacy arrays are auto-normalized: productTitle and productThumbnail from the first view become the product's title and thumbnail.
Next Steps
- Products & Views Guide — Working with the data model
- Elements Guide — Element types and parameters
- Options Cascade — How options merge through the hierarchy