@wix/agent-skills 1.14.0 → 1.15.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 (247) hide show
  1. package/README.md +4 -1
  2. package/package.json +1 -1
  3. package/skills/README.md +23 -0
  4. package/skills/wix-app/SKILL.md +10 -2
  5. package/skills/wix-app/references/AUTO_PATTERNS_DASHBOARD.md +326 -0
  6. package/skills/wix-app/references/CODE_QUALITY.md +1 -0
  7. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +124 -115
  8. package/skills/wix-app/references/DASHBOARD_PAGE.md +3 -0
  9. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +23 -9
  10. package/skills/wix-app/references/SITE_PLUGIN.md +1 -1
  11. package/skills/wix-app/references/auto-patterns-dashboard/action-cell.md +115 -0
  12. package/skills/wix-app/references/auto-patterns-dashboard/app-config-structure.md +264 -0
  13. package/skills/wix-app/references/auto-patterns-dashboard/app-context.md +37 -0
  14. package/skills/wix-app/references/auto-patterns-dashboard/bulk-actions.md +86 -0
  15. package/skills/wix-app/references/auto-patterns-dashboard/collection-page-actions.md +119 -0
  16. package/skills/wix-app/references/auto-patterns-dashboard/collection-page.md +103 -0
  17. package/skills/wix-app/references/auto-patterns-dashboard/custom-actions-override.md +76 -0
  18. package/skills/wix-app/references/auto-patterns-dashboard/custom-columns-override.md +82 -0
  19. package/skills/wix-app/references/auto-patterns-dashboard/custom-components-override.md +89 -0
  20. package/skills/wix-app/references/auto-patterns-dashboard/custom-header-override.md +124 -0
  21. package/skills/wix-app/references/auto-patterns-dashboard/custom-sections-override.md +91 -0
  22. package/skills/wix-app/references/auto-patterns-dashboard/custom-slots-override.md +71 -0
  23. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-actions.md +70 -0
  24. package/skills/wix-app/references/auto-patterns-dashboard/entity-page-view-actions.md +73 -0
  25. package/skills/wix-app/references/auto-patterns-dashboard/entity-page.md +98 -0
  26. package/skills/wix-app/references/auto-patterns-dashboard/example-patterns.json +278 -0
  27. package/skills/wix-app/references/auto-patterns-dashboard/pages-configuration.md +94 -0
  28. package/skills/wix-app/references/auto-patterns-dashboard/resolved-action.md +43 -0
  29. package/skills/wix-app/references/auto-patterns-dashboard/sdk-utilities.md +66 -0
  30. package/skills/wix-app/references/auto-patterns-dashboard/views.md +76 -0
  31. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +1 -14
  32. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +54 -29
  33. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +2 -2
  34. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +17 -105
  35. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +127 -0
  36. package/skills/wix-app/references/editor-react-component/PARTS.md +2 -1
  37. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +15 -15
  38. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +25 -53
  39. package/skills/wix-app/scripts/generate-auto-patterns.js +510 -0
  40. package/skills/wix-auth/SKILL.md +12 -0
  41. package/skills/wix-auth/references/device-flow.md +140 -0
  42. package/skills/wix-docs/SKILL.md +188 -0
  43. package/skills/wix-docs/references/API_SPEC_SEARCH.md +213 -0
  44. package/skills/wix-docs/references/EXTRACTING.md +120 -0
  45. package/skills/wix-headless/SKILL.md +84 -130
  46. package/skills/wix-headless/entry/bootstrap.mjs +93 -0
  47. package/skills/wix-headless/entry/skill.md +78 -0
  48. package/skills/wix-headless/references/AI_FEATURES.md +178 -0
  49. package/skills/wix-headless/references/CAPABILITIES.md +84 -0
  50. package/skills/wix-headless/references/DISCOVERY.md +34 -56
  51. package/skills/wix-headless/references/DOC_DISCOVERY.md +37 -0
  52. package/skills/wix-headless/references/FEEDBACK.md +118 -0
  53. package/skills/wix-headless/references/IMAGE_GENERATION.md +69 -0
  54. package/skills/wix-headless/references/SDK_HANDOFF.md +97 -0
  55. package/skills/wix-headless/references/SEED.md +44 -188
  56. package/skills/wix-headless/references/SETUP.md +32 -103
  57. package/skills/wix-headless/references/astro.md +98 -0
  58. package/skills/wix-headless/references/inline-recipes/how-to-code-a-blog.md +196 -0
  59. package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +236 -0
  60. package/skills/wix-headless/references/inline-recipes/how-to-code-bookings.md +279 -0
  61. package/skills/wix-headless/references/inline-recipes/how-to-code-cms.md +163 -0
  62. package/skills/wix-headless/references/inline-recipes/how-to-code-events.md +203 -0
  63. package/skills/wix-headless/references/inline-recipes/how-to-code-forms.md +222 -0
  64. package/skills/wix-headless/references/inline-recipes/how-to-code-members-astro.md +124 -0
  65. package/skills/wix-headless/references/inline-recipes/how-to-code-members-custom-login.md +160 -0
  66. package/skills/wix-headless/references/inline-recipes/how-to-code-members-non-astro.md +118 -0
  67. package/skills/wix-headless/references/inline-recipes/how-to-code-portfolio.md +132 -0
  68. package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +124 -0
  69. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +188 -0
  70. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +173 -0
  71. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurants.md +161 -0
  72. package/skills/wix-headless/references/inline-recipes/setup-blog.md +175 -0
  73. package/skills/wix-headless/references/inline-recipes/setup-bookings.md +228 -0
  74. package/skills/wix-headless/references/inline-recipes/setup-cms.md +200 -0
  75. package/skills/wix-headless/references/inline-recipes/setup-events.md +196 -0
  76. package/skills/wix-headless/references/inline-recipes/setup-forms.md +174 -0
  77. package/skills/wix-headless/references/inline-recipes/setup-online-store.md +176 -0
  78. package/skills/wix-headless/references/inline-recipes/setup-portfolio.md +153 -0
  79. package/skills/wix-headless/references/inline-recipes/setup-pricing-plans.md +229 -0
  80. package/skills/wix-headless/references/inline-recipes/setup-restaurant-orders.md +161 -0
  81. package/skills/wix-headless/references/inline-recipes/setup-restaurant-reservations.md +117 -0
  82. package/skills/wix-headless/references/inline-recipes/setup-restaurants.md +152 -0
  83. package/skills/wix-headless/references/managed/AUTHENTICATION.md +57 -0
  84. package/skills/wix-headless/references/managed/CONNECT.md +74 -0
  85. package/skills/wix-headless/references/managed/CREATE.md +130 -0
  86. package/skills/wix-headless/references/managed/DEPLOYMENT.md +57 -0
  87. package/skills/wix-headless/references/non-astro.md +59 -0
  88. package/skills/wix-headless/references/self-managed/AUTHENTICATION.md +22 -0
  89. package/skills/wix-headless/references/self-managed/DEPLOYMENT.md +7 -0
  90. package/skills/wix-headless/references/stripe/AUTHENTICATION.md +55 -0
  91. package/skills/wix-headless/references/stripe/DEPLOYMENT.md +63 -0
  92. package/skills/wix-manage/SKILL.md +24 -1
  93. package/skills/wix-manage/references/analytics/query-site-analytics.md +241 -0
  94. package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +1 -1
  95. package/skills/wix-manage/references/bookings/diagnose-availability-issues.md +265 -0
  96. package/skills/wix-manage/references/marketing/create-and-publish-social-post.md +436 -0
  97. package/skills/wix-manage/references/marketing/generate-and-publish-marketing-plan.md +209 -0
  98. package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +249 -0
  99. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +51 -0
  100. package/skills/wix-vibe-headless/SKILL.md +136 -0
  101. package/skills/wix-vibe-headless/references/blog/INSTRUCTIONS.md +128 -0
  102. package/skills/wix-vibe-headless/references/blog/wix-blog.js +217 -0
  103. package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +153 -0
  104. package/skills/wix-vibe-headless/references/bookings/wix-bookings-checkout.js +147 -0
  105. package/skills/wix-vibe-headless/references/bookings/wix-bookings-services.js +215 -0
  106. package/skills/wix-vibe-headless/references/cms/INSTRUCTIONS.md +154 -0
  107. package/skills/wix-vibe-headless/references/cms/wix-cms.js +186 -0
  108. package/skills/wix-vibe-headless/references/events/INSTRUCTIONS.md +142 -0
  109. package/skills/wix-vibe-headless/references/events/wix-events-browse.js +135 -0
  110. package/skills/wix-vibe-headless/references/events/wix-events-registration.js +187 -0
  111. package/skills/wix-vibe-headless/references/members/INSTRUCTIONS.md +211 -0
  112. package/skills/wix-vibe-headless/references/members/wix-members-auth.js +387 -0
  113. package/skills/wix-vibe-headless/references/portfolio/INSTRUCTIONS.md +111 -0
  114. package/skills/wix-vibe-headless/references/portfolio/wix-portfolio.js +194 -0
  115. package/skills/wix-vibe-headless/references/pricing-plans/INSTRUCTIONS.md +127 -0
  116. package/skills/wix-vibe-headless/references/pricing-plans/wix-pricing-plans.js +157 -0
  117. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +138 -0
  118. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-menu.js +224 -0
  119. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-ordering.js +156 -0
  120. package/skills/wix-vibe-headless/references/restaurants/wix-restaurants-reservations.js +107 -0
  121. package/skills/wix-vibe-headless/references/shared/wix-client.js +186 -0
  122. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +155 -0
  123. package/skills/wix-vibe-headless/references/storefront/wix-store-cart.js +147 -0
  124. package/skills/wix-vibe-headless/references/storefront/wix-store-catalog.js +142 -0
  125. package/skills/wix-headless/references/BUILD-astro.md +0 -253
  126. package/skills/wix-headless/references/BUILD-own-build.md +0 -167
  127. package/skills/wix-headless/references/BUILD.md +0 -105
  128. package/skills/wix-headless/references/DESIGN_SYSTEM.md +0 -165
  129. package/skills/wix-headless/references/DISCOVERY-connect.md +0 -55
  130. package/skills/wix-headless/references/DISCOVERY-create.md +0 -238
  131. package/skills/wix-headless/references/PLAN-connect.md +0 -19
  132. package/skills/wix-headless/references/PLAN-create.md +0 -17
  133. package/skills/wix-headless/references/PLAN.md +0 -92
  134. package/skills/wix-headless/references/astro/blog/BLOG_PAGES.md +0 -300
  135. package/skills/wix-headless/references/astro/blog/BLOG_SETUP.md +0 -218
  136. package/skills/wix-headless/references/astro/bookings/COMPONENTS.md +0 -45
  137. package/skills/wix-headless/references/astro/bookings/SERVICES_PAGES.md +0 -77
  138. package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +0 -214
  139. package/skills/wix-headless/references/astro/cms/FAQ_KNOWLEDGE_BASE.md +0 -231
  140. package/skills/wix-headless/references/astro/cms/PORTFOLIO.md +0 -453
  141. package/skills/wix-headless/references/astro/cms/RESOURCE_LIBRARY.md +0 -354
  142. package/skills/wix-headless/references/astro/cms/TEAM_DIRECTORY.md +0 -299
  143. package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +0 -351
  144. package/skills/wix-headless/references/astro/ecom/CART_PAGES.md +0 -119
  145. package/skills/wix-headless/references/astro/ecom/CART_WIRING.md +0 -103
  146. package/skills/wix-headless/references/astro/ecom/COMPONENTS_CSS.md +0 -132
  147. package/skills/wix-headless/references/astro/forms/CONTACT_FORM.md +0 -463
  148. package/skills/wix-headless/references/astro/gift-cards/COMPONENTS.md +0 -119
  149. package/skills/wix-headless/references/astro/gift-cards/PAGES.md +0 -129
  150. package/skills/wix-headless/references/astro/stores/BACK_IN_STOCK.md +0 -178
  151. package/skills/wix-headless/references/astro/stores/CATEGORY_PAGES.md +0 -85
  152. package/skills/wix-headless/references/astro/stores/COMPONENTS_CSS.md +0 -129
  153. package/skills/wix-headless/references/astro/stores/HOME_AND_NAV.md +0 -229
  154. package/skills/wix-headless/references/astro/stores/PRODUCT_PAGES.md +0 -215
  155. package/skills/wix-headless/references/astro/stores/SHARED_WIRING.md +0 -165
  156. package/skills/wix-headless/references/astro/templates/Layout.astro +0 -132
  157. package/skills/wix-headless/references/astro/templates/astro.config.mjs +0 -41
  158. package/skills/wix-headless/references/astro/templates/bookings/AvailabilityCalendar.tsx +0 -374
  159. package/skills/wix-headless/references/astro/templates/bookings/BookingForm.tsx +0 -136
  160. package/skills/wix-headless/references/astro/templates/bookings/SeoTags.astro +0 -25
  161. package/skills/wix-headless/references/astro/templates/bookings/ServiceBookingFlow.tsx +0 -71
  162. package/skills/wix-headless/references/astro/templates/bookings/ServiceCard.astro +0 -54
  163. package/skills/wix-headless/references/astro/templates/bookings/booking-confirmation.astro +0 -49
  164. package/skills/wix-headless/references/astro/templates/bookings/bookingDriver.ts +0 -245
  165. package/skills/wix-headless/references/astro/templates/bookings/components-bookings.css +0 -424
  166. package/skills/wix-headless/references/astro/templates/bookings/services/[slug].astro +0 -176
  167. package/skills/wix-headless/references/astro/templates/bookings/services/index.astro +0 -181
  168. package/skills/wix-headless/references/astro/templates/ecom/CartBadge.tsx +0 -84
  169. package/skills/wix-headless/references/astro/templates/ecom/CartView.tsx +0 -543
  170. package/skills/wix-headless/references/astro/templates/ecom/cart.astro +0 -13
  171. package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +0 -302
  172. package/skills/wix-headless/references/astro/templates/ecom/discounts.ts +0 -71
  173. package/skills/wix-headless/references/astro/templates/ecom/thank-you.astro +0 -24
  174. package/skills/wix-headless/references/astro/templates/gift-cards/GiftCardPurchase.tsx +0 -172
  175. package/skills/wix-headless/references/astro/templates/gift-cards/_home-teaser-snippet.astro +0 -42
  176. package/skills/wix-headless/references/astro/templates/gift-cards/_nav-snippet.astro +0 -11
  177. package/skills/wix-headless/references/astro/templates/gift-cards/components-gift-cards.css +0 -220
  178. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.astro +0 -51
  179. package/skills/wix-headless/references/astro/templates/gift-cards/gift-cards.ts +0 -75
  180. package/skills/wix-headless/references/astro/templates/global.css +0 -288
  181. package/skills/wix-headless/references/astro/templates/stores/AddToCartButton.tsx +0 -77
  182. package/skills/wix-headless/references/astro/templates/stores/BackInStockForm.tsx +0 -176
  183. package/skills/wix-headless/references/astro/templates/stores/CategoryRail.astro +0 -69
  184. package/skills/wix-headless/references/astro/templates/stores/ProductCard.astro +0 -79
  185. package/skills/wix-headless/references/astro/templates/stores/ProductPurchase.tsx +0 -397
  186. package/skills/wix-headless/references/astro/templates/stores/SeoTags.astro +0 -21
  187. package/skills/wix-headless/references/astro/templates/stores/back-in-stock.ts +0 -67
  188. package/skills/wix-headless/references/astro/templates/stores/categories.ts +0 -155
  189. package/skills/wix-headless/references/astro/templates/stores/category/[slug].astro +0 -130
  190. package/skills/wix-headless/references/astro/templates/stores/components-stores.css +0 -400
  191. package/skills/wix-headless/references/astro/templates/stores/products/[slug].astro +0 -128
  192. package/skills/wix-headless/references/astro/templates/stores/products/index.astro +0 -101
  193. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +0 -161
  194. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +0 -32
  195. package/skills/wix-headless/references/bookings/FLOW.md +0 -246
  196. package/skills/wix-headless/references/bookings/INSTRUCTIONS.md +0 -95
  197. package/skills/wix-headless/references/bookings/SERVICES_DATA.md +0 -355
  198. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +0 -176
  199. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +0 -71
  200. package/skills/wix-headless/references/commands/known-apps.json +0 -6
  201. package/skills/wix-headless/references/custom/CONNECTION_PLAN.md +0 -142
  202. package/skills/wix-headless/references/custom/INSTRUCTIONS.md +0 -88
  203. package/skills/wix-headless/references/custom/blog/WIRING.md +0 -52
  204. package/skills/wix-headless/references/custom/bookings/WIRING.md +0 -197
  205. package/skills/wix-headless/references/custom/cms/WIRING.md +0 -97
  206. package/skills/wix-headless/references/custom/ecom/WIRING.md +0 -67
  207. package/skills/wix-headless/references/custom/forms/WIRING.md +0 -101
  208. package/skills/wix-headless/references/custom/stores/WIRING.md +0 -80
  209. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +0 -59
  210. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +0 -43
  211. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +0 -51
  212. package/skills/wix-headless/references/images/INSTRUCTIONS.md +0 -357
  213. package/skills/wix-headless/references/seed-recipes.md +0 -49
  214. package/skills/wix-headless/references/shared/AGENTS_MD.md +0 -47
  215. package/skills/wix-headless/references/shared/AUTHENTICATION.md +0 -108
  216. package/skills/wix-headless/references/shared/BUILD_NOISE.md +0 -8
  217. package/skills/wix-headless/references/shared/DESIGN_MD.md +0 -84
  218. package/skills/wix-headless/references/shared/DOCS_SEARCH.md +0 -41
  219. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +0 -186
  220. package/skills/wix-headless/references/shared/IMPLEMENTER.md +0 -206
  221. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +0 -97
  222. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +0 -143
  223. package/skills/wix-headless/references/shared/STYLING.md +0 -140
  224. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +0 -126
  225. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +0 -252
  226. package/skills/wix-headless/references/verticals/_schema.json +0 -74
  227. package/skills/wix-headless/references/verticals/_schema.md +0 -95
  228. package/skills/wix-headless/references/verticals/blog.md +0 -31
  229. package/skills/wix-headless/references/verticals/bookings.md +0 -41
  230. package/skills/wix-headless/references/verticals/cms.md +0 -30
  231. package/skills/wix-headless/references/verticals/ecom.md +0 -25
  232. package/skills/wix-headless/references/verticals/forms.md +0 -26
  233. package/skills/wix-headless/references/verticals/gift-cards.md +0 -24
  234. package/skills/wix-headless/references/verticals/stores.md +0 -33
  235. package/skills/wix-headless/scripts/check-manifest.mjs +0 -335
  236. package/skills/wix-headless/scripts/compose.mjs +0 -520
  237. package/skills/wix-headless/scripts/emit-design-tokens.mjs +0 -157
  238. package/skills/wix-headless/scripts/flatten.sh +0 -61
  239. package/skills/wix-headless/scripts/generate-images.mjs +0 -242
  240. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +0 -154
  241. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +0 -190
  242. package/skills/wix-headless/scripts/scaffold.sh +0 -139
  243. package/skills/wix-headless/scripts/seed-utilities.sh +0 -93
  244. package/skills/wix-headless/scripts/write-decorative-json.mjs +0 -62
  245. package/skills/wix-headless/shared-utilities/analytics.ts +0 -40
  246. package/skills/wix-headless/shared-utilities/ricos.ts +0 -179
  247. package/skills/wix-headless/shared-utilities/wix-image.ts +0 -72
@@ -1,129 +1,58 @@
1
- # Setup
1
+ # Setup — install the business apps
2
2
 
3
- Runs once after approval, with the contract in scratch. Domain: install the apps the loaded packs declare, pull the Wix env, run `npm install`, and read `siteId` + `appId` from `wix.config.json` into scratch. Run flow (timing, handles, waits, batching) is owned by the framework conductor (`BUILD-astro.md` / `BUILD-own-build.md`; Setup is an early run-step in each).
3
+ Install the Wix apps the resolved capabilities need, on the given metasite. That is the whole of setup — the frontend toolchain stays with the host.
4
4
 
5
- This article is the **astro entry path** (`frontendBuild === "wix"`): Steps 1–5 + npm recovery. The `none`/`own` classes reuse **only** Step 4a (app installs); their skips (no `env pull`, no `scaffold.sh`, no per-pack `npm install`, no `seed-utilities.sh`) and their `init` bootstrap are owned by `BUILD-own-build.md`. Assumes `DISCOVERY.md`'s CLI-auth pre-flight passed. Routing: `PLAN.md` § "Operation routing" + `BUILD.md`.
5
+ ## 1 · Obtain the token
6
6
 
7
- ---
7
+ Obtain `$TOKEN` (a bearer authorized for the metasite) and `$SITE_ID` (the metasite id) **using the provided authentication mechanism** — see `<TYPE_DIR>/AUTHENTICATION.md`. Hold them for the install calls below.
8
8
 
9
- ## Step 1 — Read the scaffolded project config (siteId + appId)
9
+ All Wix REST calls in this skill then use the same universal call shape:
10
10
 
11
- > **Single folder — CWD == project == site-root.** `scaffold.sh` flattens the project into CWD: one folder, one `.wix/` (`package.json`, `src/`, `wix.config.json`, `.wix/design-tokens.css`, …), with the end-of-run `AGENTS.md` at its root. Never `cd` into a subdir or look in a parent for `.wix`. `<site-root>` == `<project-dir>` == CWD; pass absolute paths only when a call runs in its own subshell.
12
-
13
- Do **not** speculatively `Read ./wix.config.json` before the scaffold completes — it doesn't exist yet on a fast-Q&A run, so the read fails and wastes a round-trip.
14
-
15
- Once `scaffold_handle` returns, read `./wix.config.json` and hold in scratch:
16
- - `siteId` — passed as `--site` to `npx @wix/cli@latest token`, embedded in every install body + the `wix-site-id` header on every site-scoped REST call.
17
- - `appId` — goes into the SDK's `createClient` inputs later.
18
-
19
- Capture CWD as `<site-root>` in scratch. No `cd` step — every file op runs in the project root.
20
-
21
- ---
22
-
23
- ## Step 3 — Invoke the `wix-manage` skill
24
-
25
- **Always invoke `Skill(name="wix-manage")` here** — it is the only thing that publishes `<wix-manage-root>` into scratch **and loads the recipe files into context** (Step 4's installs and the whole Seed phase reuse them; `SEED.md` does not re-invoke). A known directory path is not a substitute — the recipes must be in context. Use the harness's skill-invocation primitive (Claude Code: `Skill(name="wix-manage")`); the prose instruction is the contract — don't hardcode a tool-call snippet.
26
-
27
- Then read the app-install recipe by absolute path (the `Skill` invocation must precede this Read — it needs the path `wix-manage`'s SKILL.md publishes):
28
-
29
- ```
30
- Read <wix-manage-root>/references/app-installation/install-wix-apps.md
31
11
  ```
32
-
33
- The recipe's Step 2 documents the install body shape:
34
-
35
- ```
36
- tenant: { tenantType: "SITE", id: "<siteId>" }
37
- appInstance: { appDefId: "<pack.apps[N].appDefId>" }
12
+ Authorization: Bearer $TOKEN
13
+ wix-site-id: $SITE_ID
14
+ Content-Type: application/json
38
15
  ```
39
16
 
40
- Endpoint: `POST https://www.wixapis.com/apps-installer-service/v1/app-instance/install`.
41
-
42
- > **Recipe call shape.** Recipes are authored in `curl` form. Build each call with the headers in `references/shared/AUTHENTICATION.md` (`Authorization: Bearer $TOKEN` + `wix-site-id: $SITE_ID` + `Content-Type: application/json`). The recipe's URL/method/body are the source of truth.
43
-
44
- > **Missing-skill fallback (only if the `Skill` primitive errors):** fall back to the install body shape above (REST-shaped and stable) and note the missing skill in the run digest. Don't silently substitute — `wix-manage` is the canonical entry point.
17
+ ## 2 · Install one app per capability
45
18
 
46
- ---
19
+ For each capability in `verticals[]`, install its app by `appDefId` (these are the constants the install call needs):
47
20
 
48
- ## Step 4 — One concurrent batch
21
+ - **stores** → `215238eb-22a5-4c36-9e7b-e7c08025e04e`
22
+ - **blog** → `14bcded7-0066-7c35-14d7-466cb3f09103`
23
+ - **forms** → `225dd912-7dea-4738-8688-4b8c6955ffc2`
24
+ - **events** → `140603ad-af8d-84a5-2c80-a0f60cb47351`
25
+ - **bookings** → `13d21c63-b5ec-5912-8397-c3a5ddb27a97`
26
+ - **pricing-plans** → `1522827f-c56c-a5c9-2ac9-00f9e6ae12d3`
27
+ - **restaurants** → `b278a256-2757-4f19-9313-c05c783bec92` (Wix Restaurants **Menus** — the seedable core). Online ordering and table reservations are **separate optional apps**, install only if intent calls for them: Orders (New) → `9a5d83fd-8570-482e-81ab-cfa88942ee60`, Table Reservations → `f9c07de2-5341-40c6-b096-8eb39de391fb`.
28
+ - **portfolio** → `d90652a2-f5a1-4c7c-84c4-d4cdcc41f130` (Wix Portfolio; the install ships a default sample collection + projects — `setup-portfolio.md` STEP 0 cleans them)
29
+ - **cms** → **no install** (Wix Data is core) — skip
49
30
 
50
- Fire 4a + 4b + 4c as a single concurrent batch (`PLAN.md` § "Batching discipline").
31
+ For any vertical added later, its appDefId is in the docs — "Apps Created by Wix": <https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/platform/about-apps-created-by-wix.md>.
51
32
 
52
- ### 4a. App installs — one `curl` per `pack.apps[*]` (business track, frontend-blind)
33
+ > **members — install is conditional on the layer, and only the *profile* layer installs anything.** Members is a cross-cutting capability (`CAPABILITIES.md`), not a `verticals[]` entry, so it has no unconditional row above. Split by layer:
34
+ > - **Identity only** (sign-up / log-in / log-out, "logged-in vs not" gating — the common case, and all that pricing-plans' subscribe flow needs) → **no install.** It's the headless OAuth app; members self-register. Skip, exactly like cms.
35
+ > - **Profile / Members Area** (the site *displays or edits* member data — name / photo / roles / badges, a my-account page) → install the **Wix Members Area app**, `appDefId` **`14cc59bc-f0b7-15b8-e1c7-89ce41d0e0c9`** (via the same `apps-installer-service` call above; it pulls in its Site-Members dependency automatically). **Wrinkle:** Members Area is **not** in the "Apps Created by Wix" table (that table has Stores, Blog, Pricing Plans, Groups… but no Members Area), so the GUID can't be grabbed from there — it comes from the App Market listing (<https://www.wix.com/app-market/web-solution/members-area>). Install it **only when the run genuinely needs profile data**; pure "logged-in vs not" gating (the common case) is the identity layer and needs no install.
53
36
 
54
- The install body is identical per `pack.apps[*]` regardless of frontend. Mint the site-scoped REST token once, cache it for the run, then fire one `curl` per `apps:` entry across every loaded pack (top-level + transitive via `requires:`):
37
+ Fire one install `curl` per app — `POST /apps-installer-service/v1/app-instance/install`:
55
38
 
56
39
  ```bash
57
- SITE_ID="<siteId>"
58
- TOKEN=$(npx @wix/cli@latest token --site "$SITE_ID") # once; cache in scratch for the run
59
-
60
- # per-pack iteration; one curl per pack.apps[*]:
61
- curl -sS -X POST "https://www.wixapis.com/apps-installer-service/v1/app-instance/install" \
40
+ # TOKEN, SITE_ID from the provided authentication mechanism — see <TYPE_DIR>/AUTHENTICATION.md
41
+ curl -sS -w "\nHTTP_STATUS:%{http_code}" \
42
+ -X POST "https://www.wixapis.com/apps-installer-service/v1/app-instance/install" \
62
43
  -H "Authorization: Bearer $TOKEN" \
63
44
  -H "wix-site-id: $SITE_ID" \
64
45
  -H "Content-Type: application/json" \
65
46
  -d '{
66
47
  "tenant": { "tenantType": "SITE", "id": "'"$SITE_ID"'" },
67
- "appInstance": { "appDefId": "<pack.apps[N].appDefId>", "enabled": true }
48
+ "appInstance": { "appDefId": "<appDefId>", "enabled": true }
68
49
  }'
69
50
  ```
70
51
 
71
- Use `npx @wix/cli@latest token …` (not bare `wix token`) — `npx` resolves the project-local CLI the scaffold produced (first call auto-fetches it ~3–5 s if missing). A 200 confirms the install. On 401/403, retry the same call once with the cached token (do **not** re-mint — it's byte-identical for the run; recovery ladder in `references/shared/AUTHENTICATION.md`); a persistent 401 usually means the CLI session expired and `wix login` is required — surface the response body.
72
-
73
- Packs with `apps: []` (`cms`, `ecom`) or `disabled: true` (`gift-cards`, whose `apps:` is empty by design — the user opts in via the dashboard) install nothing — skip the curl.
74
-
75
- ### 4b. `npx @wix/cli@latest env pull --json`
76
-
77
- Foreground, ~5 s. Writes `WIX_CLIENT_ID` to `.env.local` (idempotent). Skipping it causes `Missing environment variable WIX_CLIENT_ID` build failures downstream. **Always pass `--json`** — without it the CLI emits an interactive spinner that floods the non-TTY pipe with ANSI frames; `--json` gives one clean line (the skill only needs `.env.local` on disk).
78
-
79
- ### 4c. Dispatch background `npm install`
80
-
81
- Background shell; capture `npm_handle` + `<npm-tempfile>` in scratch. Trust the exit code at the seed gate — do not probe `node_modules`.
82
-
83
- ```bash
84
- npm install --no-fund --no-audit --legacy-peer-deps <package-set> \
85
- 2> <npm-tempfile>
86
- # dispatched with run_in_background: true; capture as npm_handle
87
- ```
88
-
89
- `<package-set>` from the resolved pack set (loaded + transitive via `requires:`):
90
-
91
- | Always | Add when pack is loaded |
92
- |---|---|
93
- | `@wix/sdk tailwindcss @tailwindcss/vite` | — |
94
- | | **stores** → `@wix/stores` |
95
- | | **ecom** (direct or via stores `requires:`) → `@wix/ecom @wix/redirects` |
96
- | | **blog** → `@wix/blog @wix/ricos @astrojs/rss @astrojs/sitemap` |
97
- | | **forms** → `@wix/forms` |
98
- | | **cms** → `@wix/data @wix/essentials` |
99
- | | **bookings** → `@wix/bookings @wix/essentials @wix/forms @wix/redirects @wix/auto_sdk_ecom_cart-v-2` |
100
- | | **gift-cards** → (none — disabled-by-default pack ships no Astro-time imports) |
101
-
102
- Example (resolved set = stores + ecom + gift-cards + cms):
103
-
104
- ```bash
105
- npm install --no-fund --no-audit --legacy-peer-deps \
106
- @wix/sdk @wix/stores @wix/ecom @wix/redirects \
107
- @wix/data @wix/essentials \
108
- tailwindcss @tailwindcss/vite \
109
- 2> <npm-tempfile>
110
- ```
111
-
112
- Use `npm --legacy-peer-deps` — `pnpm` fails against the `@wix/cli` template. **Skipping the per-pack additions makes `astro build` fail with `Rollup failed to resolve import "@wix/<pack>"`** (~30 s recovery). Don't invent packages beyond the table; extend the table for a new vertical.
113
-
114
- ---
115
-
116
- ## Step 5 — Transition to Seed
117
-
118
- Setup prints no summary. Before transitioning to `SEED.md`, confirm: `siteId` + `appId` in scratch (from `wix.config.json`, both non-empty), the cached token mints, every `apps:` pack got a 200 (empty-`apps:` packs skipped), `.env.local` contains `WIX_CLIENT_ID`, and `npm_handle` was dispatched. On any failure, surface it verbatim instead of proceeding.
119
-
120
- ---
121
-
122
- ## npm install recovery
52
+ The installs are independent — issue them in whatever order is convenient.
123
53
 
124
- Invoked when `npm_handle` returns non-zero (dispatched in Step 4c, waited at the seed gate in `BUILD-astro.md`):
54
+ A **200** confirms the install. On a non-200, surface the response verbatim and stop.
125
55
 
126
- 1. **Foreground retry** `npm install --no-fund --no-audit --legacy-peer-deps <packages>` (90 s timeout). If it hangs, add `--prefer-offline`; if still hanging, `npm cache clean --force` and retry once more.
127
- 2. **Last resort:** ask the user to run `npm install --legacy-peer-deps` manually and report back. Don't substitute pnpm/yarn — pnpm fails against the `@wix/cli` template.
56
+ ## 3 · Proceed to Seed
128
57
 
129
- Package set = the Step 4c table (always-on three ∪ per-pack packages). Don't invent package names.
58
+ Confirm every required app returned 200 (cms skipped). Then continue to **`SEED.md`**, which seeds from the local inline recipes.
@@ -0,0 +1,98 @@
1
+ # Astro — the pinned docs to read *before* connecting an Astro frontend to Wix
2
+
3
+ Astro is the **documented default** frontend for Wix-managed headless — pick it unless the user names another framework (then read `non-astro.md` instead). This file is to *wiring an Astro frontend to the Wix backend* what `SEED.md` is to seeding: the pointer to *how* it connects — an **index of doc pages**, each with a one-line "what it settles" note, **followed by a Caveats section** carrying the things the docs don't say. It holds **no config blobs, page skeletons, design tokens, or payloads** — the model designs and writes the whole frontend; this file only says *how to connect it* and *what to watch out for*.
4
+
5
+ **Auto-auth is the whole point.** On managed-Astro you create **no client** — no `createClient`, no `OAuthStrategy`, no `clientId`, no token handling in app code. You `import { x } from "@wix/<pkg>"` and call methods; `@wix/astro` + the session middleware authenticate every call automatically (§2, §3). The manual OAuth client survives **only** off this path — self-managed or non-Astro frontends (`non-astro.md`).
6
+
7
+ **Hard constraint up front: Astro 5 only.** `headless link` does **not** support Astro 6 — check the project's Astro major before linking an existing project (Caveat A1).
8
+
9
+ **How to use it.** Before scaffolding, wiring, or releasing, look the task up here and read its pinned pages top-to-bottom until you can act — read-then-act, never invent a URL or a config from memory. If a task has no entry, navigate from the doc index in §4.
10
+
11
+ **URL form & how to read it.** Each pinned link is the **`.md` twin** of a docs article (the article URL with `.md` appended). A page pinned here is **already curated — read it directly; don't re-discover it with search.** The two read paths take **different URL forms** — don't mix them:
12
+
13
+ - **`curl` the pinned link — first priority. Fetch it as-is (keep the `.md`)** for raw markdown.
14
+ - **MCP doc tools — second priority** (discovery of a page this file doesn't pin, or a fallback if a fetch fails). **Pass the URL *without* the `.md` suffix:** `ReadFullDocsArticle` for the guide/article pages here; `SearchWixCLIDocumentation` / `SearchWixHeadlessDocumentation` / `SearchWixSDKDocumentation` to reach an unpinned command or method page.
15
+ - **No MCP, or a shape not pinned anywhere → doc discovery** (`DOC_DISCOVERY.md`): a `curl` semantic search (`document_type: SDK`/`WIX_HEADLESS`) plus structured schema lookup, then read the hit's `.md?apiView=SDK`.
16
+
17
+ ---
18
+
19
+ ## 1 — Get the project onto Wix (scaffold / link / connect)
20
+
21
+ Pick the row that matches the operation, then read it before running anything.
22
+
23
+ | Page | What it settles |
24
+ |---|---|
25
+ | <https://dev.wix.com/docs/wix-cli/command-reference/project-creation/create-headless.md> | **`create`** — `npm create @wix/new@latest -- headless`. The flags (`--folder-name`, `--business-name`, `--site-template`, `--skip-install`, `--skip-git`, `--no-publish`) and the **required `--` separator**. `--site-template` accepts `commerce\|scheduler\|registration\|blank`, but **we don't adopt the business templates** — the model designs, so scaffold `blank` and let config come from Wix, not template pages. |
26
+ | <https://dev.wix.com/docs/go-headless/get-started/quick-starts/wix-managed-headless/quick-start-from-an-existing-astro-project.md> | **`connect`** (user brought an Astro project) — `npm create @wix/new@latest -- headless link`. The end-to-end "link an Astro project I already have" flow. |
27
+ | <https://dev.wix.com/docs/wix-cli/command-reference/project-creation/create-headless-link.md> | **`headless link` reference** — link flags and **exactly what it mutates in `astro.config.mjs`** (the integration list, `output: 'server'`, the image domain, the prod fetch adapter). Read alongside Caveat A2 — the docs' list is incomplete. |
28
+ | <https://dev.wix.com/docs/wix-cli/command-reference/project-creation/create-init.md> | **`init`** — connect existing code in place without scaffolding (the lower-level connect primitive). |
29
+ | <https://dev.wix.com/docs/go-headless/get-started/quick-starts/wix-managed-headless/quick-start-with-the-wix-cli.md> | The end-to-end orientation for a fresh managed project, start to finish — read once for the shape of the whole flow. |
30
+
31
+ ## 2 — The integration & auth (the keystone)
32
+
33
+ This is what makes managed-Astro different from every other path: authentication is automatic.
34
+
35
+ | Page | What it settles |
36
+ |---|---|
37
+ | <https://dev.wix.com/docs/go-headless/wix-managed-headless/authentication/about-the-astro-integration.md> | **The keystone.** Auto-auth via the private app as OAuth handler, visitor sessions, member login, extensions, elevation. This is the "no client" anchor — read it first for §2/§3. |
38
+ | <https://dev.wix.com/docs/go-headless/wix-managed-headless/authentication/handle-member-login-using-wix-s-astro-integration.md> | **Member login** — the built-in `/api/auth/login` + `/api/auth/logout` routes and the `returnUrl` param. Use these instead of hand-rolling login. **For the full frontend contract (login = sign-up, gate in SSR/backend route, current member via `@wix/members`, no client, no elevate, pricing-plans dependency) → Read `inline-recipes/how-to-code-members-astro.md`** (local — Read it, don't curl). **Only if the brief explicitly asks for a custom/branded login form or custom sign-up fields → Read `inline-recipes/how-to-code-members-custom-login.md`** instead (a client-driven `OAuthStrategy` flow — on Astro that means an explicit client in a backend route, outside auto-auth; pick by intent, not project type). |
39
+ | <https://dev.wix.com/docs/go-headless/wix-managed-headless/authentication/elevate-api-call-permissions.md> | **Elevation.** A privileged read at runtime goes in a **backend HTTP endpoint** (`src/pages/api/*.ts`, `export const GET: APIRoute`) that wraps `auth.elevate()`, called from the frontend via `fetch('/api/…')`. This is the documented shape — prefer it over inline-frontmatter elevation. |
40
+ | <https://dev.wix.com/docs/go-headless/wix-managed-headless/authentication/fix-403-errors-for-api-calls.md> | **Fix 403** — the identity-vs-permission troubleshooting page; read when a call 403s to tell "wrong identity" from "needs elevation." |
41
+
42
+ ## 3 — Frontend data access (SDK, no client)
43
+
44
+ | Page | What it settles |
45
+ |---|---|
46
+ | <https://dev.wix.com/docs/sdk/articles/set-up-a-client/about-the-wix-client.md> | **Confirms managed-Astro is on the "don't need a client" list** — the client/`OAuthStrategy` is for self-managed only. Read it to be sure you should *not* be constructing a client here. |
47
+ | <https://dev.wix.com/docs/api-reference/articles/sdk-setup-and-usage/develop-with-the-sdk.md> | **Develop with the SDK** — calling SDK methods across SSR / islands / backend endpoints, and where elevation fits. |
48
+
49
+ One line on what reaches the frontend: **visitor-scoped reads work out of the box** with no wiring. **Admin-only data is seeded at build time** (see `SEED.md`) — don't reach for runtime elevation unless the data genuinely can't be seeded ahead of time.
50
+
51
+ ## 4 — CLI, project structure, dev loop, release
52
+
53
+ | Page | What it settles |
54
+ |---|---|
55
+ | <https://dev.wix.com/docs/wix-cli/guides/about-the-wix-cli.md> | What the CLI is and why the structure is Astro-based; auto-auth + session middleware framing. |
56
+ | <https://dev.wix.com/docs/wix-cli/guides/project-structure/project-structure.md> | **On-disk layout** — `.wix/`, `.astro/`, `astro.config.mjs`, `.env.local`, `wix.config.json`, `src/`. What's generated and not to be hand-edited. (Field-name note: `wix.config.json` carries `appId` + `siteId`/`projectId` — read defensively.) |
57
+ | <https://dev.wix.com/docs/wix-cli/command-reference/project-commands/dev.md> | **`wix dev`** — local dev server with hot reload. |
58
+ | <https://dev.wix.com/docs/wix-cli/command-reference/project-commands/build.md> | **`wix build`** — build before release/preview. |
59
+ | <https://dev.wix.com/docs/wix-cli/command-reference/project-commands/release.md> | **`wix release`** — publishes the **frontend build output** to Wix hosting and registers the origin OOTB. **Release once, at the end** (`managed/CREATE.md` §5 / `CONNECT.md` §5) — not mid-flow. Re-release **only** when the build output itself changed. **Seeded backend content and entity images are fetched at runtime, not baked into the build** — a re-release does **not** refresh them, so never re-release to "clear a cache" for a backend data/image change (that's a red herring; a backend image not showing is an attach-shape bug — `SEED.md` § "Entity images"). Only if a genuine *frontend* republish shows stale build output does running `wix release` again help. |
60
+
61
+ Prefer the documented `wix …` / `npm run dev\|build\|release` forms (the scaffold rewrites `package.json` to route them through `wix`). Deploy mechanics — origin registration, retries — live in `managed/DEPLOYMENT.md`, not here.
62
+
63
+ ## 5 — Environment variables (custom vars only)
64
+
65
+ | Page | What it settles |
66
+ |---|---|
67
+ | <https://dev.wix.com/docs/go-headless/wix-managed-headless/project-development/environment-variables/manage-environment-variables.md> | **The documented mechanism.** Declare each var in the `envField` schema in `astro.config.mjs` (`context: client\|server`, `access: public\|secret`); import from **`astro:env/client`** / **`astro:env/server`**; set with **`wix env set --key=… --value=…`**, pull with **`wix env pull`** (no `--json`). **Never edit the `WIX_CLIENT_*` vars** — the CLI manages them. |
68
+ | <https://dev.wix.com/docs/go-headless/wix-managed-headless/project-development/environment-variables/about-environment-variables-in-the-cli.md> | The four var types (client/server × public/secret) — read when choosing the right `context`/`access`. |
69
+
70
+ This is for *custom* vars only. Because there's no client on managed-Astro, app code doesn't read `WIX_CLIENT_ID` at all (don't reach for the `import.meta.env.WIX_CLIENT_ID` manual-client pattern — managed-Astro has no client, so there's nothing to read it into).
71
+
72
+ ## 6 — SEO: let owners manage tags on item pages
73
+
74
+ Main pages (home, listings, about) get their SEO tags **automatically** on managed-Astro — nothing to write. **Item pages** — any parameterized detail route (`/blog/[...slug]`, a product / service / event detail, an optional category/collection route) — do **not**: they need code so the tags a site owner edits in the dashboard reach the live `<head>`. Wire this on **every managed site that renders item/detail routes** — it's what lets owners control each item's `<title>`/description/OG/canonical without touching code, and it registers the route for the sitemap + dashboard SEO editor. Skipping it leaves detail pages with a generic fallback title the owner can't fix.
75
+
76
+ | Page | What it settles |
77
+ |---|---|
78
+ | <https://dev.wix.com/docs/go-headless/wix-managed-headless/seo/add-seo-support-to-item-pages.md> | **The item-page SEO contract.** The three steps every detail route needs — export `wixMetadata` (route registration), call `loadSEOTagsServiceConfig(...)`, render `<SEO.Tags>` — plus the deps (`@wix/seo` + `@wix/essentials ≥ 1.0.10`), the `WIX_APPS` sourcing rule (reference it directly in the export), per-page-type values, and how to verify. Read it before writing any `[slug]` / `[...slug]` detail page. |
79
+
80
+ The **per-vertical values** — which `WIX_APPS.*PageMetadata` accessor + `seoTags.ItemType.*` to pass — live in each capability's `inline-recipes/how-to-code-*.md` (blog, store, bookings, events each name theirs).
81
+
82
+ ## 7 — Caveats (the gaps the docs don't mention)
83
+
84
+ The heart of the file: tribal knowledge the docs won't surface. These are **guidance the model must follow when it writes the frontend** — not things this skill writes for it.
85
+
86
+ | Caveat | What it says |
87
+ |---|---|
88
+ | **A1 — Astro 5 only** | `headless link` does **not** support Astro 6. Before linking an existing Astro project, check its Astro major; on 6 it fails. Fresh scaffolds are fine (they pin a supported Astro). |
89
+ | **A2 — `astro.config.mjs` always carries `wixPages()` + `checkOrigin: false`** | A working config must **always** include `@wix/astro-pages` (`wixPages()`) alongside `wix()`/`react()`, **and** set `security: { checkOrigin: false }`. Neither is in the docs; both are **unconditional** (no "when to add" logic). `wixPages()` injects the `/_wix/pages.json` page manifest + the `wix:astro:pages` virtual module the Wix platform consumes — omit it and `/_wix/pages.json` 404s. `checkOrigin: false` disables Astro 5's CSRF origin check, which false-positives on legitimate same-site POSTs behind Wix hosting; it's a safe no-op when there are no server POSTs. If you touch `astro.config.mjs`, keep both. |
90
+ | **A3 — Guard every SSR SDK call** | Wrap every Wix SDK call in `.astro` frontmatter in `try/catch` — an unguarded throw truncates the response mid-stream (white screen). Memoize repeated SSR probes at module scope to coalesce duplicate calls within a request. |
91
+ | **A4 — Islands reading browser-only state must be `client:only="react"`** | An island that reads browser-only state (cart badge via `sessionStorage`, availability/booking widgets) must be `client:only="react"`, not `client:load` — otherwise SSR renders a zero/empty state and hydration flashes it to the real value. |
92
+ | **A5 — No HTML comments in `.astro` frontmatter** | `.astro` frontmatter is TypeScript — use `//`, never `<!-- -->`, or the build fails. |
93
+ | **A6 — Wix media + rich text** | **Resolve `wix:image://` URIs — never hand-build the CDN URL.** SDK media fields (product/blog/CMS images) come back as internal identifiers like `wix:image://v1/<hash>/<file>#originWidth=…`, **not** ready URLs. Convert them with the SDK media module — `import { media } from '@wix/sdk'`, then `media.getScaledToFillImageUrl(uri, w, h, {})` (**returns the URL string directly — do NOT append `.url`; the 4th `options` arg is required, pass `{}`**), or `media.getImageUrl(uri).url` for the original (**that** one returns a `{ url }` object). The two shapes differ — mixing them (`getScaledToFillImageUrl(...).url`) resolves every image to `undefined`. Manually building a `static.wixstatic.com/.../v1/fit/...` URL gets the format wrong and the image **403s** (or silently fails to load). Only `wix:image://` values need this — an already-absolute `https://` URL (e.g. an Unsplash placeholder) passes straight through. Docs: <https://dev.wix.com/docs/sdk/core-modules/sdk/media>. Then **constrain** Wix image URLs (`aspect-ratio` + `object-fit: cover`) or they render at intrinsic size and overflow the layout. **Rich text:** the ban is on dumping *raw* HTML/Ricos into a text node — when you bind a rich-text field into a layout slot (a card excerpt, a `textContent` string), use its `.plain` variant. This is **not** a "render plain text" rule: a **blog post body is `richContent` (Ricos) and must render formatted** — via `@wix/ricos`, or by converting Ricos → sanitized HTML and rendering with `set:html` (SDK_HANDOFF §3/§6 require full formatted content, not flattened text). Plain `.plain` is for short bound fields; formatted Ricos is for the post body. |
94
+ | **A7 — `clientId` is off-path here** | In managed-Astro there is no client, so `appId`-as-`clientId` only matters on the self-managed / non-Astro path (see `non-astro.md`). Don't construct one here. |
95
+ | **A8 — Member auth uses the built-in routes, never an `OAuthStrategy` client** | Render account/gated UI **behind a login check resolved server-side** — in SSR frontmatter (guarded `try/catch`, A3) or a `src/pages/api/*.ts` route — and bounce anonymous visitors with `/api/auth/login?returnUrl=…` (the same shape blog comments already use). **Do not build an `OAuthStrategy` login handshake on Astro** — that's the non-Astro path and it 500s under auto-auth. Read the current member with **`@wix/members` `getCurrentMember`** (not the dev-preview `@wix/site-members`). Full contract: `inline-recipes/how-to-code-members-astro.md`. |
96
+ | **A9 — `sharp` is dev-only and never used here — pre-empt it, never build or diagnose it** | `sharp` is **not** a declared dependency: it's an *optional* transitive dep of Astro (`astro.optionalDependencies.sharp`, absent from your `package.json`) that powers only Astro's **local, build-time** image optimization (`astro:assets` / `<Image>`). This headless flow serves **remote Wix Media URLs** (`static.wixstatic.com`) through plain `<img>` — it **never** calls `<Image>`, so sharp is invoked at neither build nor runtime; it is pure dev-time dead weight here. Its postinstall can try to **build from source via node-gyp, fail, and abort the whole `npm install`, leaving `node_modules/` empty.** **Pre-empt this — don't react to it: always run `npm install --ignore-scripts`** (skips sharp's failing native build; the Wix CLI/SDK packages carry no postinstall that this breaks). **Do not** reach for **`--no-optional`** (deprecated / a silent no-op in npm 7+, so sharp still builds and aborts) or **`--omit=optional`** (sharp still resolves and builds). A missing or failed `sharp` is **expected and irrelevant** to a site that serves remote image URLs: **never** retry the install, switch node versions, add `node-addon-api`, or spend *any* time diagnosing a sharp error — one `--ignore-scripts` install, then move straight on. |
97
+
98
+ > **Seeding token (cross-link, not duplicated):** build-time seeding still mints a REST token via the Wix CLI — that token is **byte-identical on every re-mint**, so mint once and reuse. The full token mechanism lives in `managed/AUTHENTICATION.md`; don't restate it here.
@@ -0,0 +1,196 @@
1
+ ---
2
+ name: "How to Code a Blog"
3
+ description: The frontend read contract for a Blog V3 site — which @wix/blog modules to import, how to list/get posts with the mandatory RICH_CONTENT fieldset, how to resolve categories/tags/cover media, how to render Ricos rich content, and the read-public/write-authenticated comments flow. Specifies the *how* (modules + exact calls + the failure modes the docs omit); which posts to render come from the blog the site reads.
4
+ ---
5
+ **RECIPE**: How to Code a Wix Blog Frontend (Blog V3 + Ricos rich content)
6
+
7
+ A concise contract for writing the **frontend code** of a blog against a Blog V3 site: listing posts, opening a post by slug, rendering its rich content, resolving categories/tags/cover images, and (optionally) reading and submitting comments. **This recipe is the *how* (which modules, which calls, which fields), not the *what*** — which posts to show, how the page looks, and the framework are decided by the request you're fulfilling.
8
+
9
+ > **This recipe is for CODING the blog, not for seeding it.** It assumes a Blog V3 site already exists (published posts, optional categories/tags). It says nothing about creating posts — only how to read and render them from frontend code.
10
+
11
+ > **⚠️ Reading rule — always append `.md?apiView=SDK` to every doc link below.** The Wix docs render two views of the same page. The **bare / REST view shows `id`**; the **`?apiView=SDK` view shows `_id`** — and the SDK is what your frontend calls. Reading the REST view by mistake is the most common source of `undefined`-id bugs (links to `/blog/undefined`). Fetch the `.md?apiView=SDK` form directly; if a field name surprises you, you're probably reading the REST view.
12
+
13
+ ---
14
+
15
+ ## The modules and the client (read this first)
16
+
17
+ **Wix Blog app id** (a constant Astro needs for blog-post page routing, and comments need as `appId`):
18
+ `14bcded7-0066-7c35-14d7-466cb3f09103`
19
+
20
+ **⚠️ CRITICAL: blog posts are NOT CMS collections — use `@wix/blog`, never `@wix/data`.** Querying blog content through `@wix/data` reads the wrong store and returns nothing. Import only:
21
+
22
+ | Need | Package | Module |
23
+ |---|---|---|
24
+ | Posts (list, get, query by slug) | `@wix/blog` | `posts` |
25
+ | Categories (resolve `categoryIds`) | `@wix/blog` | `categories` |
26
+ | Tags (resolve `tagIds`) | `@wix/blog` | `tags` |
27
+ | Render rich content | `@wix/ricos` | `RicosViewer` + `quickStartViewerPlugins` |
28
+ | Resolve `wix:image://` cover URIs | `@wix/sdk` | `media` |
29
+ | Likes — like/unlike a post (only if the site has members) | `@wix/blog` | `likes` |
30
+ | Comments — read/submit (only if the blog has comments) | `@wix/comments` | `comments` |
31
+ | Comment/like author name/photo (only with members) | `@wix/members` | `members` |
32
+
33
+ Discover the exact current call shapes with `SearchWixSDKDocumentation` (e.g. `"blog query posts"`, `"comments queryComments createComment"`) rather than walking a module menu — the menu pages often surface only dashboard/extension pages, not the runtime query functions. The `@wix/ricos` viewer API moves between versions — **follow the blog doc to the current viewer API; don't pin a version blind.**
34
+
35
+ **Auth / client — framework split:**
36
+ - **Astro (Wix-managed):** authentication is ambient. Call `posts` / `categories` / `tags` directly from server components and backend routes (`src/pages/api/*.ts`) — **no `createClient`, no `OAuthStrategy`, no `clientId`.**
37
+ - **Non-Astro (Vite/React/Vue/static):** build one manual visitor client and reuse it:
38
+ ```js
39
+ import { createClient, OAuthStrategy } from '@wix/sdk';
40
+ import { posts, categories, tags } from '@wix/blog';
41
+
42
+ const client = createClient({
43
+ modules: { posts, categories, tags },
44
+ auth: OAuthStrategy({ clientId: /* the project's PUBLIC OAuth client id */ }),
45
+ });
46
+ ```
47
+ The `clientId` is public, not a secret.
48
+
49
+ ---
50
+
51
+ ## The blog features (build the ones the site needs)
52
+
53
+ Each section below is a **self-contained blog feature** — implement only the ones the site uses; they don't have to be built in order. The only ordering is *within* a feature (e.g. resolve `categoryIds` after you have the post).
54
+
55
+ ### Listing posts (and the `RICH_CONTENT` + `_id` rules)
56
+
57
+ Query posts with `posts.queryPosts(...)`, newest first:
58
+
59
+ ```js
60
+ const { items } = await posts
61
+ .queryPosts({ fieldsets: ["RICH_CONTENT", "URL"] })
62
+ .descending("firstPublishedDate")
63
+ .limit(20)
64
+ .find();
65
+ ```
66
+ Doc: <https://dev.wix.com/docs/api-reference/business-solutions/blog/posts/query-posts.md?apiView=SDK>
67
+
68
+ **⚠️ CRITICAL: request the `RICH_CONTENT` fieldset, or `post.richContent` is `undefined`.** `queryPosts` omits the body by default; without `fieldsets: ["RICH_CONTENT"]` the post comes back with no `richContent`, and the detail page renders blank. (Add `"URL"` to get `post.url`/`slug` for links.)
69
+
70
+ **⚠️ CRITICAL: the entity id is `_id`, NOT `id`.** The SDK normalizes every entity's id to **`_id`**; `post.id` is `undefined` in SDK code. Use `post._id` for keys and lookups, and `post.slug` for links (`/blog/${post.slug}`). (A surprising field name means you're reading the REST doc view — re-open it with `?apiView=SDK`.)
71
+
72
+ **Visibility:** only published posts are returned to a visitor token, so a missing post usually means it wasn't seeded `publish: true` — not a query bug (ties back to the seed recipe).
73
+
74
+ ### Opening a post by slug
75
+
76
+ Filter by `slug` and take the first item:
77
+
78
+ ```js
79
+ const { items } = await posts
80
+ .queryPosts({ fieldsets: ["RICH_CONTENT", "URL"] })
81
+ .eq("slug", slug)
82
+ .find();
83
+ const post = items[0];
84
+ if (!post) { /* 404 → redirect to /blog */ }
85
+ ```
86
+
87
+ **Astro page routing + SEO (Wix-managed) — `wixMetadata` is required.** A blog-post detail page (`src/pages/blog/[...slug].astro`) is a Wix **item page**: its `<title>`/description/OG/canonical come from what the owner sets in the dashboard. Wire it per the canonical guide — **[Add SEO Support to Item Pages](https://dev.wix.com/docs/go-headless/wix-managed-headless/seo/add-seo-support-to-item-pages.md)** — which covers all three steps: export `wixMetadata` (registers the route → sitemap + dashboard SEO editor), call `loadSEOTagsServiceConfig(...)`, and render `<SEO.Tags>` (from `@wix/seo`; deps + `@wix/essentials ≥ 1.0.10` are in the guide's "Before you begin"). Source `wixMetadata` from `WIX_APPS`, referenced **directly** inside the export (it's evaluated in module scope):
88
+
89
+ ```js
90
+ import { WIX_APPS } from "@wix/essentials";
91
+ import { seoTags } from "@wix/seo"; // → itemType: seoTags.ItemType.BLOG_POST
92
+
93
+ export const wixMetadata = {
94
+ appDefId: WIX_APPS.blogs.id,
95
+ pageIdentifier: WIX_APPS.blogs.postPageMetadata.pageIdentifier,
96
+ identifiers: { slug: WIX_APPS.blogs.postPageMetadata.identifiers.slug },
97
+ };
98
+ ```
99
+ Use the `[...slug]` **rest** param (not `[slug]`), and `Astro.params` directly — Wix headless projects run `output: "server"` (SSR), so there's no `getStaticPaths()`. **If you add a blog category route** (e.g. `/category/[slug]`), wire it the same way with `WIX_APPS.blogs.categoryPageMetadata` + `seoTags.ItemType.BLOG_CATEGORY`. ⚠️ Dashboard SEO *overrides* for blog **categories** may not be honored by the resolver (it can return label-derived defaults) — the route still registers and gets valid default tags, so this is a Wix-side gap, not a wiring bug.
100
+
101
+ ### Rendering the post body (Ricos rich content)
102
+
103
+ The body is **Ricos** (`post.richContent`), not HTML — **never** `set:html={post.content}` (there is no `.content`), and never `String(node)`. Render it with `@wix/ricos`:
104
+
105
+ ```tsx
106
+ // src/components/RicosViewer.tsx
107
+ import { quickStartViewerPlugins, RicosViewer } from '@wix/ricos';
108
+ import '@wix/ricos/css/all-plugins-viewer.css';
109
+
110
+ const plugins = quickStartViewerPlugins(); // module-level, once — not per render
111
+
112
+ export default function RicosContentViewer({ content }) {
113
+ if (!content) return null;
114
+ return <div className="ricos-content"><RicosViewer content={content} plugins={plugins} /></div>;
115
+ }
116
+ ```
117
+ Doc: <https://dev.wix.com/docs/sdk/business-solutions/blog/introduction.md?apiView=SDK> (follow it to the current Ricos viewer API; verify with `SearchWixSDKDocumentation "ricos viewer"`).
118
+
119
+ **⚠️ CRITICAL (Astro): render the viewer with `client:only="react"`.** `@wix/ricos` is a React component that breaks under SSR. `<RicosViewer client:only="react" content={post.richContent} />` makes it render client-side only. `@wix/ricos` accepts the camelCase `richContent` from the `@wix/blog` SDK directly — no key renaming.
120
+
121
+ **⚠️ Ricos text invisible on dark themes.** The Ricos library CSS hardcodes near-black text color on paragraphs/lists. If the site theme is dark, scope an override on the `.ricos-content` wrapper forcing `var(--color-text)` — and in Astro use `<style is:global>`, because React islands don't inherit scoped Astro styles.
122
+
123
+ For a short excerpt/card summary use `post.excerpt` (a plain string) — not the raw `richContent` nodes.
124
+
125
+ ### Resolving categories and tags
126
+
127
+ `post.categoryIds` / `post.tagIds` are id arrays — resolve each to a label:
128
+
129
+ ```js
130
+ const { category } = await categories.getCategory(id); // ENVELOPE — destructure { category }
131
+ const tag = await tags.getTag(id); // returns the BlogTag DIRECTLY — do NOT destructure
132
+ ```
133
+ Docs: <https://dev.wix.com/docs/api-reference/business-solutions/blog/category/get-category.md?apiView=SDK> · <https://dev.wix.com/docs/api-reference/business-solutions/blog/tags/get-tag.md?apiView=SDK>
134
+
135
+ **⚠️ CRITICAL: the two return shapes differ.** `categories.getCategory(id)` returns an **envelope** `{ category }` — destructure it. `tags.getTag(id)` returns the **tag object directly** — destructuring it as `{ tag }` yields `undefined`. Getting this backwards is a silent `undefined.label`.
136
+
137
+ ### Rendering the cover image
138
+
139
+ A post's cover lives at `post.media?.wixMedia?.image` and may be a **`wix:image://` identifier, not a ready URL**. Resolve it with the SDK media module:
140
+
141
+ ```js
142
+ import { media } from '@wix/sdk';
143
+ const coverUrl = post.media?.wixMedia?.image
144
+ ? media.getImageUrl(post.media.wixMedia.image).url // or media.getScaledToFillImageUrl(ref, w, h)
145
+ : undefined;
146
+ ```
147
+
148
+ **Never hand-build a `static.wixstatic.com/.../v1/fit/...` URL** — the format is easy to get wrong and the image then **403s**. Only `wix:image://` values need resolving; an already-absolute `https://` URL (e.g. an Unsplash placeholder seeded when imagery is off) goes straight into `<img src>`. Constrain Wix image URLs with `aspect-ratio` + `object-fit: cover` so they don't overflow at intrinsic size. Doc: <https://dev.wix.com/docs/sdk/core-modules/sdk/media>
149
+
150
+ ### Member features (only if the site has the members capability)
151
+
152
+ When the site has **members** (login — see `how-to-code-members-astro.md` / `-non-astro.md`), two blog features become member-native. Both follow the same **read-public / write-as-the-logged-in-member** shape as everywhere else — resolve identity at the action, never gate the whole page, and **never `auth.elevate()`** for a member acting on their own behalf.
153
+
154
+ > **⚠️ Members-only (gated) content — gate on a LIVE, queryable signal, never a hardcoded id/slug list.** If the brief gates full articles to paying members, decide "is this post gated?" from a signal **carried on the post itself** and read at request time — a `members-only` blog **category or tag**, or a boolean field on a companion CMS record — so a gated post the owner publishes later **self-classifies** with no code change. **Do NOT** gate by a hardcoded list of "premium" post slugs/ids frozen at build time: a members-only post added afterward would read as **public** (an owner edit silently lost). Combine the gate with the member check — resolve the visitor's plan/login at the action, and reveal the full body only when both the post is flagged gated *and* the member is eligible (plan eligibility is itself a live read — see `how-to-code-pricing-plans.md`).
155
+
156
+ > **⚠️ Members can LIKE and COMMENT — they CANNOT author or manage posts.** Every draft-post write/query method (`createDraftPost`, `updateDraftPost`, `publishDraftPost`, `deleteDraftPost`, `queryDraftPosts`) is **admin-only** (`applicableIdentities: [APP]`, Manage-Blog scope) — a member token is rejected. Blog authoring is a back-office capability; the seed recipe's `memberId` only *attributes* a post to a member, it doesn't grant members authoring rights (`setup-blog.md` STEP 1). Do **not** build a "write a post" / "my drafts" member surface expecting the member's own session to work. (It's only achievable by an app-mediated backend that `auth.elevate()`s to APP, creates on the member's behalf, and enforces per-member ownership itself — an authoring workflow with moderation implications, not a drop-in feature. Don't build it unless the brief explicitly asks.)
157
+
158
+ ### Likes (member-native)
159
+
160
+ Liking is a first-class member action — `likes.createLike` / `deleteLike` / `queryLikes` accept a **`MEMBER`** identity (not admin), so a logged-in member likes/unlikes a post directly.
161
+
162
+ - **Show the count + "liked by me":** `likes.queryLikes` (public read) for the per-post total; the current member's like state comes from their own likes. Post-level engagement counts are also on the post via the metrics fieldset.
163
+ - **Toggle:** on click, POST to a backend endpoint (`src/pages/api/*.ts`) that calls `likes.createLike` / `deleteLike` with the request session; if the caller isn't a member, redirect to `/api/auth/login?returnUrl=…` (same gate-on-action shape as comments). Keys off the post id (`post._id`).
164
+ - Discover shapes: `SearchWixSDKDocumentation "blog likes createLike queryLikes"`.
165
+
166
+ ### Comments — read public, write authenticated
167
+
168
+ > **⚠️ Intent-gate this feature.** Comments **hard-depend on members/login**, so build them **only when the brief explicitly asks for reader comments or discussion.** An unrequested comments feature drags in an unrequested login gate — consistent with the `CAPABILITIES.md` blog entry (comments are optional / intent-gated, not part of the baseline blog surface). Reading comments is public; **submitting / editing / deleting** needs a logged-in member — render the thread always, and resolve identity **at the action** (show a "log in to comment" prompt to anonymous visitors, not a form that bounces).
169
+
170
+ Package: `@wix/comments` (`comments`). The API keys off the post's **`referenceId`** — request the `REFERENCE_ID` fieldset when fetching the post, then `contextId = resourceId = post.referenceId`, and `appId = "14bcded7-0066-7c35-14d7-466cb3f09103"` (the Blog app id).
171
+
172
+ - **List (public, SSR) — use `listCommentsByResource`, NOT `queryComments`.** `comments.listCommentsByResource(APP_ID, { contextId, resourceId, commentSort: { order: "OLDEST_FIRST" }, cursorPaging: { limit } })` → returns `{ comments }`. **⚠️ The docs' `queryComments` example ships wrapped in `auth.elevate(comments.queryComments)` — an admin path that must NOT be used for the public/anonymous SSR read.** Reaching for `queryComments` steers you straight into that elevated example; use `listCommentsByResource` for the visitor read.
173
+ - **Comment body is Ricos, not a string.** `createComment` / `updateComment` take `content: { richContent: <ricos-doc> }` — the same `{ nodes: [{ type:"PARAGRAPH", nodes:[{ type:"TEXT", textData:{ text, decorations:[] }}]}]}` shape as post bodies. Convert the textarea string ↔ Ricos yourself (a small `plainTextToRicos` / `ricosToPlainText` helper).
174
+ - **Submit (member-gated):** POST to a backend endpoint (`src/pages/api/*.ts`) that resolves the session and calls `comments.createComment(...)`; if the caller isn't a member, redirect to `/api/auth/login?returnUrl=…` (framework-provided on managed Astro — **no `src/pages/api/auth` file needed**, `@wix/astro` emits it at build). **Not** a client island.
175
+ - **Edit / delete own comment — ownership is app-enforced.** The SDK does **not** enforce ownership server-side, so you must: fetch first (`comments.getComment(id)`), check `existing.author?.memberId === member._id`, then `comments.updateComment(id, { revision: existing.revision, content })` (**⚠️ update requires the fetched `revision`**) or `comments.deleteComment(id)`.
176
+ - **Comment count:** request the **`METRICS` fieldset** on the post fetch and read `post.metrics.comments`. Do **not** call `comments.countComments` — it needs elevation.
177
+ - **Author name/photo:** resolve `comment.author?.memberId` (and `post.memberId`) via `@wix/members`. Comment fields normalize to **`_id`** / **`_createdDate`** (same `_id` rule as posts).
178
+ - **Pagination / "load more":** `listCommentsByResource` is **cursor-paged** — pass `cursorPaging: { limit }` and follow the returned paging **cursor** for the next page; don't offset-page.
179
+ - **"Edited" indicator:** after an update, `comment.contentEdited === true` — render an "(edited)" marker.
180
+ - **Threaded replies (optional, only if the brief wants nested discussion):** a reply carries `comment.parentComment` (present *only* on replies); `comment.replyCount` is the number of replies; fetch one comment's thread with `comments.getCommentThread(commentId, …)`. For a flat thread (the common case), ignore `parentComment` and just render the `listCommentsByResource` results in `OLDEST_FIRST` order.
181
+ - **Optional extras (wire only if asked):** comment votes — `comment.voteSummary.upvoteCount` / `downvoteCount`; and marking/pinning — `comment.marked`.
182
+
183
+ > **⚠️ REST-vs-SDK permission trap.** The raw REST comments methods all report `applicableIdentities: [APP]` (admin) — but the **`@wix/comments` SDK path** resolves the **read as public** and the **write as the logged-in member**. Don't let the REST spec push you into `auth.elevate()`-ing the read or the member write — that's wrong for the visitor thread. Only the genuine **moderation** calls (`hideComment`, `moderateDraftContent`, `countComments`, `markComment`, publish/bulk-*) need elevation, and those are back-office, not part of the visitor-facing feature.
184
+
185
+ ---
186
+
187
+ ## Conclusion
188
+ A correct Blog V3 frontend:
189
+ - imports **`posts` / `categories` / `tags` from `@wix/blog`** (+ `@wix/ricos`, `media`) — **never `@wix/data`** for blog content;
190
+ - queries with the **`RICH_CONTENT` fieldset** (else `richContent` is `undefined`) and uses **`post._id`** (never `post.id`) and `post.slug` for links;
191
+ - renders the body with **`@wix/ricos` `RicosViewer`** (`client:only="react"` in Astro, `.ricos-content` color override for dark themes) — never `set:html`, never raw nodes;
192
+ - destructures **`categories.getCategory` as `{ category }`** but takes **`tags.getTag` directly** (not `{ tag }`);
193
+ - resolves **`wix:image://` covers via the SDK `media` module** — never a hand-built CDN URL;
194
+ - exports **`wixMetadata`** on the Astro `[...slug]` detail page;
195
+ - if comments exist, reads them **public/SSR** and submits via an **authenticated API endpoint** keyed on **`post.referenceId`** + the Blog `appId`;
196
+ - if the site has **members**, wires **likes** (`@wix/blog` `likes`, `MEMBER`-scoped) and comments as member-native, gate-on-action features — but **never** a member post-authoring surface (all draft-post methods are APP-only; a member token is rejected).