@wix/agent-skills 1.0.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 (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/package.json +29 -0
  4. package/skills/wix-app/SKILL.md +344 -0
  5. package/skills/wix-app/references/APP_IDENTIFIERS.md +35 -0
  6. package/skills/wix-app/references/APP_MARKET_REVIEW.md +311 -0
  7. package/skills/wix-app/references/APP_VALIDATION.md +171 -0
  8. package/skills/wix-app/references/BACKEND_API.md +233 -0
  9. package/skills/wix-app/references/BACKEND_EVENT.md +116 -0
  10. package/skills/wix-app/references/CODE_QUALITY.md +33 -0
  11. package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +587 -0
  12. package/skills/wix-app/references/DASHBOARD_MENU_PLUGIN.md +157 -0
  13. package/skills/wix-app/references/DASHBOARD_MODAL.md +283 -0
  14. package/skills/wix-app/references/DASHBOARD_PAGE.md +403 -0
  15. package/skills/wix-app/references/DASHBOARD_PLUGIN.md +205 -0
  16. package/skills/wix-app/references/DATA_COLLECTION.md +451 -0
  17. package/skills/wix-app/references/DOCUMENTATION.md +42 -0
  18. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +65 -0
  19. package/skills/wix-app/references/EMBEDDED_SCRIPT.md +468 -0
  20. package/skills/wix-app/references/EXTENSION_REGISTRATION.md +96 -0
  21. package/skills/wix-app/references/SERVICE_PLUGIN.md +235 -0
  22. package/skills/wix-app/references/SITE_PLUGIN.md +436 -0
  23. package/skills/wix-app/references/STORES_VERSIONING.md +334 -0
  24. package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +84 -0
  25. package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +345 -0
  26. package/skills/wix-app/references/dashboard-menu-plugin/blog-slots.md +71 -0
  27. package/skills/wix-app/references/dashboard-menu-plugin/bookings-slots.md +58 -0
  28. package/skills/wix-app/references/dashboard-menu-plugin/crm-slots.md +8 -0
  29. package/skills/wix-app/references/dashboard-menu-plugin/ecommerce-slots.md +17 -0
  30. package/skills/wix-app/references/dashboard-menu-plugin/events-slots.md +29 -0
  31. package/skills/wix-app/references/dashboard-menu-plugin/restaurants-slots.md +27 -0
  32. package/skills/wix-app/references/dashboard-menu-plugin/stores-slots.md +35 -0
  33. package/skills/wix-app/references/dashboard-page/API_SPEC.md +138 -0
  34. package/skills/wix-app/references/dashboard-page/DASHBOARD_API.md +573 -0
  35. package/skills/wix-app/references/dashboard-page/DYNAMIC_PARAMETERS.md +269 -0
  36. package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +164 -0
  37. package/skills/wix-app/references/dashboard-plugin/SLOTS.md +294 -0
  38. package/skills/wix-app/references/data-collection/WIX_DATA.md +270 -0
  39. package/skills/wix-app/references/data-collection/extension-template.ts +107 -0
  40. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +138 -0
  41. package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +454 -0
  42. package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +165 -0
  43. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +576 -0
  44. package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +170 -0
  45. package/skills/wix-app/references/editor-react-component/EDIT-FLOW.md +6 -0
  46. package/skills/wix-app/references/editor-react-component/PARTS.md +25 -0
  47. package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +203 -0
  48. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +167 -0
  49. package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +137 -0
  50. package/skills/wix-app/references/service-plugin/ADDITIONAL-FEES.md +112 -0
  51. package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +118 -0
  52. package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +87 -0
  53. package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +86 -0
  54. package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +135 -0
  55. package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +79 -0
  56. package/skills/wix-app/references/service-plugin/VALIDATIONS.md +68 -0
  57. package/skills/wix-app/references/site-plugin/EXAMPLES.md +311 -0
  58. package/skills/wix-app/references/site-plugin/SLOTS.md +263 -0
  59. package/skills/wix-design-system/SKILL.md +129 -0
  60. package/skills/wix-design-system/references/file-structure.md +56 -0
  61. package/skills/wix-design-system/scripts/wds.cjs +531 -0
  62. package/skills/wix-headless/SKILL.md +418 -0
  63. package/skills/wix-headless/references/DISCOVERY.md +332 -0
  64. package/skills/wix-headless/references/ORCHESTRATION.md +269 -0
  65. package/skills/wix-headless/references/SETUP.md +154 -0
  66. package/skills/wix-headless/references/blog/BLOG_CONTENT.md +152 -0
  67. package/skills/wix-headless/references/blog/BLOG_PAGES.md +299 -0
  68. package/skills/wix-headless/references/blog/BLOG_SETUP.md +218 -0
  69. package/skills/wix-headless/references/blog/INSTRUCTIONS.md +32 -0
  70. package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +373 -0
  71. package/skills/wix-headless/references/cms/FAQ_KNOWLEDGE_BASE.md +229 -0
  72. package/skills/wix-headless/references/cms/INSTRUCTIONS.md +40 -0
  73. package/skills/wix-headless/references/cms/PORTFOLIO.md +454 -0
  74. package/skills/wix-headless/references/cms/RESOURCE_LIBRARY.md +356 -0
  75. package/skills/wix-headless/references/cms/TEAM_DIRECTORY.md +299 -0
  76. package/skills/wix-headless/references/commands/install-app.md +42 -0
  77. package/skills/wix-headless/references/commands/known-apps.json +5 -0
  78. package/skills/wix-headless/references/commands/mcp-bootstrap.md +28 -0
  79. package/skills/wix-headless/references/designer/INSTRUCTIONS.md +828 -0
  80. package/skills/wix-headless/references/ecom/CART_PAGES.md +120 -0
  81. package/skills/wix-headless/references/ecom/CART_WIRING.md +103 -0
  82. package/skills/wix-headless/references/ecom/COMPONENTS_CSS.md +132 -0
  83. package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +59 -0
  84. package/skills/wix-headless/references/forms/CONTACT_FORM.md +477 -0
  85. package/skills/wix-headless/references/forms/INSTRUCTIONS.md +43 -0
  86. package/skills/wix-headless/references/gift-cards/COMPONENTS.md +119 -0
  87. package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +51 -0
  88. package/skills/wix-headless/references/gift-cards/PAGES.md +129 -0
  89. package/skills/wix-headless/references/images/INSTRUCTIONS.md +359 -0
  90. package/skills/wix-headless/references/shared/BUILD_NOISE.md +8 -0
  91. package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +185 -0
  92. package/skills/wix-headless/references/shared/IMPLEMENTER.md +155 -0
  93. package/skills/wix-headless/references/shared/MCP_PREFIX.md +105 -0
  94. package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +97 -0
  95. package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +423 -0
  96. package/skills/wix-headless/references/shared/STYLING.md +117 -0
  97. package/skills/wix-headless/references/stores/BACK_IN_STOCK.md +178 -0
  98. package/skills/wix-headless/references/stores/CATEGORY_PAGES.md +86 -0
  99. package/skills/wix-headless/references/stores/COMPONENTS_CSS.md +129 -0
  100. package/skills/wix-headless/references/stores/HOME_AND_NAV.md +227 -0
  101. package/skills/wix-headless/references/stores/INSTRUCTIONS.md +96 -0
  102. package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +249 -0
  103. package/skills/wix-headless/references/stores/PRODUCT_PAGES.md +213 -0
  104. package/skills/wix-headless/references/stores/SHARED_WIRING.md +164 -0
  105. package/skills/wix-headless/references/verticals/_schema.json +160 -0
  106. package/skills/wix-headless/references/verticals/_schema.md +185 -0
  107. package/skills/wix-headless/references/verticals/blog.md +125 -0
  108. package/skills/wix-headless/references/verticals/cms.md +121 -0
  109. package/skills/wix-headless/references/verticals/ecom.md +96 -0
  110. package/skills/wix-headless/references/verticals/forms.md +106 -0
  111. package/skills/wix-headless/references/verticals/gift-cards.md +121 -0
  112. package/skills/wix-headless/references/verticals/stores.md +167 -0
  113. package/skills/wix-headless/scripts/check-manifest.mjs +198 -0
  114. package/skills/wix-headless/scripts/copy-utility-templates.mjs +153 -0
  115. package/skills/wix-headless/scripts/emit-design-tokens.mjs +77 -0
  116. package/skills/wix-headless/scripts/finalize-run-json.mjs +141 -0
  117. package/skills/wix-headless/scripts/init-site-json.mjs +63 -0
  118. package/skills/wix-headless/scripts/patch-decorative-slots.mjs +124 -0
  119. package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +190 -0
  120. package/skills/wix-headless/scripts/preview.sh +45 -0
  121. package/skills/wix-headless/scripts/release.sh +73 -0
  122. package/skills/wix-headless/scripts/scaffold.sh +53 -0
  123. package/skills/wix-headless/scripts/seed-utilities.sh +55 -0
  124. package/skills/wix-headless/shared-utilities/analytics.ts +40 -0
  125. package/skills/wix-headless/shared-utilities/ricos.ts +179 -0
  126. package/skills/wix-headless/shared-utilities/wix-image.ts +72 -0
  127. package/skills/wix-headless/templates/ecom/CartBadge.tsx +84 -0
  128. package/skills/wix-headless/templates/ecom/CartView.tsx +543 -0
  129. package/skills/wix-headless/templates/ecom/cart.astro +13 -0
  130. package/skills/wix-headless/templates/ecom/components-ecom.css +215 -0
  131. package/skills/wix-headless/templates/ecom/discounts.ts +71 -0
  132. package/skills/wix-headless/templates/ecom/thank-you.astro +24 -0
  133. package/skills/wix-headless/templates/gift-cards/GiftCardPurchase.tsx +172 -0
  134. package/skills/wix-headless/templates/gift-cards/_home-teaser-snippet.astro +42 -0
  135. package/skills/wix-headless/templates/gift-cards/_nav-snippet.astro +11 -0
  136. package/skills/wix-headless/templates/gift-cards/components-gift-cards.css +219 -0
  137. package/skills/wix-headless/templates/gift-cards/gift-cards.astro +51 -0
  138. package/skills/wix-headless/templates/gift-cards/gift-cards.ts +75 -0
  139. package/skills/wix-headless/templates/stores/AddToCartButton.tsx +77 -0
  140. package/skills/wix-headless/templates/stores/BackInStockForm.tsx +176 -0
  141. package/skills/wix-headless/templates/stores/CategoryRail.astro +69 -0
  142. package/skills/wix-headless/templates/stores/ProductCard.astro +79 -0
  143. package/skills/wix-headless/templates/stores/ProductPurchase.tsx +397 -0
  144. package/skills/wix-headless/templates/stores/SeoTags.astro +21 -0
  145. package/skills/wix-headless/templates/stores/back-in-stock.ts +67 -0
  146. package/skills/wix-headless/templates/stores/categories.ts +155 -0
  147. package/skills/wix-headless/templates/stores/category/[slug].astro +130 -0
  148. package/skills/wix-headless/templates/stores/components-stores.css +295 -0
  149. package/skills/wix-headless/templates/stores/products/[slug].astro +128 -0
  150. package/skills/wix-headless/templates/stores/products/index.astro +101 -0
  151. package/skills/wix-manage/SKILL.md +280 -0
  152. package/skills/wix-manage/references/app-installation/install-wix-apps.md +155 -0
  153. package/skills/wix-manage/references/app-installation/list-installed-apps.md +124 -0
  154. package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +226 -0
  155. package/skills/wix-manage/references/bookings/booking-service-policy-setup.md +95 -0
  156. package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +416 -0
  157. package/skills/wix-manage/references/bookings/bookings-staff-setup.md +255 -0
  158. package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +462 -0
  159. package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +278 -0
  160. package/skills/wix-manage/references/bookings/external-calendar-integration.md +258 -0
  161. package/skills/wix-manage/references/bookings/multi-resource-service-creation.md +231 -0
  162. package/skills/wix-manage/references/calendar/configure-default-business-hours.md +226 -0
  163. package/skills/wix-manage/references/cms/cms-data-items-crud.md +422 -0
  164. package/skills/wix-manage/references/cms/cms-data-operations-extended.md +263 -0
  165. package/skills/wix-manage/references/cms/cms-ecommerce-catalog-integration.md +136 -0
  166. package/skills/wix-manage/references/cms/cms-references-and-relationships.md +160 -0
  167. package/skills/wix-manage/references/cms/cms-schema-management.md +143 -0
  168. package/skills/wix-manage/references/contacts/bulk-delete-contacts.md +73 -0
  169. package/skills/wix-manage/references/contacts/bulk-label-and-unlabel-contacts.md +67 -0
  170. package/skills/wix-manage/references/domains/domain-search-and-purchase.md +434 -0
  171. package/skills/wix-manage/references/ecommerce/api-recommendation-tracking.md +420 -0
  172. package/skills/wix-manage/references/ecommerce/flow-add-free-shipping.md +267 -0
  173. package/skills/wix-manage/references/ecommerce/flow-bundle-and-save.md +290 -0
  174. package/skills/wix-manage/references/ecommerce/flow-fix-coverage-gaps.md +300 -0
  175. package/skills/wix-manage/references/ecommerce/flow-optimize-shipping-rates.md +364 -0
  176. package/skills/wix-manage/references/ecommerce/flow-seasonal-promotion.md +315 -0
  177. package/skills/wix-manage/references/ecommerce/flow-stock-mover.md +308 -0
  178. package/skills/wix-manage/references/ecommerce/flow-upsell-boost.md +271 -0
  179. package/skills/wix-manage/references/ecommerce/goal-clear-inventory.md +118 -0
  180. package/skills/wix-manage/references/ecommerce/goal-drive-cross-sells.md +122 -0
  181. package/skills/wix-manage/references/ecommerce/goal-increase-aov.md +132 -0
  182. package/skills/wix-manage/references/ecommerce/goal-reduce-cart-abandonment.md +148 -0
  183. package/skills/wix-manage/references/ecommerce/goal-seasonal-revenue.md +146 -0
  184. package/skills/wix-manage/references/ecommerce/guardrail-discount-conflicts.md +118 -0
  185. package/skills/wix-manage/references/ecommerce/guardrail-margin-protection.md +88 -0
  186. package/skills/wix-manage/references/ecommerce/guardrail-rate-pricing-sanity.md +108 -0
  187. package/skills/wix-manage/references/ecommerce/guardrail-shipping-health.md +124 -0
  188. package/skills/wix-manage/references/ecommerce/recipe-apply-shipping-recommendations.md +299 -0
  189. package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +582 -0
  190. package/skills/wix-manage/references/ecommerce/setup-coupons.md +338 -0
  191. package/skills/wix-manage/references/ecommerce/setup-discount-rules.md +444 -0
  192. package/skills/wix-manage/references/ecommerce/setup-shipping-rates.md +86 -0
  193. package/skills/wix-manage/references/ecommerce/setup-shipping-regions.md +56 -0
  194. package/skills/wix-manage/references/ecommerce/setup-store-pickup-location.md +209 -0
  195. package/skills/wix-manage/references/ecommerce/skill-graph.md +139 -0
  196. package/skills/wix-manage/references/ecommerce/troubleshoot-checkout-delivery-dropoff.md +124 -0
  197. package/skills/wix-manage/references/ecommerce/troubleshoot-discount-not-applying.md +95 -0
  198. package/skills/wix-manage/references/events/list-events.md +203 -0
  199. package/skills/wix-manage/references/forms/create-form.md +260 -0
  200. package/skills/wix-manage/references/get-paid/create-payment-links.md +212 -0
  201. package/skills/wix-manage/references/get-paid/how-to-setup-wix-payments.md +57 -0
  202. package/skills/wix-manage/references/get-paid/payment-links-for-bookings.md +101 -0
  203. package/skills/wix-manage/references/media/upload-media-to-wix.md +216 -0
  204. package/skills/wix-manage/references/pricing-plans/create-and-update-pricing-plans.md +77 -0
  205. package/skills/wix-manage/references/pricing-plans/pricing-plans-bookings-integration.md +166 -0
  206. package/skills/wix-manage/references/restaurants/wix-restaurants-setup.md +336 -0
  207. package/skills/wix-manage/references/rich-content/ricos-converter-service.md +295 -0
  208. package/skills/wix-manage/references/site-properties/change-payment-currency-site-properties.md +59 -0
  209. package/skills/wix-manage/references/sites/create-site-from-template.md +183 -0
  210. package/skills/wix-manage/references/sites/query-sites.md +125 -0
  211. package/skills/wix-manage/references/stores/add-store-pages-to-site.md +57 -0
  212. package/skills/wix-manage/references/stores/bulk-create-products-with-options.md +1041 -0
  213. package/skills/wix-manage/references/stores/create-product-catalog-v1.md +125 -0
  214. package/skills/wix-manage/references/stores/create-product-from-image.md +824 -0
  215. package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +566 -0
  216. package/skills/wix-manage/references/stores/find-products-query-and-search-catalog-v3.md +194 -0
  217. package/skills/wix-manage/references/stores/query-products-catalog-v1.md +80 -0
  218. package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +99 -0
  219. package/skills/wix-manage/references/stores/update-product-pre-order.md +213 -0
  220. package/skills/wix-manage/references/stores/update-product-with-options.md +318 -0
@@ -0,0 +1,154 @@
1
+ # Setup
2
+
3
+ Runs once per session, immediately after plan approval. Establishes MCP connectivity, installs apps, pulls env, kicks off npm install in background, writes memory, creates the user-facing roadmap.
4
+
5
+ Target: **~15 seconds on the critical path** (everything after the MCP prefix discovery in Step 0 runs as a single concurrent batch).
6
+
7
+ ---
8
+
9
+ ## Step 0 — MCP Prefix Discovery + Schema Bootstrap (first time only)
10
+
11
+ Runs once per session, before any MCP call. Separate from the Setup step because it requires a sequential **discover prefix → verify connectivity → bootstrap schemas** chain.
12
+
13
+ 1. **Discover the MCP prefix.** Wix MCP tool names take the form `<prefix>WixREADME`. Use whatever tool-discovery primitive your runtime provides to look up `WixREADME` and strip the trailing suffix from the returned tool name — the remainder (ending in `wix-mcp-remote__` or similar) is the **MCP prefix**.
14
+ 2. Call `<prefix>WixREADME` once to verify connectivity.
15
+ 3. If discovery returns no match or the verify call fails → stop and tell the user: *"Wix MCP tools are not available in this session. Please ensure the Wix MCP server is connected (or that the Wix plugin is enabled), then restart your client."*
16
+ 4. **Pre-load Wix MCP tool schemas** — read `<SKILL_ROOT>/references/commands/mcp-bootstrap.md` and follow its single `ToolSearch` invocation. Loads every Wix MCP tool schema the build will use (CallWixSiteAPI, SearchWixRESTDocumentation, ReadFullDocsArticle, ReadFullDocsMethodSchema, SearchWixCLIDocumentation, SearchWixSDKDocumentation, SearchWixHeadlessDocumentation, SearchWixWDSDocumentation, SearchBuildAppsDocumentation, BrowseWixRESTDocsMenu).
17
+ 5. Hold the prefix for the whole session. Pass it into **every** subagent prompt as:
18
+ ```
19
+ MCP tool prefix: <prefix>
20
+ Use this prefix for every Wix MCP call. Example: <prefix>CallWixSiteAPI, <prefix>WixREADME.
21
+ ```
22
+
23
+ See `references/shared/MCP_PREFIX.md` for the tool-not-found recovery procedure that subagents use if the prefix somehow fails downstream.
24
+
25
+ > **Why the MCP bootstrap is mandatory.** Without it, the first `CallWixSiteAPI` emits `body` as a JSON string (because the schema isn't loaded) and returns `Expected object, received string`. Pinning the schema-load list in `references/commands/mcp-bootstrap.md` and reading it as a discrete step makes the operation impossible to skim past — the orchestrator can skip a footnote; it can't skip a numbered step that resolves to a single concrete tool call.
26
+
27
+ ---
28
+
29
+ ## Setup Dispatch — one concurrent batch
30
+
31
+ > **BATCHING — read this twice before proceeding.**
32
+ >
33
+ > Launch every operation below as a single concurrent batch. No narration, no *"Now setting up:"*, no transition text between dispatches.
34
+ >
35
+ > Any text adjacent to a dispatch closes the batch and forces remaining operations into separate turns. An earlier run lost 13s to roadmap-tracker calls splitting across 13 turns; an earlier run lost ~50 minutes to an npm install recovery gate. Both are eliminated by strict single-batch dispatch here.
36
+
37
+ ### Contents of the setup dispatch
38
+
39
+ The skill assembles this dispatch dynamically from the loaded vertical packs. The items below list what to emit.
40
+
41
+ #### 1. Verify scaffold completed
42
+
43
+ **Before the setup dispatch:** read `<project>/wix.config.json` to confirm the background scaffold from Discovery Step 1 finished. If not, wait for the background scaffold to finish. On scaffold failure, retry the inline `npm create @wix/new` call once (same shell command from DISCOVERY.md Step 1); surface the error if it still fails. Recovery ladder is documented in DISCOVERY.md § "Strict-then-recover" — auth, invalid template, etc.
44
+
45
+ Once `wix.config.json` exists, extract `siteId` (value of the `siteId` field — this is the businessId for all MCP calls in the session).
46
+
47
+ `cd` into the project directory so all subsequent file operations and shell commands are relative to it.
48
+
49
+ #### 2. The dispatch itself (one concurrent batch)
50
+
51
+ **MCP app installs** — one `<prefix>CallWixSiteAPI` per app in the union of loaded packs' `apps[*]`. Example for an ecommerce run (stores pack contributes one app; cms pack contributes none):
52
+
53
+ ```
54
+ <prefix>CallWixSiteAPI(
55
+ siteId: "<siteId>",
56
+ reason: "Install Wix Stores app for <brand>",
57
+ sourceDocUrl: "https://dev.wix.com/docs/picasso/wix-ai-docs/recipes-v2/manage/platform/recipe-install-wix-apps",
58
+ method: "POST",
59
+ url: "https://www.wixapis.com/apps-installer-service/v1/app-instance/install",
60
+ body: {
61
+ tenant: { tenantType: "SITE", id: "<siteId>" },
62
+ appInstance: { appDefId: "<pack.apps[0].appDefId>", enabled: true }
63
+ }
64
+ )
65
+ ```
66
+
67
+ > The `CallWixSiteAPI` schema was already loaded by the Step 0 MCP bootstrap, so `body` is correctly typed as a JSON object on the first call. See `references/shared/MCP_PREFIX.md` § "CallWixSiteAPI call conventions".
68
+
69
+ A 200 response with `"enabled": true` confirms success.
70
+
71
+ **Packs with `apps: []` (e.g. `cms`)** — record a phase entry in `run.json` anyway: `{phase: "app-install-<pack>", status: "skipped", notes: "Bundled with Wix platform; no install required"}`. Without an explicit skipped entry, `run.json` reads as a silent omission ("did the CMS install run? was it skipped? did it fail?"); the explicit entry makes observability unambiguous.
72
+
73
+ **Namespace propagation:** After app install, the app's API namespace may take up to 30 seconds to register. If a downstream MCP call fails with `UNSUPPORTED_FORM_NAMESPACE`, wait 10 seconds and retry up to 3 times. Phase 1 Seeders handle this retry themselves.
74
+
75
+ **Shell: `npx @wix/cli env pull`** (foreground, ~5s). Writes `WIX_CLIENT_ID` to `.env.local`. Idempotent. Skipping this historically caused `Missing environment variable WIX_CLIENT_ID` build failures.
76
+
77
+ **Background shell: `npm install ...`**:
78
+
79
+ The package list is the union of:
80
+ - Always: `@wix/sdk tailwindcss @tailwindcss/vite`
81
+ - Per loaded pack: each pack's `packages` array
82
+
83
+ > **Do not add any package beyond this set.** If a pack feels like it should have its own SDK (`@wix/<pack-name>`), confirm by reading its `packages:` array. Passive packs (gift-cards) intentionally declare nothing because they're runtime-detected via REST. There is no `@wix/gift-cards` SDK on npm — adding it on a hunch fails with `npm 404`. Same logic for any other pack: the union above is the install list. Period.
84
+
85
+ Flags: `--no-fund --no-audit --legacy-peer-deps`. `--legacy-peer-deps` is mandatory (Wix SDK transitive peer conflicts). `--no-fund --no-audit` prevent interactive prompts that hang agent sessions.
86
+
87
+ Because scaffold runs with `--skip-install`, delete the stale lockfile before installing: `rm -f package-lock.json`.
88
+
89
+ Example combined command (ecommerce run):
90
+ ```bash
91
+ rm -f package-lock.json && npm install --no-fund --no-audit --legacy-peer-deps \
92
+ @wix/sdk tailwindcss @tailwindcss/vite \
93
+ @wix/stores @wix/ecom @wix/redirects @wix/site \
94
+ @wix/data @wix/essentials
95
+ ```
96
+
97
+ Capture the background process's handle (whatever your runtime uses to wait on a long-running shell) for later wait in Step 8 (Build & Preview).
98
+
99
+ **Memory writes** — two writes:
100
+ 1. `MEMORY.md` index entry (one line)
101
+ 2. `project`-type memory file with brand, vertical(s), apps, pages, project path, phase: `scaffolding`
102
+
103
+ **User-facing roadmap × N** — target 6–8 entries mapped to phase boundaries:
104
+
105
+ | Entry | Marks completed |
106
+ |------|-----------------|
107
+ | Scaffold project | Immediately on creation (already done in Discovery) |
108
+ | Install apps | Immediately on creation (this dispatch) |
109
+ | Seed data | After Phase 1 Seed returns (Step 6) |
110
+ | Design site | After Phase 2 Design System returns (Step 4) |
111
+ | Generate images | After image subagent returns (may finish later than critical path) |
112
+ | Wire features | After Phase 3 Components + Phase 4 Pages return (Step 7/8) |
113
+ | Install dependencies | After npm install background shell completes (Step 8) |
114
+ | Build and preview | After Step 8 |
115
+
116
+ > **No ampersands in roadmap titles.** Some progress trackers HTML-escape input — `"Build & preview"` renders as literal `Build &amp; preview`. Spell out "and" (or restructure) to avoid `&`. Same for `<`, `>`, `"` and other HTML-meaningful characters.
117
+
118
+ > **Avoid the 13-entry sprawl.** Historical runs used one entry per phase-per-feature ("Design page — Home", "Seed stores", "Wire CMS", etc.). Collapse to the phase-boundary list above. Users care about milestones, not sub-phases.
119
+
120
+ **Shell: `mkdir -p .wix`** — minimal. No `.wix/logs/`.
121
+
122
+ ### Batching verification
123
+
124
+ After the dispatch, the run log should show ~8–12 operations dispatched as one concurrent batch (varies by pack count). If they spread across multiple turns, the batching guidance failed and the skill needs to be tightened.
125
+
126
+ ---
127
+
128
+ ## npm install recovery
129
+
130
+ If the background npm install from the Setup dispatch fails or hangs:
131
+
132
+ 1. **Foreground retry with 90-second timeout:**
133
+ ```bash
134
+ npm install --no-fund --no-audit --legacy-peer-deps <packages>
135
+ ```
136
+
137
+ 2. **If still hanging, retry with `--prefer-offline`:**
138
+ ```bash
139
+ npm install --prefer-offline --no-fund --no-audit --legacy-peer-deps <packages>
140
+ ```
141
+
142
+ 3. **If still hanging, clear the cache:**
143
+ ```bash
144
+ npm cache clean --force
145
+ npm install --no-fund --no-audit --legacy-peer-deps <packages>
146
+ ```
147
+
148
+ 4. **Last resort:** tell the user: *"npm install is hanging. Please run `npm install --legacy-peer-deps` manually in your terminal, then let me know when it's done."*
149
+
150
+ ---
151
+
152
+ ## After the Setup Dispatch
153
+
154
+ Proceed immediately to **Step 3 — Phase 1 Seed + Phase 2 Design System + Image Phase 1** — see `ORCHESTRATION.md`. Do not wait for the background npm install; that's waited on in Step 8.
@@ -0,0 +1,152 @@
1
+ # Recipe: Seed Initial Blog Posts via MCP
2
+
3
+ Create 3 on-brand blog posts so the blog has real content on first preview.
4
+
5
+ > **Critical Rules — Read Before Starting**
6
+ > 1. **Seed content is required** — a blog with zero posts on first preview is a build failure. Do not skip this section.
7
+ > 2. **Re-publish after PATCH** — updating a published post sets `hasUnpublishedChanges: true`. Call `publish` again or visitors see the old version.
8
+ > 3. **Use `@wix/blog`, not `@wix/data`** — blog posts are NOT CMS collections.
9
+ > 4. **`RICH_CONTENT` fieldset required** — without it, `post.richContent` is undefined and rendering fails.
10
+
11
+ > **Required in the Seed phase.** When dispatched with `Scope: seed`, MCP tools and discovery context are guaranteed available. Always execute this section — do not skip. A blog with zero posts on first preview is a build failure.
12
+ >
13
+ > **Skip only for standalone invocations** where the Blog skill is invoked directly AND `mcp__wix-mcp-remote__CallWixSiteAPI` is genuinely unavailable. In that case, the user can create posts manually in the Wix dashboard.
14
+
15
+ ## Step 0: Ensure Blog App Is Installed
16
+
17
+ Before querying blog data, verify the Blog app is installed:
18
+
19
+ 1. **Probe** — `CallWixSiteAPI: POST /blog/v3/posts/query` with body `{ "query": { "paging": { "limit": 1 } } }`
20
+ 2. **If the API returns a "REQUIRED_APP_NOT_INSTALLED" error** → install the Wix Blog app:
21
+ ```
22
+ CallWixSiteAPI: POST https://www.wixapis.com/apps-installer-service/v1/app-instance/install
23
+ body: {
24
+ "tenant": { "tenantType": "SITE", "id": "<siteId>" },
25
+ "appInstance": { "appDefId": "14bcded7-0066-7c35-14d7-466cb3f09103", "enabled": true }
26
+ }
27
+ ```
28
+ > Translate this prose-HTTP form into the full `CallWixSiteAPI` tool-call shape — include `siteId`, `reason`, `sourceDocUrl` wrapper fields and pass `body` as a real object (NOT a stringified JSON). See `../../shared/MCP_PREFIX.md` § "CallWixSiteAPI call conventions".
29
+
30
+ Then retry the probe query to confirm installation succeeded.
31
+ 3. **If the probe succeeds** → proceed to Step 1.
32
+
33
+ ---
34
+
35
+ ## Step 1: Get Member ID
36
+
37
+ Blog posts require a `memberId` (the post author). Fetch the first site member:
38
+
39
+ ```
40
+ CallWixSiteAPI: GET /members/v1/members
41
+ ```
42
+
43
+ Extract the first member's `_id` from the response. This will be used as the author for all posts.
44
+
45
+ ## Step 2: Design 3 On-Brand Blog Posts
46
+
47
+ No API call — use discovery context (business type, brand name, tone, industry) to plan 3 posts:
48
+
49
+ - Titles, summaries, and rich content appropriate for the business
50
+ - Content should demonstrate different Ricos node types (paragraphs, headings, code blocks, lists, blockquotes)
51
+ - Posts should feel like real content a reader would engage with, not placeholder text
52
+
53
+ **Post design guidelines by business type:**
54
+
55
+ | Business Type | Post 1 | Post 2 | Post 3 |
56
+ |--------------|--------|--------|--------|
57
+ | AI / tech blog | Architecture deep-dive | Practical comparison (X vs Y) | Lessons learned / field report |
58
+ | Skincare / beauty | Ingredient science spotlight | Routine guide (morning/evening) | Myth-busting or FAQ |
59
+ | Food / restaurant | Behind the recipe | Seasonal menu spotlight | Sourcing / farm-to-table story |
60
+ | Fitness / wellness | Training methodology breakdown | Nutrition or recovery guide | Client transformation story |
61
+ | Fashion / retail | Trend analysis | Styling guide | Behind the brand / process |
62
+ | General business | Industry insight | How-to guide | Company news / milestone |
63
+
64
+ Adapt titles, tone, and content to match the brand's voice and style.
65
+
66
+ ## Step 3: Create Posts
67
+
68
+ For each post, call `POST /blog/v3/draft-posts` with `publish: true` to create and immediately publish.
69
+
70
+ > Do not include the `media` field — cover images are handled separately by the image agent after post creation.
71
+
72
+ ```
73
+ CallWixSiteAPI: POST /blog/v3/draft-posts
74
+ body: {
75
+ "draftPost": {
76
+ "title": "<Post Title>",
77
+ "memberId": "<member-id-from-step-1>",
78
+ "richContent": {
79
+ "nodes": [
80
+ {
81
+ "type": "HEADING",
82
+ "id": "<unique-id>",
83
+ "nodes": [
84
+ { "type": "TEXT", "id": "", "nodes": [], "textData": { "text": "Section Heading", "decorations": [] } }
85
+ ],
86
+ "headingData": { "level": 2 }
87
+ },
88
+ {
89
+ "type": "PARAGRAPH",
90
+ "id": "<unique-id>",
91
+ "nodes": [
92
+ { "type": "TEXT", "id": "", "nodes": [], "textData": { "text": "Paragraph content here.", "decorations": [] } }
93
+ ],
94
+ "paragraphData": {}
95
+ }
96
+ ]
97
+ }
98
+ },
99
+ "publish": true
100
+ }
101
+ ```
102
+
103
+ ### Ricos JSON Node Reference
104
+
105
+ Use these node types to build rich, varied content:
106
+
107
+ | Node Type | Structure | Use For |
108
+ |-----------|-----------|---------|
109
+ | `PARAGRAPH` | `{ type: "PARAGRAPH", id, nodes: [TEXT], paragraphData: {} }` | Body text |
110
+ | `HEADING` | `{ type: "HEADING", id, nodes: [TEXT], headingData: { level: 2 } }` | Section headers (level 2–4) |
111
+ | `CODE_BLOCK` | `{ type: "CODE_BLOCK", id, nodes: [TEXT], codeBlockData: { language: "javascript" } }` | Code snippets |
112
+ | `BULLETED_LIST` | `{ type: "BULLETED_LIST", id, nodes: [LIST_ITEM] }` | Unordered lists |
113
+ | `LIST_ITEM` | `{ type: "LIST_ITEM", id, nodes: [PARAGRAPH] }` | Items inside BULLETED_LIST |
114
+ | `BLOCKQUOTE` | `{ type: "BLOCKQUOTE", id, nodes: [PARAGRAPH] }` | Pull quotes, callouts |
115
+ | `TEXT` | `{ type: "TEXT", id: "", nodes: [], textData: { text: "...", decorations: [] } }` | Inline text (leaf node inside paragraphs, headings, etc.) |
116
+
117
+ **Tips:**
118
+ - Container nodes (PARAGRAPH, HEADING, etc.) need a unique `id` (use any string, e.g., `"n1"`, `"n2"`). TEXT nodes can use an empty string `""` for `id`.
119
+ - TEXT nodes are always leaf nodes inside PARAGRAPH, HEADING, CODE_BLOCK, etc.
120
+ - LIST_ITEM nodes contain PARAGRAPH nodes (not TEXT directly)
121
+ - Mix at least 3 different node types per post for visual variety
122
+ - Create all 3 posts in sequence (one `CallWixSiteAPI` call per post)
123
+ - **Best practice:** include all fields (title, content, media) in the initial creation call to avoid needing a re-publish
124
+
125
+ > **Re-publish after PATCH:** If you update a published post (e.g., adding a cover image via PATCH after creation), it becomes `hasUnpublishedChanges: true`. You must call `POST /blog/v3/draft-posts/{draftPostId}/publish` to re-publish. To avoid this, include media in the initial creation call.
126
+
127
+ ## Step 4: Verify
128
+
129
+ Query published posts to confirm all 3 exist:
130
+
131
+ ```
132
+ CallWixSiteAPI: POST /blog/v3/posts/query
133
+ body: {
134
+ "query": {
135
+ "paging": { "limit": 10 }
136
+ }
137
+ }
138
+ ```
139
+
140
+ Confirm 3 posts are returned. Report post titles to the user.
141
+
142
+ ### Step 5: Log Results
143
+
144
+ Write a sidecar file at `.wix/logs/blog-data.md` (see `../../shared/LIFECYCLE_LOG.md` for the sidecar contract). Do **not** append to `.wix/lifecycle.log.md` directly — the orchestrator concatenates all sidecars at the end. Use a `####` heading so the entry nests under `### features-orchestrator` in the assembled log:
145
+
146
+ ```markdown
147
+ ## blog
148
+ - Status: complete
149
+ - Content: {n} posts published ({post titles})
150
+ - Images: {generated (n/n attached) | skipped (user declined) | not attempted}
151
+ ```
152
+
@@ -0,0 +1,299 @@
1
+ # Reference: Blog Pages
2
+
3
+ Blog listing, post detail, RSS feed, layout, SEO head component, and date formatting.
4
+
5
+ ## Files to Create
6
+
7
+ | File | Purpose |
8
+ |------|---------|
9
+ | `src/pages/blog/index.astro` | Blog listing page |
10
+ | `src/pages/blog/[...slug].astro` | Blog post detail page (with RicosViewer) |
11
+ | `src/pages/rss.xml.js` | RSS feed |
12
+ | `src/layouts/BlogPost.astro` | Blog post layout wrapper |
13
+ | `src/components/BaseHead.astro` | SEO head component (OG/Twitter cards) |
14
+ | `src/components/FormattedDate.astro` | Date formatting helper |
15
+
16
+ ---
17
+
18
+ ## 1. SEO Head Component (`src/components/BaseHead.astro`)
19
+
20
+ ```astro
21
+ ---
22
+ import '../styles/global.css';
23
+
24
+ interface Props {
25
+ title: string;
26
+ description: string;
27
+ image?: string;
28
+ }
29
+
30
+ const canonicalURL = new URL(Astro.url.pathname, Astro.site);
31
+
32
+ const { title, description, image = '/blog-placeholder-1.jpg' } = Astro.props;
33
+ ---
34
+
35
+ <!-- Global Metadata -->
36
+ <meta charset="utf-8" />
37
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
38
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
39
+ <meta name="generator" content={Astro.generator} />
40
+
41
+ <!-- Canonical URL -->
42
+ <link rel="canonical" href={canonicalURL} />
43
+
44
+ <!-- Primary Meta Tags -->
45
+ <title>{title}</title>
46
+ <meta name="title" content={title} />
47
+ <meta name="description" content={description} />
48
+
49
+ <!-- Open Graph / Facebook -->
50
+ <meta property="og:type" content="website" />
51
+ <meta property="og:url" content={Astro.url} />
52
+ <meta property="og:title" content={title} />
53
+ <meta property="og:description" content={description} />
54
+ <meta property="og:image" content={new URL(image, Astro.url)} />
55
+
56
+ <!-- Twitter -->
57
+ <meta property="twitter:card" content="summary_large_image" />
58
+ <meta property="twitter:url" content={Astro.url} />
59
+ <meta property="twitter:title" content={title} />
60
+ <meta property="twitter:description" content={description} />
61
+ <meta property="twitter:image" content={new URL(image, Astro.url)} />
62
+ ```
63
+
64
+ > If the project already has a `<head>` component or `Layout.astro` with SEO tags, adapt the existing component instead of creating a new one. The key additions are the OG/Twitter meta tags with `image` support.
65
+
66
+ ---
67
+
68
+ ## 2. Formatted Date Component (`src/components/FormattedDate.astro`)
69
+
70
+ ```astro
71
+ ---
72
+ interface Props {
73
+ date: Date;
74
+ }
75
+
76
+ const { date } = Astro.props;
77
+ ---
78
+
79
+ <time datetime={date.toISOString()}>
80
+ {
81
+ date.toLocaleDateString('en-us', {
82
+ year: 'numeric',
83
+ month: 'short',
84
+ day: 'numeric',
85
+ })
86
+ }
87
+ </time>
88
+ ```
89
+
90
+ ---
91
+
92
+ ## 3. Blog Post Layout (`src/layouts/BlogPost.astro`)
93
+
94
+ ```astro
95
+ ---
96
+ import BaseHead from '../components/BaseHead.astro';
97
+ import Header from '../components/Header.astro';
98
+ import Footer from '../components/Footer.astro';
99
+ import FormattedDate from '../components/FormattedDate.astro';
100
+
101
+ interface Props {
102
+ title: string;
103
+ description?: string;
104
+ pubDate: Date;
105
+ updatedDate?: Date;
106
+ heroImage?: string;
107
+ tags?: Array<{ label: string; slug: string }>;
108
+ }
109
+
110
+ const { title, description, pubDate, updatedDate, heroImage, tags = [] } = Astro.props;
111
+ ---
112
+
113
+ <html lang="en">
114
+ <head>
115
+ <BaseHead title={title} description={description ?? ''} />
116
+ <style is:global>
117
+ /* All BlogPost layout styles are created by the design skill.
118
+ See COMPONENT_PATTERNS.md → Blog Post Content for the complete
119
+ styling contract: .hero-image, .prose, .title, .date, .tags,
120
+ .ricos-content overrides, etc. */
121
+ </style>
122
+ </head>
123
+
124
+ <body>
125
+ <Header />
126
+ <main>
127
+ <article>
128
+ <div class="hero-image">
129
+ {heroImage && <img width={1020} height={510} src={heroImage} alt="" />}
130
+ </div>
131
+ <div class="prose">
132
+ <div class="title">
133
+ <div class="date">
134
+ <FormattedDate date={pubDate} />
135
+ {
136
+ updatedDate && (
137
+ <div class="last-updated-on">
138
+ Last updated on <FormattedDate date={updatedDate} />
139
+ </div>
140
+ )
141
+ }
142
+ </div>
143
+ <h1>{title}</h1>
144
+ {tags.length > 0 && (
145
+ <div class="tags">
146
+ {tags.map((tag) => (
147
+ <span class="tag">{tag.label}</span>
148
+ ))}
149
+ </div>
150
+ )}
151
+ <hr />
152
+ </div>
153
+ <slot />
154
+ </div>
155
+ </article>
156
+ </main>
157
+ <Footer />
158
+ </body>
159
+ </html>
160
+ ```
161
+
162
+ > Adapt `Header` and `Footer` imports to match the project's existing components. If the project uses a different layout pattern (e.g., `Layout.astro` wrapper), use that instead and incorporate the blog-specific elements (hero image, date, title, tags).
163
+
164
+ ---
165
+
166
+ ## 4. Blog Listing Page (`src/pages/blog/index.astro`)
167
+
168
+ ```astro
169
+ ---
170
+ import { queryBlogPosts } from "../../lib/blog";
171
+ import BaseHead from "../../components/BaseHead.astro";
172
+ import Footer from "../../components/Footer.astro";
173
+ import FormattedDate from "../../components/FormattedDate.astro";
174
+ import Header from "../../components/Header.astro";
175
+ import { SITE_DESCRIPTION, SITE_TITLE } from "../../consts";
176
+
177
+ const posts = await queryBlogPosts();
178
+ ---
179
+
180
+ <!doctype html>
181
+ <html lang="en">
182
+ <head>
183
+ <BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} />
184
+ <style>
185
+ /* Listing page styles are created by the design skill.
186
+ Feature skill only wires queryBlogPosts() data. */
187
+ </style>
188
+ </head>
189
+ <body>
190
+ <Header />
191
+ <main>
192
+ <section>
193
+ {
194
+ posts.length === 0 ? (
195
+ <div>There are no posts available.</div>
196
+ ) : (
197
+ <ul>
198
+ {posts.map((post) => (
199
+ <li>
200
+ <a href={`/blog/${post.slug}/`}>
201
+ {post.coverImageUrl && (
202
+ <img
203
+ width={720}
204
+ height={360}
205
+ src={post.coverImageUrl}
206
+ alt=""
207
+ />
208
+ )}
209
+ <h4 class="title">{post.title}</h4>
210
+ <p class="date">
211
+ <FormattedDate date={post.pubDate} />
212
+ </p>
213
+ </a>
214
+ </li>
215
+ ))}
216
+ </ul>
217
+ )
218
+ }
219
+ </section>
220
+ </main>
221
+ <Footer />
222
+ </body>
223
+ </html>
224
+ ```
225
+
226
+ > Adapt the layout to match the project's existing design. The key pattern is: `queryBlogPosts()` from the blog service, linking to `/blog/${post.slug}/`.
227
+
228
+ ---
229
+
230
+ ## 5. Blog Post Detail Page (`src/pages/blog/[...slug].astro`)
231
+
232
+ ```astro
233
+ ---
234
+ import RicosViewer from '../../components/RicosViewer';
235
+ import { getPostBySlug } from "../../lib/blog";
236
+ import BlogPost from '../../layouts/BlogPost.astro';
237
+
238
+ export const wixMetadata = {
239
+ appDefId: "14bcded7-0066-7c35-14d7-466cb3f09103",
240
+ pageIdentifier: "wix.blog.sub_pages.post",
241
+ identifiers: {
242
+ slug: "BLOG.POST.SLUG",
243
+ },
244
+ };
245
+
246
+ const { slug } = Astro.params;
247
+ const post = await getPostBySlug(slug!);
248
+
249
+ if (!post) {
250
+ return Astro.redirect("/blog");
251
+ }
252
+ ---
253
+
254
+ <BlogPost
255
+ title={post.title}
256
+ description={post.excerpt}
257
+ pubDate={post.pubDate}
258
+ heroImage={post.coverImageUrl}
259
+ tags={post.tags}
260
+ >
261
+ <RicosViewer client:only="react" content={post.richContent} />
262
+ </BlogPost>
263
+ ```
264
+
265
+ Critical details:
266
+ - **`wixMetadata` export is required** — it tells the Wix platform this page is a blog post page. The `appDefId` is the Wix Blog app's ID (constant, do not change). `identifiers.slug` maps the URL param to the blog post slug.
267
+ - **`client:only="react"` is required** — `@wix/ricos` is a React component; `client:only="react"` ensures it renders only on the client, avoiding SSR issues with React-dependent code.
268
+ - **`[...slug]` (rest param)** — uses Astro's rest parameter syntax, not `[slug]`, to match the full slug path.
269
+ - **`RicosViewer`** renders the rich content from the Wix Blog editor (images, videos, text formatting, embeds, etc.) using `quickStartViewerPlugins()` for full content-type support.
270
+ - **No `getStaticPaths()`** — Wix headless projects use `output: "server"` (SSR on Cloudflare Workers), so pages use `Astro.params` directly instead of static path generation.
271
+ - **404 handling** — `getPostBySlug` returns `null` for missing posts; redirect to `/blog` listing.
272
+ - **Ricos color overrides** — The BlogPost layout's `<style is:global>` block includes `.ricos-content` overrides that force `var(--color-text)` on all Ricos elements. Without these, blog text is invisible on dark themes.
273
+
274
+ ---
275
+
276
+ ## 6. RSS Feed (`src/pages/rss.xml.js`)
277
+
278
+ ```javascript
279
+ import rss from '@astrojs/rss';
280
+ import { queryBlogPosts } from '../lib/blog';
281
+ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
282
+
283
+ export async function GET(context) {
284
+ const posts = await queryBlogPosts();
285
+ return rss({
286
+ title: SITE_TITLE,
287
+ description: SITE_DESCRIPTION,
288
+ site: context.site,
289
+ items: posts.map((post) => ({
290
+ title: post.title,
291
+ pubDate: post.pubDate,
292
+ description: post.excerpt,
293
+ link: `/blog/${post.slug}/`,
294
+ })),
295
+ });
296
+ }
297
+ ```
298
+
299
+ > Requires the `site` property in `astro.config.mjs` (set in BLOG_SETUP.md step 1).