Storefront — seeding
Seed a Wix Stores catalog by calling seed-store.cjs — don't hand-write the REST calls. It's
a build-time module (run via exec_tool, not shipped in the app) that abstracts every Wix Stores
seed operation. Load it and call setupStore — the one-call path — with plain data.
Pass only the connector token and catalog data. The module handles site configuration internally;
do not read the config or supply site/client IDs.
Match each product's type to what the buyer receives (the example shows both). Access — a
membership, or an online course/program the buyer enrolls in — isn't a store product at all; that's
the pricing-plans vertical, not here.
// build-time exec_tool
const { accessToken } = await base44.asServiceRole.connectors.getConnection("wix");
const seed = require(require("path").resolve(".agents/skills/wix-vibe-headless/references/storefront/seed/seed-store.cjs"));
const ctx = { token: accessToken };
// ONE call: install (+ wait for V3) → create products → categories → attach images, ids kept
// in memory (no hand-threading). Categories map name -> product NAMES. Pass an imageUrl per product
// to attach its image; omit it to skip images.
// imageUrl: a public, fetchable https:// url — Wix copies the image bytes at attach time.
const result = await seed.setupStore(ctx, {
currency: "EUR", // Pass only if the user asked for a currency or it's obvious for the store; else omit this line.
products: [
// physical — a shipped item: carries `quantity` (the default type)
{ name: "The Glam Rocker", description: "Sequin-studded velvet legend…", price: 49.99, quantity: 12, imageUrl: imageUrls[0] },
// a product with buyer choices — see "Options, variants and sale prices" below
{ name: "The Understudy", description: "…", price: 245, quantity: 8, imageUrl: imageUrls[1],
options: [{ name: "Color", type: "color", choices: [{ name: "Ink", colorCode: "#1B1B2F" }, { name: "Bone", colorCode: "#EDE6D6" }] }] },
// a product on sale — compareAtPrice drives the strikethrough + the tile's percent-off badge
{ name: "Encore Jacket", description: "…", price: 68, compareAtPrice: 129, quantity: 5, imageUrl: imageUrls[2] },
// digital — a file the buyer downloads & keeps (ebook, PDF, video): `digitalFileUrl`, NO `quantity`
{ name: "Backstage Guide", description: "…", price: 12, digitalFileUrl: "https://…/guide.pdf" },
],
categories: { "Legends": ["The Glam Rocker"], "Rising Stars": [] }, // omit if the brief names none
});
// result: { products:[{id,slug,revision,name}], categories:[{id,name}], imagesAttached,
// imagesSkipped (product names whose imageUrl was not an absolute https:// url — attach those afterwards),
// productsWithoutImages (product names seeded with no imageUrl — attach afterwards once urls exist),
// currency: { requested, actual, status, warnings } }A product name is at most 80 characters — Wix rejects the whole batch over that, so keep
names short and put the detail in description.
The optional currency sets the site's payment currency before product creation. Pass it only when
the user explicitly asked for a currency, or when it's obvious for the store — otherwise omit it. Do
not infer a currency from the builder's country/region or the brief's language; when in doubt, leave
it out and the current site currency is preserved. Product prices are numbers in that currency;
changing currency does not convert existing amounts.
Currency update or verification failures do not stop seeding: inspect result.currency.status
and warnings, report the unresolved setting, and use the connector skill to resolve it. An
unknown actual currency is null; do not replace currency symbols to simulate a successful update.
Currency changes may take time to appear in existing product responses, even after carts and
checkout use the new currency. If result.currency.status confirms the update succeeded, continue
without waiting for or verifying the change in product responses or the preview.
Seeding is additive — never delete or overwrite existing content. Don't clean up, don't remove "sample" data, don't reset. Just add.
Stock
{ name: "Limited Print", price: 25, quantity: 12 } // count stock: integer 0–99999
{ name: "Made-to-order Print", price: 25, inStock: true } // available without a quantity counter
{ name: "Unavailable Print", price: 25, inStock: false } // unavailable without a quantity counterSupply quantity or inStock, never both. Use inStock: true for unlimited stock, not a
large invented quantity. All expanded variants inherit the same setting. Omitting both defaults
to quantity 0 for physical products and in-stock for downloads. Stock mode doesn't change the
product type or remove the downloadable-file requirement.
Wix inventory tracking.
How many, and exercising the UI
Default to 3 products unless the brief asks for a specific catalog — the seed shows the shape, not a full inventory; the owner adds the rest later, from the Wix dashboard or by asking you for more.
The shipped storefront renders colour options as real swatches, shows a size/colour summary on each tile, and puts a percent-off badge on a discounted product. A catalog of plain single-price products leaves all of that invisible, so make those 3 exercise it: unless the brief says otherwise, give at least one product a colour option and put one product on sale. Keep it truthful to the business.
options: [
{ name: "Color", type: "color", choices: [{ name: "Ink", colorCode: "#1B1B2F" }, { name: "Bone", colorCode: "#EDE6D6" }] },
{ name: "Size", type: "text", choices: ["Small", "Medium", "Large"] }, // or [{ name: "Small" }, …]
]type: "color"→SWATCH_CHOICESwith each choice'scolorCode, which the PDP draws as a swatch. Any othertype→ text pills. Give every colour choice acolorCode. Within a batch, reuse the same color code for the same option/choice name across products; give different shades distinct names (for example, Forest Green and Light Green).- Choice names must be unique within each product option, for both text and color choices. Reusing a choice name across different products is fine; color choices must follow the consistency rule above.
- Variants are expanded for you: the full cross-product of the options, each carrying the product's
price,compareAtPriceand stock setting (quantityorinStock). Two options with 2 and 3 choices means 6 variants — keep option counts small. compareAtPrice(>price) is the "was" price: strikethrough on the PDP and a−N%badge on the tile, computed from the two amounts. It works with or without options.
Digital downloads
Pick the product type from what the buyer receives. A shipped physical item is the default. A
downloadable file the buyer keeps — ebook, PDF guide, template, preset pack, printable, music
track, downloadable video — is a digital product: pass its file as digitalFileUrl. Selling
access rather than a file — a membership, subscription, or an online course/program the buyer
enrolls in — is Pricing Plans, not a Stores product, so it isn't seeded here.
digitalFileUrl (plus digitalFileName when the url carries no filename) makes a product a digital
download — uploaded and created with both the file and stock, which is what the cart requires
(quantity is ignored). It's also the only way in: a file-less digital product is created
successfully, reads back healthy, and is then rejected at add-to-cart as ITEM_NOT_FOUND_IN_CATALOG.
No real, fetchable file in hand → seed the product as physical with inStock: true and tell the
user; swap it to a digital download once a real file exists.
Two things this module does not seed, so don't try:
- Ribbons ("New", "Best Seller"). The tile renders
product.ribbonwhen it's there, but ribbons are set in the Wix dashboard — tell the merchant that's where to add them. - Per-choice media — the photo that makes picking a choice swap the gallery image. Seeded swatches
select and price correctly; the gallery follows a choice once photos are linked to it (Wix dashboard,
or the wix-manage "Update Product with Options" recipe → Choice & variant fields). The shipped PDP then
follows automatically —
choiceImage()reads it back atmedia.items[].mediaId.
Escape hatch — individual functions
If seeding reports a partial failure, keep the reported successful product IDs and correct the failed inputs. Do not rerun the whole seed or wrap it in a retry loop: creation may already have succeeded for some products. Missing results mean unknown creation status; inspect before creating again.
Reach for the functions below only when the one-call setupStore doesn't fit (partial re-seed, custom
ordering, mid-flow checks). setupStore is built from them, in this order:
await seed.installStoresApp(ctx); // install + wait for the V3 catalog
const products = await seed.bulkCreateProducts(ctx, [ // → [{id,slug,revision}], in stock by `quantity`
{ name: "The Glam Rocker", description: "…", price: 49.99, quantity: 12 },
]);
const cats = await seed.createCategories(ctx, ["Legends"]); // sequential → [{id,name}]
await seed.addProductsToCategories(ctx, { [cats[0].id]: [products[0].id] });
await seed.attachProductImages(ctx, products.map((p, i) => ({ id: p.id, url: imageUrls[i], altText: p.slug })));Functions
| fn | does |
|---|---|
setupStore(ctx, {products, categories?}) |
one-call: install+wait → products → categories → images |
installStoresApp(ctx) |
install the Wix Stores app on the site (waits for the V3 catalog) |
bulkCreateProducts(ctx, products) |
one bulk create → [{id,slug,revision}]; products come out in stock with the quantity you pass |
createCategories(ctx, names) |
sequential (shared tree 409s on concurrent) → [{id,name}] |
addProductsToCategories(ctx, {catId:[pid]}) |
sequential add-items |
attachProductImages(ctx, [{id,url,altText}]) |
one bulk media attach; no revision to pass. Wix re-hosts each url server-side; the media can take a little while to appear on read-back (propagation) — normal, not a failure |
Reference
If a call returns a shape you didn't expect, or you need an operation this module doesn't cover,
use the documentation skill available in your environment to search + read the live Wix API reference — never guess. The
authoritative source recipe is wix-headless/references/inline-recipes/setup-online-store.md.
Read a method's page before writing its call: it carries the exact body shape, the required permission scope, and the response envelope.
- Install a Wix app onto the site: https://dev.wix.com/docs/api-reference/business-management/app-installation/app-installation/install-app.md
- Import an image into Wix Media: https://dev.wix.com/docs/api-reference/assets/media/media-manager/files/import-file.md
- Create Category: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/categories/create-category.md
- Bulk Update Categories: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/categories/bulk-update-categories.md
- Bulk Add Items To Category: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/categories/bulk-add-items-to-category.md
- Bulk Create Products With Inventory: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/bulk-create-products-with-inventory.md
- Bulk Update Products: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/bulk-update-products.md
- Bulk Create Inventory Items: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/inventory-items-v3/bulk-create-inventory-items.md
- Query Products: https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/query-products.md