merchi_sdk_product_form
v1.0.7
Published
Contract SDK for AI-built Merchi custom product forms.
Downloads
511
Readme
Merchi Product Form SDK
Contract SDK for AI-built and hand-written custom Merchi product order forms.
Custom forms are React components that run inside the Merchi dashboard preview and the product embed. This package defines the only imports, components, and helpers those forms may use. Source is validated by a static gate and compiled to a browser bundle that externalises react and this SDK to window globals.
Table of Contents
- Installation
- Quick start
- How forms run
- Form component contract
- Layout and fields
- Group variations
- Pricing and job building
- Allowed exports
- Development
- License
Installation
npm install merchi_sdk_product_formPeer dependency: react ^18 or ^19.
In the Merchi monorepo, the dashboard installs a packed tarball:
cd merchi_sdk_product_form
npm run build && npm pack
cd ../merchi_dashboard && npm installQuick start
A minimal form renders independent variation fields and relies on the host shell for quantity, live pricing, and submit actions:
import React from 'react';
import {
Section,
Stack,
Heading,
Text,
Field,
} from 'merchi_sdk_product_form';
export default function Form({ product }) {
const fields = product?.independentVariationFields ?? [];
return (
<Stack gap={24}>
<Section>
<Heading>{product?.name || 'Order form'}</Heading>
{product?.description ? <Text muted>{product.description}</Text> : null}
</Section>
<Section title="Options">
<Stack gap={16}>
{fields.map((field) => (
<Field key={field.id} field={field} />
))}
</Stack>
</Section>
</Stack>
);
}See examples/colour-grid-form.tsx for a per-colour quantity grid (wristbands, multi-SKU products).
How forms run
- Authoring — Form source is stored as TSX on a
ProductFormin Merchi. - Gate — Only imports from
reactandmerchi_sdk_product_formare allowed (legacy@merchi/product-form-sdkis still accepted for older drafts). - Compile — esbuild bundles the form to an IIFE;
react→window.React,merchi_sdk_product_form→window.MerchiProductFormSdk. - Host — The dashboard or embed loads the bundle, provides
createProductFormRuntime, and wraps the form inProductFormShell(quantity control, live quote footer, add-to-cart / buy-now).
Form authors should not reimplement quantity controls, pricing footers, or checkout buttons — the shell provides those.
Form component contract
Default-export a React component matching ProductFormComponent:
export default function Form({ product, pricing, actions, helpers }) {
// product — ProductJson for the item being ordered
// pricing — request quotes as the user edits (createPricing wrapper)
// actions — submit handlers (addToCart, buyNow, …); may be undefined
// helpers — serializeJob, nonEmptyGroups, formatCurrency, urlFor
}Inside composed UI, prefer useProductForm() from a ProductFormProvider / ProductFormShell subtree for quote state and submit wiring.
Layout and fields
| Export | Purpose |
|--------|---------|
| Section, Stack, Card | Page structure |
| Heading, Text, Divider | Typography |
| Field | Render a product variation field (options, text, files, etc.) |
| theme | Shared spacing/colour tokens |
Loop product.independentVariationFields for options that apply to the whole order (job.variations).
There is no TextInput, Select, Button, or ColorSwatches — use Field and layout components only.
Group variations
Some products need per-batch choices (e.g. colour × quantity grids):
| Helper / component | When to use |
|--------------------|-------------|
| productHasGroups(product) | Product has groupVariationFields |
| isOptionQuantityGridProduct(product) | Single option-based group field → use grid |
| OptionQuantityGrid | Table: swatch, quantity, row cost, inventory |
| GroupRows | Multiple group fields or free-text group fields |
| Field with groupIndex | Field inside a specific batch row |
When groups exist, each batch has its own quantity in job.variationsGroups. Do not use top-level job.quantity — ProductFormShell hides the global quantity control for group products.
Pricing and job building
| Export | Purpose |
|--------|---------|
| createPricing / createProductFormRuntime | Host/runtime wiring (embed & dashboard) |
| buildProductFormJob | Build a JobJson from form state |
| selectionsToVariations | Map field selections to variation payloads |
| serializeJob | Strip empty groups before submit |
| nonEmptyGroups | Filter groups with quantity > 0 |
| formatCurrency, urlFor | Display helpers |
Allowed exports
The compile gate allowlists these runtime named imports (type-only imports are erased and not checked):
SDK_VERSION, serializeJob, nonEmptyGroups, formatCurrency, urlFor, createPricing, createProductFormRuntime, productHasGroups, groupFieldsOf, independentFieldsOf, isOptionQuantityGridProduct, buildProductFormJob, selectionsToVariations, Section, Stack, Card, Heading, Text, Divider, Field, GroupRows, OptionQuantityGrid, ProductFormProvider, ProductFormShell, useProductForm, OPTION_FIELD_TYPES, theme
Keep this list in sync with src/index.ts and merchi_api/common/js/product_form_gate.cjs.
Development
npm install
npm run build # tsc → dist/
npm test # jest
npm run lint # eslint src
npm pack # merchi_sdk_product_form-<version>.tgzRepository: github.com/merchisdk/merchi_sdk_product_form
License
GPL-3.0 — see LICENSE (same as merchi_sdk_ts).
