All skills
wix avatar

/wix-vibe-headless

@1563591 official
by Wix.comwix/skills33 stars
33

Client-only, dependency-free REST scaffolds for connecting an already-built front end (a vibe-coded app, an HTML/JSX/Vite project, a design-tool export) to a live Wix site over the site's public WIX_CLIENT_ID — the browser talks to Wix directly, no SDK, no backend, no build step. One skill covering every Wix business solution: Stores/eCommerce storefront (products, cart, checkout), Bookings (services, slots, appointments), Blog (posts, categories, tags), Events & Tickets (browse, RSVP, ticketing), Portfolio (collections, projects, galleries), Restaurants (menu, online ordering, reservations), Forms (any visitor-fillable form — contact/enquiry, signup, waitlist, application, survey, quote request; schema-driven render + submit), CMS / Wix Data (list, detail, filter, CRUD), Pricing Plans (memberships, subscriptions, checkout), and Members (custom login — email+password, Google/Facebook, and custom SSO — plus account areas and member-gated content). Each vertical ships a copy-as-is REST layer plus wiring instructions. Read-only over the owner's content — never provisions, never mocks data. Triggers: connect my Wix store/shop, build a storefront over Wix, add a cart and checkout, connect Wix Bookings, take appointments/reservations, show my Wix blog, list my Wix events, sell tickets, take RSVPs, build a portfolio from Wix Portfolio, show my restaurant menu / order online / book a table, display my Wix CMS collection, wire a contact form to Wix, add a contact/enquiry form, build a signup or application form, take survey responses, sell membership/subscription plans, add member login / sign up, let members log in with Google or Facebook, custom login page, account / profile page, gate content behind login, sign in with SSO/Okta, 'here is my WIX_CLIENT_ID', connect this app to my Wix site over REST. Use this for CLIENT-ONLY REST integration over an existing site; use `wix-headless` instead for SDK + Wix CLI builds, hosting, and one-prompt new-site creation.

Use this Skill: https://skilld.dev/gh/wix/skills/wix-vibe-headless

This session only. Nothing lands on disk.

referencesbookingsseedSEED.md

≈2.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Bookings — seeding

Seed a Wix Bookings catalog by calling seed-bookings.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 Bookings seed operation. Load it and call setupBookings — the one-call path — with plain data.

Transcribed from wix-headless/references/inline-recipes/setup-bookings.md — NOT yet live-verified.

// build-time exec_tool
const { accessToken } = await base44.asServiceRole.connectors.getConnection("wix");
const seed = require(require("path").resolve(".agents/skills/wix-vibe-headless/references/bookings/seed/seed-bookings.cjs"));
const ctx = { token: accessToken, siteId: WIX_METASITE_ID };

// ONE call: install → resolve staff → categories → services → CLASS sessions → images, all in the
// correct order with ids kept in memory (no hand-threading of scheduleId/resourceId). `category` is
// a NAME (resolved to an id internally). Free service: set free:true, omit price. CLASS `sessions`
// are local "YYYY-MM-DDThh:mm:ss".
const result = await seed.setupBookings(ctx, {
  services: [
    // `imageUrl` per service is optional and attached IN this one call. Pass a plain url — the module
    // imports it into Wix Media for you (bookings binds a service image by the Wix Media file id, not a
    // url). Use the FINAL https://media.base44.com/... url from the COMPLETED generate_image (it runs in
    // the background while you build — wait for it), never a still-generating /__generating__/<id>.png.
    { type: "APPOINTMENT", name: "Consultation", description: "…", tagLine: "…", price: 75, duration: 60, category: "Our Services", imageUrl: "https://media.base44.com/…" },
    { type: "CLASS", name: "Morning Yoga", description: "…", price: 20, capacity: 20, category: "Our Services",
      sessions: [{ start: "2026-08-10T09:00:00", end: "2026-08-10T10:00:00" }] },
  ],
  // staffResourceId defaults to the fresh install's owner (queryStaff()[0].resourceId).
});
// result: { services:[...], categories:[{id,name}], resourceId, sessionsScheduled, imagesAttached }

// fallback (finer control / re-attach): import the url to Wix Media, then patch one service after the fact.
// const file = await seed.importImage(ctx, imageUrl);   // → { id, url } (Wix Media file id + wixstatic url)
// await seed.attachServiceImage(ctx, { serviceId: s.id, revision: s.revision, image: { id: file.id, url: file.url, width: 1024, height: 1024 } });

Seeding is additive — never delete or overwrite existing content. Don't clean up, don't remove "sample" data, don't reset. Just add.

What the shipped UI renders from this

Pass these and the catalog reads like a real one; omit them and the pages have visible holes:

  • sessions on every CLASS. A class's bookable times ARE its sessions, so a class seeded without them shows "No available times in this range" — which reads as broken, not empty. Schedule a few weeks out. An APPOINTMENT needs none: its slots come from staff working hours, which a fresh install's owner already has.
  • duration (APPOINTMENT, minutes) → the card's 60 min · 1-to-1 line and the DURATION cell on the service page. A class has no service-level duration and shows CAPACITY instead, so pass capacity there.
  • tagLine → the card's second line. One line about the service, not a copy of description.
  • price, or free: true for a no-fee service, which the UI labels "Free".

Two things this module can't set, so don't try: varied pricing (a "From €85" service needs payment.varied) and conferencing (the UI's "Online" location label reads that flag — seeded services all sit at the business location, which shows as "In person").

Escape hatch — individual functions

Reach for the functions below only when the one-call setupBookings doesn't fit (partial re-seed, custom staff/ordering). setupBookings is built from them, in this order:

await seed.installBookingsApp(ctx);
const staff = await seed.queryStaffWithRetry(ctx);                   // → [{resourceId,id,name}]; polls (fresh install provisions the owner async); use resourceId, NOT id
const cats = await seed.createCategories(ctx, ["Our Services"]);    // → [{id,name}]; every service needs a categoryId
const services = await seed.createServices(ctx, [                   // → [{id,slug,revision,type,scheduleId}]
  { type: "APPOINTMENT", name: "Consultation", price: 75, duration: 60, categoryId: cats[0].id, staffMemberIds: [staff[0].resourceId] },
  { type: "CLASS", name: "Morning Yoga", price: 20, capacity: 20, categoryId: cats[0].id },
]);
// CLASS only: schedule sessions with each class's returned scheduleId (local wall-clock times)
await seed.scheduleClassSessions(ctx, [
  { scheduleId: services[1].scheduleId, resourceId: staff[0].resourceId, start: "2026-08-10T09:00:00", end: "2026-08-10T10:00:00", capacity: 20 },
]);
// images (optional): import the url to Wix Media first (bookings binds by file id), then attach.
// Use the FINAL https://media.base44.com/... url only (never a /__generating__/ placeholder).
const file = await seed.importImage(ctx, imageUrl);   // → { id, url } (Wix Media file id + wixstatic url)
await seed.attachServiceImage(ctx, { serviceId: services[0].id, revision: services[0].revision, image: { id: file.id, url: file.url, width: 1024, height: 1024 } });

Functions

fn does
setupBookings(ctx, {services, staffResourceId?}) one-call: install → staff → categories → services → CLASS sessions → images
installBookingsApp(ctx) install the Wix Bookings app on the site
queryStaff(ctx) [{resourceId,id,name}] — one shot; use resourceId, not id
queryStaffWithRetry(ctx) STEP 1 — same, but polls until the default owner provisions after a fresh install (avoids MISSING_APPOINTMENT_RESOURCES)
createStaff(ctx, [{name,description}]) create named staff → [{resourceId,id,name}] (omit email/phone)
queryCategories(ctx) [{id,name}] — reuse a category created earlier this run
createCategories(ctx, names) STEP 2 — every service needs a category.id or it's invisible → [{id,name}]; reuses an existing same-named category (idempotent, no dupes on re-run)
createServices(ctx, services) STEP 3 — one bulk create (APPOINTMENT/CLASS mixed) → [{id,slug,revision,type,scheduleId,success,error}]
scheduleClassSessions(ctx, sessions) STEP 4 (CLASS only) — one bulk Calendar-Events-V3 create → [{id,success,error}]
getService(ctx, serviceId) fetch a service (current revision; confirm an image landed)
importImage(ctx, url) import an external url into Wix Media → {id,url} (file id + wixstatic url); bookings binds by this file id
attachServiceImage(ctx, {serviceId,revision,image}) optional — patch media.mainMedia/coverMedia (revision-checked); image.id MUST be a Wix Media file id from importImage

Both bulk calls report per-item success/error — retry only the failed items once with the same body; don't loop and don't re-create the ones that already succeeded.

Rentals

seed-rentals.cjs is the rentals half — the same transport, a different create order and payload. Wix Rentals has no APIs of its own, so a rental is a Bookings service with rentals-specific field values.

const seed = require(require("path").resolve(".agents/skills/wix-vibe-headless/references/bookings/seed/seed-rentals.cjs"));
await seed.setupRentals(ctx, {
  resourceTypeName: "Meeting rooms",
  resources: ["Room A", "Room B"],              // parallel capacity = MORE RESOURCES
  rentals: [
    { name: "Meeting room, hourly", description: "…", price: 25, unit: "HOUR", min: 60, max: 480 },
    { name: "Meeting room, daily",  description: "…", price: 180, unit: "DAY", min: 1, max: 5 },
  ],
});
// → { resourceType, resources, services, ok, problems }

price is a RATE — per hour or per day — not the cost of a rental. Hourly min/max are MINUTES (30–1440); daily are DAYS (1–8).

ok must be true. problems is the read-back check: a service created without appId or without durationRange still returns 200 and is simply a plain Bookings service from then on.

The four traps this seed handles

  • Install Rentals ONLY. It provisions the Bookings infrastructure it runs on; installing Wix Bookings as well is redundant.
  • appId is immutable after create. A service created without it is a plain Bookings service forever — there is no update that converts it.
  • Order is load-bearing: resource type → resources → services. A service whose resource type holds no resources has permanently empty availability, and nothing errors.
  • Rental services do not use categories. Unlike bookings, do not create or assign one.
  • serviceResources is required and the docs' Create Service parameter list omits it. Without it the create fails MISSING_APPOINTMENT_RESOURCES, whose message sends you to check the resource type's contents — a dead end, since it fails even when the type is populated.

Resources are seeded 24/7 (no working hours) so a multi-day rental stays one booking rather than a multi-service group. Pass workingHours only when the brief names opening hours.

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-bookings.md.

Read a method's page before writing its call: it carries the exact body shape, the required permission scope, and the response envelope.

Source: SKILL.md on GitHub

1 warning6d3 checks · Risk SAFE
  • Gen Agent Trust Hub6d

    The skill is safe and provides a comprehensive integration framework for Wix Headless services. It uses platform-secured connectors for authentication and includes automated scaffolding utilities to assist with project setup.

  • Socket6d

    No alerts

  • Snyk6d

    Risk: MEDIUM · 1 issue

Signed by skilld at 1563591. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 43 minutes ago.

Activeupdated 4 weeks ago

README badge

README badge for wix/skills/wix-vibe-headless