@wix/agent-skills 1.18.1 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +13 -13
  3. package/skills/wix-app/references/APP_VALIDATION.md +7 -33
  4. package/skills/wix-app/references/BACKEND_API.md +151 -152
  5. package/skills/wix-app/references/DASHBOARD_PAGE.md +18 -14
  6. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +6 -3
  7. package/skills/wix-app/references/EXTENSION_REGISTRATION.md +12 -8
  8. package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +23 -26
  9. package/skills/wix-app/references/dashboard-page/COLLECTION_TOOLKIT.md +7 -6
  10. package/skills/wix-app/references/dashboard-page/ENTITY_PAGE_TOOLKIT.md +71 -4
  11. package/skills/wix-app/references/dashboard-page/PATTERNS_BUNDLE_READING.md +67 -7
  12. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -1
  13. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +9 -6
  14. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +59 -89
  15. package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +23 -4
  16. package/skills/wix-base44-connector/SKILL.md +168 -48
  17. package/skills/wix-base44-connector/scripts/{utils.js → utils.cjs} +69 -48
  18. package/skills/wix-docs/SKILL.md +109 -111
  19. package/skills/wix-docs/references/API_SPEC_SEARCH.md +35 -23
  20. package/skills/wix-docs/references/CALLING.md +91 -0
  21. package/skills/wix-docs/references/EXTRACTING.md +5 -3
  22. package/skills/wix-headless/references/DOC_DISCOVERY.md +9 -3
  23. package/skills/wix-manage/SKILL.md +8 -2
  24. package/skills/wix-manage/references/bookings/booking-service-policy-setup.md +59 -33
  25. package/skills/wix-manage/references/bookings/bookings-staff-setup.md +45 -22
  26. package/skills/wix-manage/references/bookings/multi-resource-service-creation.md +70 -12
  27. package/skills/wix-manage/references/calendar/configure-default-business-hours.md +53 -17
  28. package/skills/wix-manage/references/seo/manage-content-plan.md +247 -0
  29. package/skills/wix-manage/references/seo/manage-seo-tags.md +59 -6
  30. package/skills/wix-manage/references/stores/change-store-currency.md +10 -0
  31. package/skills/wix-manage/references/stores/create-product-catalog-v3.md +17 -1
  32. package/skills/wix-manage/references/stores/update-product-with-options.md +9 -0
  33. package/skills/wix-vibe-headless/SKILL.md +17 -18
  34. package/skills/wix-vibe-headless/install/pin-agents-md.cjs +1 -1
  35. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed-with-install.md +119 -0
  36. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +61 -67
  37. package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +31 -29
  38. package/skills/wix-vibe-headless/platforms/base44.md +18 -7
  39. package/skills/wix-vibe-headless/platforms/generic.md +13 -12
  40. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +4 -13
  41. package/skills/wix-vibe-headless/references/blog/seed/SEED.md +4 -8
  42. package/skills/wix-vibe-headless/references/blog/seed/{seed-blog.js → seed-blog.cjs} +2 -3
  43. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +5 -14
  44. package/skills/wix-vibe-headless/references/bookings/seed/SEED.md +5 -9
  45. package/skills/wix-vibe-headless/references/bookings/seed/{seed-bookings.js → seed-bookings.cjs} +2 -2
  46. package/skills/wix-vibe-headless/references/bookings/seed/{seed-rentals.js → seed-rentals.cjs} +3 -3
  47. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +1 -1
  48. package/skills/wix-vibe-headless/references/cms/seed/SEED.md +2 -2
  49. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +4 -13
  50. package/skills/wix-vibe-headless/references/events/seed/SEED.md +3 -7
  51. package/skills/wix-vibe-headless/references/events/seed/{seed-events.js → seed-events.cjs} +2 -2
  52. package/skills/wix-vibe-headless/references/forms/INSTRUCTIONS.md +2 -1
  53. package/skills/wix-vibe-headless/references/forms/seed/SEED.md +1 -1
  54. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +4 -13
  55. package/skills/wix-vibe-headless/references/members/seed/SEED.md +2 -3
  56. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +4 -13
  57. package/skills/wix-vibe-headless/references/portfolio/app/components/ProjectMedia.jsx +1 -1
  58. package/skills/wix-vibe-headless/references/portfolio/seed/SEED.md +3 -7
  59. package/skills/wix-vibe-headless/references/portfolio/seed/{seed-portfolio.js → seed-portfolio.cjs} +2 -2
  60. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +5 -14
  61. package/skills/wix-vibe-headless/references/pricing-plans/app/components/OrderCard.jsx +1 -1
  62. package/skills/wix-vibe-headless/references/pricing-plans/seed/SEED.md +3 -7
  63. package/skills/wix-vibe-headless/references/pricing-plans/seed/{seed-pricing-plans.js → seed-pricing-plans.cjs} +2 -2
  64. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +5 -15
  65. package/skills/wix-vibe-headless/references/restaurants/seed/SEED.md +3 -7
  66. package/skills/wix-vibe-headless/references/restaurants/seed/{seed-restaurants.js → seed-restaurants.cjs} +2 -2
  67. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +363 -327
  68. package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +1 -0
  69. package/skills/wix-vibe-headless/references/storefront/app/hooks/useProductDetail.js +2 -2
  70. package/skills/wix-vibe-headless/references/storefront/app/hooks/useShop.js +63 -78
  71. package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-catalog.js +59 -43
  72. package/skills/wix-vibe-headless/references/storefront/seed/SEED.md +51 -14
  73. package/skills/wix-vibe-headless/references/storefront/seed/{seed-store.js → seed-store.cjs} +194 -28
  74. package/skills/wix-vibe-headless/references/storefront/app/pages/Shop.jsx +0 -75
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/agent-skills",
3
- "version": "1.18.1",
3
+ "version": "1.19.0",
4
4
  "description": "Wix Skills for AI coding agents — versioned npm distribution of the wix/skills content.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -8,7 +8,7 @@ compatibility: requires `@wix/cli` >= 1.1.192.
8
8
 
9
9
  Helps build extensions for Wix CLI applications. Covers all extension types: dashboard pages, modals, plugins, menu plugins, custom element widgets, Editor React components, site plugins, embedded scripts, backend APIs, events, service plugins, and data collections.
10
10
 
11
- **Scaffolding is owned by the Wix CLI.** For every extension type except Backend API, files, folders, builder boilerplate, UUIDs, and `src/extensions.ts` registration are generated by `wix generate --params`. This skill provides the decision logic, API guidance, configuration semantics, and business-logic patterns that fill in the generated stubs.
11
+ **Scaffolding is owned by the Wix CLI.** Use `wix generate --params` for every supported type. It generates files and, where applicable, builder boilerplate, UUIDs, and `src/extensions.ts` registration. HTTP endpoints are discovered from files and need no registration. This skill provides the decision logic, API guidance, configuration semantics, and business-logic patterns that fill in the generated stubs.
12
12
 
13
13
  ## ⚠️ MANDATORY WORKFLOW CHECKLIST ⚠️
14
14
 
@@ -117,7 +117,7 @@ Patterns owns the page shell and everything collection-shaped. These concepts ar
117
117
  | Filters, search, sorting, view presets/tabs | the collection's filter and view APIs |
118
118
  | Row actions, bulk actions, drag-and-drop | the collection's feature APIs |
119
119
  | Multiple pages inside one extension | `PatternsReactRouter`, `PatternsReactRoute`, `usePatternsNavigate` |
120
- | **Add / edit / view one item from a collection** | `EntityPage` + `useEntityPage` (fetch + save + validation), reached with `usePatternsNavigate().navigateToEntityPage`. Form state via `useForm` / `useController` from `@wix/patterns/form`. **Not** a dashboard modal — see [Entity create and edit](#entity-create-and-edit) |
120
+ | **Add / edit / view one item from a collection** | `EntityPage` + `useEntityPage` (fetch + save + validation), reached with `usePatternsNavigate().navigateToEntityPage`. Form state via `useForm` / `useController` from `@wix/patterns/form` (`useController`, never `register`). **Not** a dashboard modal — see [Entity create and edit](#entity-create-and-edit) |
121
121
  | Overlays tied to a collection (item picker, bulk-action confirm) | `PickerModal` / `usePickerModal`, `bulkActionModal` |
122
122
 
123
123
  **Looking a component up is two direct file reads** — no script, never `node_modules` browsed by hand. Resolve the installed package root once per session ([Prerequisites](references/WIX_PATTERNS_DOCS.md#prerequisites)), then reuse it. Start with what exists:
@@ -163,7 +163,7 @@ This is the most common place the selection order gets dropped: the collection g
163
163
 
164
164
  The documented flow:
165
165
 
166
- 1. From the collection page's action cell or primary action, call `navigateToEntityPage({ path, entity })` from `usePatternsNavigate()`. (The patterns docs give this exact use case — "navigate to an entity page on an action cell click on a collection page" — and it renders the entity header immediately, before the fetch resolves.)
166
+ 1. From the collection page's action cell or primary action, call `navigateToEntityPage({ path, entity })` from `usePatternsNavigate()`. (The patterns docs give this exact use case — "navigate to an entity page on an action cell click on a collection page" — and it renders the entity header immediately, before the fetch resolves.) On the **create** route there is no record to pass: omit `entity` and see [ENTITY_PAGE_TOOLKIT.md § Create route](references/dashboard-page/ENTITY_PAGE_TOOLKIT.md#create-route), which is what the whole "add new" flow turns on.
167
167
  2. Register the route with `PatternsReactRoute` inside `PatternsReactRouter`.
168
168
  3. In the entity page, `useEntityPage({ fetch, onSave })` owns fetching, saving, validation, dirty state, loading skeletons, and error states. Form state comes from `useForm` / `useController` in `@wix/patterns/form`. The call itself — both generics, what `onSave` receives, which params exist — is in [ENTITY_PAGE_TOOLKIT.md](references/dashboard-page/ENTITY_PAGE_TOOLKIT.md).
169
169
  4. Compose the body from `EntityPage.Header`, `EntityPage.MainContent`, `EntityPage.AdditionalContent`, and `EntityPage.Card`. **WDS goes inside those cards** — `FormField`, `Input`, `Text` for the individual fields.
@@ -183,7 +183,7 @@ Use a Dashboard Modal for dialogs that neither write nor display a listed record
183
183
  | Service Plugin | Backend | `SERVICE_PLUGIN` | [SERVICE_PLUGIN.md](references/SERVICE_PLUGIN.md) |
184
184
  | App Tools (AI assistant tools) | Backend | `APP_TOOLS`, then `SERVICE_PLUGIN` with `pluginType: TOOLS_PROVIDER_CONFIG` | [APP_TOOLS.md](references/APP_TOOLS.md) |
185
185
  | Backend Event Extension | Backend | `EVENT` | [BACKEND_EVENT.md](references/BACKEND_EVENT.md) |
186
- | Backend API | Backend | — (manual, see banner below) | [BACKEND_API.md](references/BACKEND_API.md) |
186
+ | Backend API (HTTP endpoint) | Backend | `HTTP_ENDPOINT` | [BACKEND_API.md](references/BACKEND_API.md) |
187
187
  | Data Collection | Backend | `DATA_COLLECTION` | [DATA_COLLECTION.md](references/DATA_COLLECTION.md) |
188
188
  | Editor React component | Site | `EDITOR_REACT_COMPONENT` | [EDITOR_REACT_COMPONENT.md](references/EDITOR_REACT_COMPONENT.md) |
189
189
  | Custom element widget | Site | `CUSTOM_ELEMENT` | [CUSTOM_ELEMENT_WIDGET.md](references/CUSTOM_ELEMENT_WIDGET.md) |
@@ -193,7 +193,7 @@ Use a Dashboard Modal for dialogs that neither write nor display a listed record
193
193
  **Key constraints:**
194
194
  - Dashboard Page cannot use `<Modal />`; use a separate Dashboard Modal and `dashboard.openModal()`.
195
195
 
196
- > **⚠️ Backend API is the only extension type the CLI does NOT scaffold.** `wix generate` has no `BACKEND_API` handler. Create files directly per [BACKEND_API.md](references/BACKEND_API.md).
196
+ > **HTTP endpoints:** Generate with `extensionType: "HTTP_ENDPOINT"` (not `BACKEND_API`). See [BACKEND_API.md](references/BACKEND_API.md) for project-specific directories, handler types, and frontend URLs.
197
197
 
198
198
  ## Extension Comparison
199
199
 
@@ -418,17 +418,17 @@ Use the Extension Types Reference Table and decision content above. State extens
418
418
 
419
419
  ### Step 4a: Scaffold via the CLI
420
420
 
421
- For each extension **except Backend API**, run `npx wix generate --params '<json>'`. The command returns `{"success":true,"extensionType":"...","newFiles":[...]}` on success.
421
+ For each supported type, including HTTP endpoints, run `npx wix generate --params '<json>'`. The command returns `{"success":true,"extensionType":"...","newFiles":[...]}` on success.
422
422
 
423
- If the command fails because of unknown or invalid params, run `npx wix schema generate --type <extensionType>` to print the JSON Schema for that extension type, fix the `--params` payload, and retry. Do not fall back to manual scaffolding.
423
+ If the command fails because of unknown or invalid params, run `npx wix schema generate --type <extensionType>` to print the JSON Schema for that extension type, fix the `--params` payload, and retry. Do not fall back to manual scaffolding. The one exception is `HTTP_ENDPOINT` on a CLI older than 1.1.243, which predates the generator but still supports the extension: create the endpoint file by hand as described in [BACKEND_API.md](references/BACKEND_API.md#generate-for-the-project-type).
424
424
 
425
425
  **What the CLI does automatically:**
426
426
  - Creates folders and stub files
427
- - Generates a fresh UUID for the extension `id`
428
- - Updates `src/extensions.ts` with the import and `.use()` call
427
+ - For registered extensions, generates a fresh UUID and updates `src/extensions.ts` with the import and `.use()` call
428
+ - For HTTP endpoints, creates the route file without changing `src/extensions.ts`
429
429
  - Enforces naming rules (kebab-case, hyphen-required custom elements, etc.)
430
430
 
431
- **Backend API exception:** Create `src/pages/api/*.ts` files manually per [BACKEND_API.md](references/BACKEND_API.md).
431
+ **HTTP endpoints:** Run `npx wix generate --params '{"extensionType":"HTTP_ENDPOINT","name":"hello"}'`, then implement the handler in the returned file. Follow [BACKEND_API.md](references/BACKEND_API.md); if the route does not respond, its troubleshooting hint shows how to confirm discovery from the build output.
432
432
 
433
433
  ### Step 4b: Fill in business logic
434
434
 
@@ -443,7 +443,7 @@ Open every path returned in `newFiles` and replace stubbed handler bodies / UI /
443
443
  After all implementation is complete, you MUST run validation. See [APP_VALIDATION.md](references/APP_VALIDATION.md) for the complete validation workflow:
444
444
 
445
445
  1. Package installation (detect package manager, run install)
446
- 2. TypeScript compilation check (`npx tsc --noEmit`)
446
+ 2. TypeScript compilation check (`npx tsc --noEmit -p .`)
447
447
  3. Build validation (`npx wix build`)
448
448
  4. Preview deployment (`npx wix preview`)
449
449
 
@@ -497,7 +497,7 @@ The following actions need to be done manually by you:
497
497
 
498
498
  ## Extension Registration
499
499
 
500
- `wix generate --params` updates `src/extensions.ts` automatically for every CLI-supported extension type. The only case that still requires manual editing is Backend API. For background, troubleshooting, and the manual recovery pattern when `src/extensions.ts` drifts, see [EXTENSION_REGISTRATION.md](references/EXTENSION_REGISTRATION.md).
500
+ `wix generate --params` updates `src/extensions.ts` automatically for registered extensions. HTTP endpoints require no import or `.use()` call; the runtime discovers their files. For background, troubleshooting, and the manual recovery pattern when `src/extensions.ts` drifts, see [EXTENSION_REGISTRATION.md](references/EXTENSION_REGISTRATION.md).
501
501
 
502
502
  ---
503
503
 
@@ -506,7 +506,7 @@ The following actions need to be done manually by you:
506
506
  Execute these steps sequentially after all implementation is complete. See [APP_VALIDATION.md](references/APP_VALIDATION.md) for the complete guide.
507
507
 
508
508
  1. **Package Installation** — Detect package manager, run install
509
- 2. **TypeScript Compilation** — `npx tsc --noEmit`
509
+ 2. **TypeScript Compilation** — `npx tsc --noEmit -p .`
510
510
  3. **Build** — `npx wix build`
511
511
  4. **Preview** — `npx wix preview`
512
512
 
@@ -46,41 +46,15 @@ pnpm install
46
46
 
47
47
  Run TypeScript compiler to check for type errors.
48
48
 
49
- **Full project check:**
50
49
  ```bash
51
- npx tsc --noEmit
50
+ npx tsc --noEmit -p .
52
51
  ```
53
52
 
54
- **Targeted check (specific files/directories):**
55
-
56
- When validating after implementing a specific extension, you can run TypeScript checks on just those files:
57
-
58
- ```bash
59
- # Check specific directory
60
- npx tsc --noEmit src/extensions/dashboard/pages/survey/**/*.ts src/extensions/dashboard/pages/survey/**/*.tsx
61
-
62
- # Check dashboard pages only
63
- npx tsc --noEmit src/extensions/dashboard/pages/**/*.ts src/extensions/dashboard/pages/**/*.tsx
64
-
65
- # Check custom element widgets only
66
- npx tsc --noEmit src/extensions/site/widgets/**/*.ts src/extensions/site/widgets/**/*.tsx
67
-
68
- # Check dashboard modals only
69
- npx tsc --noEmit src/extensions/dashboard/modals/**/*.ts src/extensions/dashboard/modals/**/*.tsx
70
-
71
- # Check backend only
72
- npx tsc --noEmit src/extensions/backend/**/*.ts
73
- ```
74
-
75
- **When to use targeted checks:**
76
- - After implementing a single extension (faster feedback)
77
- - When debugging type errors in a specific area
78
- - During iterative development
79
-
80
- **When to use full project check:**
81
- - Before final validation
82
- - When changes affect shared types
83
- - Before building/deploying
53
+ Run it from the app root, and check the whole project rather than just the files you
54
+ generated — a type error in generated code usually surfaces in the file that consumes
55
+ it. `-p .` is what holds that line: adding a file path to it is an error, whereas adding
56
+ one to a bare `npx tsc --noEmit` silently discards `tsconfig.json` (`strict`, `paths`,
57
+ `jsx`) and checks against compiler defaults instead.
84
58
 
85
59
  **Success criteria:**
86
60
  - Exit code 0
@@ -162,7 +136,7 @@ Read: .wix/debug.log (with offset to the end)
162
136
  | Issue | Cause | Solution |
163
137
  |-------|-------|----------|
164
138
  | Package installation fails | Missing lock file, network issues, or corrupted node_modules | Delete `node_modules` and lock file, then reinstall |
165
- | TypeScript compilation fails | Type mismatches, missing declarations, or incorrect types | Fix TypeScript errors shown in `npx tsc --noEmit` output |
139
+ | TypeScript compilation fails | Type mismatches, missing declarations, or incorrect types | Fix TypeScript errors shown in `npx tsc --noEmit -p .` output |
166
140
  | Build fails | TypeScript errors, missing dependencies, or internal CLI error | Fix TypeScript errors in source; for non-obvious failures, check `.wix/debug.log` |
167
141
  | Preview fails to start | Port conflict, config issue, or internal CLI error | Check `wix.config.json`; if unclear, check `.wix/debug.log` for details |
168
142
  | Console errors in preview | Runtime exceptions | Check browser console output |
@@ -1,82 +1,95 @@
1
1
 
2
2
  # Wix Backend API Builder
3
3
 
4
- Creates HTTP endpoints for Wix CLI applications — server-side routes that handle HTTP requests, process data, and return responses. HTTP endpoints are powered by Astro endpoints and are automatically discovered from the file system.
4
+ Creates HTTP endpoints for Wix app projects. Determine the existing runtime
5
+ before choosing the directory, handler type, or frontend URL.
5
6
 
6
- **Key facts:**
7
+ ## Scope and Runtime Detection
7
8
 
8
- - Files live in `src/pages/api/` with `.ts` extension
9
- - Cannot be added via `npm run generate` — create files directly
10
- - Don't appear on the Extensions page in the app dashboard
11
- - No extension registration needed (auto-discovered)
12
- - Replace the legacy "HTTP functions" from the previous Wix CLI for Apps
9
+ - The CLI uses the `@wix/custom-extensions` runtime when the project's own
10
+ `package.json` declares that package in `dependencies` or `devDependencies`. A
11
+ transitive installation under `node_modules` is not enough. Do not infer the
12
+ runtime from using `wix dev`, `wix build`, or the Wix CLI alone.
13
+ - Existing `@wix/astro` apps retain Astro routing. Do not add
14
+ `@wix/custom-extensions`, move routes into `src/endpoints`, change their handler
15
+ imports, or introduce `WIX_SERVER_BASE_PATH` to apply the other runtime's recipe.
13
16
 
14
- ## Use Cases
17
+ ## Generate for the Project Type
15
18
 
16
- Use HTTP endpoints when you need to:
19
+ ```bash
20
+ npx wix generate --params '{"extensionType":"HTTP_ENDPOINT","name":"hello"}'
21
+ ```
17
22
 
18
- - Build REST APIs with multiple HTTP methods
19
- - Integrate with external APIs or services
20
- - Handle complex form submissions or file uploads
21
- - Serve dynamic content (images, RSS feeds, personalized data)
22
- - Access runtime data or server-side databases
23
+ Names use lowercase letters, digits, and hyphens; slash-separated names such as
24
+ `payments/checkout` create nested routes. Do not include a leading slash or `.ts`.
25
+ The generator creates GET/POST stubs; keep only the methods the task needs.
26
+
27
+ For Wix app projects, the generator preserves the selected runtime:
28
+
29
+ | Project | Generated file | Route before any server base path | `APIRoute` import |
30
+ | --- | --- | --- | --- |
31
+ | `@wix/custom-extensions` | `src/endpoints/hello.ts` | `/hello` | `@wix/custom-extensions/types` |
32
+ | `@wix/astro` | `src/pages/api/hello.ts` | `/api/hello` | `astro` |
33
+
34
+ In `@wix/custom-extensions` projects, endpoints live in `src/endpoints` by default and require
35
+ `@wix/custom-extensions@^0.2.14`; older releases neither scan that directory by
36
+ default nor export `./types`, and the build passes without serving anything. The
37
+ generator upgrades the package; when creating the file by hand, upgrade it
38
+ yourself. Install changed dependencies before validating. If `app()` in
39
+ `src/extensions.ts` passes `apiDir`, that directory (under `src/`) is the one the
40
+ runtime scans instead, and the generator does not read it: either remove `apiDir`
41
+ to use the default, or move the generated file into `src/<apiDir>`. The route is
42
+ `/<name>` either way.
43
+
44
+ If `wix generate` does not recognize `HTTP_ENDPOINT`, the CLI predates the
45
+ generator (added in `@wix/cli` 1.1.243). Update the CLI, or create the file by hand:
46
+ put it in the directory from the table above, export the handlers shown in
47
+ [HTTP Methods](#http-methods), and import `APIRoute` from
48
+ `@wix/custom-extensions/types` or from `astro`, matching the project's runtime. Do
49
+ not add `astro` to a `@wix/custom-extensions` project to make an Astro-style import
50
+ resolve. No registration step is needed.
23
51
 
24
52
  ## File Structure and Naming
25
53
 
26
- ### Basic Endpoint
27
-
28
- File path determines the endpoint URL:
29
-
30
- ```
31
- src/pages/api/<your-endpoint-name>.ts
32
- ```
33
-
34
- ### Dynamic Routes
54
+ Nested paths are relative to the runtime's endpoint directory:
35
55
 
36
- Use square brackets for dynamic parameters:
37
-
38
- ```
39
- src/pages/api/users/[id].ts → /api/users/:id
40
- src/pages/api/posts/[slug].ts → /api/posts/:slug
41
- src/pages/api/users/[userId]/posts/[postId].ts → /api/users/:userId/posts/:postId
42
- ```
56
+ | `@wix/custom-extensions` file | Route | Astro equivalent |
57
+ | --- | --- | --- |
58
+ | `src/endpoints/payments/checkout.ts` | `/payments/checkout` | `src/pages/api/payments/checkout.ts` → `/api/payments/checkout` |
59
+ | `src/endpoints/users/[id].ts` | `/users/:id` | `src/pages/api/users/[id].ts` → `/api/users/:id` |
43
60
 
44
61
  ## HTTP Methods
45
62
 
46
- Export named functions for each HTTP method. Type with `APIRoute` from `astro`. Each handler receives a `request` object and returns a `Response`:
63
+ Export a named handler for each requested HTTP method. Preserve the generated
64
+ `APIRoute` import for the project's runtime. For `@wix/custom-extensions` projects:
47
65
 
48
66
  ```typescript
49
- import type { APIRoute } from "astro";
50
-
51
- export const GET: APIRoute = async ({ request }) => {
52
- console.log("Log from GET."); // This message logs to your CLI.
53
- return new Response("Response from GET."); // This response is visible in the browser console
54
- };
67
+ import type { APIRoute } from "@wix/custom-extensions/types";
55
68
 
56
- export const POST: APIRoute = async ({ request }) => {
57
- const data = await request.json();
58
- console.log("Log POST with body: ", data); // This message logs to your CLI.
59
- return new Response(JSON.stringify(data)); // This response is visible in the browser console.
69
+ export const GET: APIRoute = async () => {
70
+ return Response.json({
71
+ message: "Hello from the backend!",
72
+ timestamp: new Date().toISOString(),
73
+ });
60
74
  };
61
75
  ```
62
76
 
77
+ In an Astro project, use `import type { APIRoute } from "astro"` instead.
78
+ The request/response examples below apply to both runtimes.
79
+
63
80
  ## Request Handling
64
81
 
65
82
  ### Path Parameters
66
83
 
67
84
  ```typescript
68
85
  export const GET: APIRoute = async ({ params }) => {
69
- const { id } = params; // From /api/users/[id]
86
+ const { id } = params; // From users/[id].ts in the endpoint directory
70
87
 
71
88
  if (!id) {
72
- return new Response(JSON.stringify({ error: "ID required" }), {
73
- status: 400,
74
- statusText: "Bad Request",
75
- headers: { "Content-Type": "application/json" },
76
- });
89
+ return Response.json({ error: "ID required" }, { status: 400 });
77
90
  }
78
91
 
79
- // Use id to fetch data
92
+ return Response.json({ id });
80
93
  };
81
94
  ```
82
95
 
@@ -91,7 +104,7 @@ export const GET: APIRoute = async ({ request }) => {
91
104
  const limit = parseInt(url.searchParams.get("limit") || "10", 10);
92
105
  const offset = parseInt(url.searchParams.get("offset") || "0", 10);
93
106
 
94
- // Use query parameters
107
+ return Response.json({ search, limit, offset });
95
108
  };
96
109
  ```
97
110
 
@@ -106,23 +119,15 @@ export const POST: APIRoute = async ({ request }) => {
106
119
  const { title, content } = body;
107
120
 
108
121
  if (!title || !content) {
109
- return new Response(
110
- JSON.stringify({ error: "Title and content required" }),
111
- {
112
- status: 400,
113
- statusText: "Bad Request",
114
- headers: { "Content-Type": "application/json" },
115
- }
122
+ return Response.json(
123
+ { error: "Title and content required" },
124
+ { status: 400 }
116
125
  );
117
126
  }
118
127
 
119
- // Process data
128
+ return Response.json({ title, content });
120
129
  } catch {
121
- return new Response(JSON.stringify({ error: "Invalid JSON" }), {
122
- status: 400,
123
- statusText: "Bad Request",
124
- headers: { "Content-Type": "application/json" },
125
- });
130
+ return Response.json({ error: "Invalid JSON" }, { status: 400 });
126
131
  }
127
132
  };
128
133
  ```
@@ -136,116 +141,110 @@ const contentType = request.headers.get("Content-Type");
136
141
 
137
142
  ## Response Patterns
138
143
 
139
- Always return a `Response` object with proper status codes and headers:
144
+ Return a `Response` from every handler path. `Response.json(body, { status })`
145
+ serializes JSON and sets `Content-Type: application/json` automatically.
140
146
 
141
- ```typescript
142
- // 200 OK
143
- return new Response(JSON.stringify({ data: result }), {
144
- status: 200,
145
- headers: { "Content-Type": "application/json" },
146
- });
147
-
148
- // 201 Created
149
- return new Response(JSON.stringify({ id: newId, ...data }), {
150
- status: 201,
151
- headers: { "Content-Type": "application/json" },
152
- });
153
-
154
- // 204 No Content (for DELETE)
155
- return new Response(null, { status: 204 });
156
-
157
- // 400 Bad Request
158
- return new Response(JSON.stringify({ error: "Invalid input" }), {
159
- status: 400,
160
- statusText: "Bad Request",
161
- headers: { "Content-Type": "application/json" },
162
- });
163
-
164
- // 404 Not Found
165
- return new Response(JSON.stringify({ error: "Not found" }), {
166
- status: 404,
167
- statusText: "Not Found",
168
- headers: { "Content-Type": "application/json" },
169
- });
170
-
171
- // 500 Internal Server Error
172
- return new Response(JSON.stringify({ error: "Internal server error" }), {
173
- status: 500,
174
- statusText: "Internal Server Error",
175
- headers: { "Content-Type": "application/json" },
176
- });
177
- ```
147
+ | Status | Use |
148
+ | --- | --- |
149
+ | 200 | Successful read or update (default) |
150
+ | 201 | Resource created |
151
+ | 204 | Success without a body: `new Response(null, { status: 204 })` |
152
+ | 400 | Invalid request |
153
+ | 404 | Resource not found |
154
+ | 500 | Unexpected server failure; return a generic error |
155
+
156
+ For example: `Response.json({ error: "Not found" }, { status: 404 })`.
178
157
 
179
158
  ## Frontend Integration
180
159
 
181
- Call HTTP endpoints from frontend components using Wix's built-in HTTP client (`httpClient.fetchWithAuth()`):
160
+ For app extensions, use `httpClient.fetchWithAuth()` from `@wix/essentials`.
161
+ Build the URL from the extension module's origin, not the host page's origin.
162
+
163
+ ### `@wix/custom-extensions` Projects
164
+
165
+ `wix dev` may run with `--base`, so the request must preserve
166
+ `import.meta.env.WIX_SERVER_BASE_PATH`. The runtime defaults this value to `/`
167
+ without a configured base, including the normal production build.
168
+ During dev, the injected value is Vite's resolved base, which already has a
169
+ trailing slash even when `--base` omits it. Concatenate the endpoint name
170
+ directly, with `/` as a fallback for a missing/empty value.
171
+ Do not hardcode the base prefix or add `/api` to a `@wix/custom-extensions` route.
182
172
 
183
173
  ```typescript
184
174
  import { httpClient } from "@wix/essentials";
185
175
 
186
- // GET request
187
- const baseApiUrl = new URL(import.meta.url).origin;
188
- const res = await httpClient.fetchWithAuth(
189
- `${baseApiUrl}/api/<your-endpoint-name>`,
190
- );
191
- const data = await res.text();
192
-
193
- // POST request
194
- const res = await httpClient.fetchWithAuth(
195
- `${baseApiUrl}/api/<your-endpoint-name>`,
196
- {
197
- method: "POST",
198
- body: JSON.stringify({ message: "Hello from frontend" }),
199
- },
200
- );
176
+ const origin = new URL(import.meta.url).origin;
177
+ const basePath = import.meta.env.WIX_SERVER_BASE_PATH || "/";
178
+ const endpointUrl = `${origin}${basePath}hello`;
179
+
180
+ // Inside an event handler or runtime data-loading function:
181
+ const res = await httpClient.fetchWithAuth(endpointUrl);
182
+ if (!res.ok) {
183
+ throw new Error(`Request failed: ${res.status}`);
184
+ }
201
185
  const data = await res.json();
202
186
  ```
203
187
 
204
- ## Identity and Authorization
188
+ Keep the module origin: passing only `${basePath}hello` can resolve against the
189
+ hosting site's origin instead of the app server.
190
+
191
+ ### Astro App Extensions
205
192
 
206
- Endpoints run as the **app**, so this is one of the few places `auth.elevate` is valid — it works only in backend code, never in a site, editor, or dashboard extension. It wraps the SDK method rather than being called around it, so inside a request handler you invoke the wrapper:
193
+ For a standard Astro app endpoint, use its `/api` route without the
194
+ `WIX_SERVER_BASE_PATH` variable. If the existing Astro configuration has its own base path,
195
+ preserve that project's URL handling instead of applying the root-only example:
207
196
 
208
197
  ```typescript
209
- import { auth } from "@wix/essentials";
210
- import { locations } from "@wix/business-tools";
198
+ import { httpClient } from "@wix/essentials";
211
199
 
212
- const elevatedArchive = auth.elevate(locations.archiveLocation);
213
- const archived = await elevatedArchive(locationId); // locationId read from the request
200
+ const endpointUrl = new URL("/api/hello", import.meta.url).href;
201
+ const res = await httpClient.fetchWithAuth(endpointUrl);
214
202
  ```
215
203
 
216
- **Only create an endpoint for calls that need it.** Settle that with [Identity and Elevation Requirement](../SKILL.md#identity-and-elevation-requirement) *before* adding a file under `src/pages/api/` — an endpoint wrapping a call the extension could have made itself is a correctness or privacy bug, not extra indirection, because elevating inside it re-targets a session-resolved call away from the visitor or hands back what the platform deliberately withheld.
217
-
218
- **Elevation bypasses Wix's permission check, so the endpoint must re-check the caller itself** — otherwise every caller who can reach it gets the elevated operation, and only `httpClient.fetchWithAuth()` (see [Frontend Integration](#frontend-integration)) sends the caller's identity for the handler to check; a bare `fetch` sends nothing and leaves the endpoint open.
219
-
220
- What you can establish depends on the host: a dashboard caller is a Wix user, whose roles already limit them. From a site or editor extension `members.getMyMember()` identifies a logged-in member, but there is **no documented way to prove the caller is the site owner** — a real constraint, not an oversight, so an owner-only operation belongs in a dashboard extension, where the Wix user identity already carries the authority, rather than behind an endpoint reachable from a site extension.
221
-
222
- ## Build, Deploy, and Delete
204
+ For either runtime, a POST uses the same endpoint URL with `method: "POST"`, a
205
+ JSON body, and `Content-Type: application/json`, provided the route exports POST.
223
206
 
224
- To take HTTP endpoints to production, build and release your project:
225
-
226
- 1. Build the project assets using the [`build`](https://dev.wix.com/docs/wix-cli/command-reference/project-commands/build) command.
227
- 2. Optionally create preview URLs using the [`preview`](https://dev.wix.com/docs/wix-cli/command-reference/project-commands/preview) command to share with team members for testing.
228
- 3. Release your project using the [`release`](https://dev.wix.com/docs/wix-cli/command-reference/project-commands/release) command.
229
-
230
- Once released, endpoints are accessible at production URLs and handle live traffic.
207
+ ## Identity and Authorization
231
208
 
232
- To delete an HTTP endpoint, remove the file under `src/pages/api/` and release again.
209
+ `auth.elevate` works only in backend code. Wrap the SDK method, then invoke
210
+ that wrapper inside the request handler:
233
211
 
234
- ## Output Structure
212
+ ```typescript
213
+ import { auth } from "@wix/essentials";
214
+ import { locations } from "@wix/business-tools";
235
215
 
216
+ const elevatedArchive = auth.elevate(locations.archiveLocation);
217
+ const archived = await elevatedArchive(locationId); // locationId read from the request
236
218
  ```
237
- src/pages/api/
238
- ├── users.ts # /api/users endpoint
239
- ├── users/
240
- │ └── [id].ts # /api/users/:id endpoint
241
- └── posts.ts # /api/posts endpoint
242
- ```
243
-
244
- ## Backend-API-specific Conventions
245
219
 
246
- - Type all handlers with `APIRoute` from `astro`.
247
- - Always return `Response` objects with `JSON.stringify()` for JSON.
248
- - Use proper HTTP status codes (200, 201, 204, 400, 404, 500).
249
- - Include `Content-Type: application/json` header on JSON responses.
250
- - Include `statusText` in error responses.
251
- - Validate input parameters and request bodies.
220
+ Before routing SDK calls through an endpoint, apply the
221
+ [Identity and Elevation Requirement](../SKILL.md#identity-and-elevation-requirement).
222
+ Keep visitor/session-resolved and caller-filtered calls in the frontend: elevation
223
+ can change whose data is accessed or expose data the platform withheld.
224
+
225
+ **Elevation bypasses Wix's permission check.** The endpoint must authorize the
226
+ caller before invoking an elevated method. Use `httpClient.fetchWithAuth()` to
227
+ send caller identity; a bare `fetch` does not supply that identity. Authentication
228
+ alone does not grant permission to perform the operation.
229
+
230
+ Dashboard callers are Wix users. For site/editor callers, `members.getMyMember()`
231
+ identifies a logged-in member but does not prove site ownership. Owner-only
232
+ operations belong in a dashboard extension; do not expose them to site visitors
233
+ on the assumption that member authentication proves ownership.
234
+
235
+ ## Validate, Deploy, and Delete
236
+
237
+ 1. Install changed dependencies, typecheck, and run `wix build`.
238
+ 2. If a dev site is configured (`wix dev-site`), run `wix dev` and request the
239
+ URL; also exercise the frontend caller when one was requested. `wix preview`
240
+ uploads a version and exits; it is not a server.
241
+ 3. When deployment is requested, use the normal build/preview/release commands,
242
+ unless the environment hosting the project manages deployment itself.
243
+
244
+ To delete an endpoint, remove its file from the appropriate directory and apply
245
+ that change through the same deployment flow. No `.use()` cleanup is needed.
246
+
247
+ If a route 404s, or the file was created by hand, confirm it was discovered: in a
248
+ `@wix/custom-extensions` build `grep 'pattern:' dist/server/index.mjs` lists every route (a
249
+ dynamic segment prints as `:"id"`); in an Astro build the route string appears
250
+ under `dist/`. A missing entry means the file is outside the scanned directory.