@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.
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/package.json +29 -0
- package/skills/wix-app/SKILL.md +344 -0
- package/skills/wix-app/references/APP_IDENTIFIERS.md +35 -0
- package/skills/wix-app/references/APP_MARKET_REVIEW.md +311 -0
- package/skills/wix-app/references/APP_VALIDATION.md +171 -0
- package/skills/wix-app/references/BACKEND_API.md +233 -0
- package/skills/wix-app/references/BACKEND_EVENT.md +116 -0
- package/skills/wix-app/references/CODE_QUALITY.md +33 -0
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +587 -0
- package/skills/wix-app/references/DASHBOARD_MENU_PLUGIN.md +157 -0
- package/skills/wix-app/references/DASHBOARD_MODAL.md +283 -0
- package/skills/wix-app/references/DASHBOARD_PAGE.md +403 -0
- package/skills/wix-app/references/DASHBOARD_PLUGIN.md +205 -0
- package/skills/wix-app/references/DATA_COLLECTION.md +451 -0
- package/skills/wix-app/references/DOCUMENTATION.md +42 -0
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +65 -0
- package/skills/wix-app/references/EMBEDDED_SCRIPT.md +468 -0
- package/skills/wix-app/references/EXTENSION_REGISTRATION.md +96 -0
- package/skills/wix-app/references/SERVICE_PLUGIN.md +235 -0
- package/skills/wix-app/references/SITE_PLUGIN.md +436 -0
- package/skills/wix-app/references/STORES_VERSIONING.md +334 -0
- package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +84 -0
- package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +345 -0
- package/skills/wix-app/references/dashboard-menu-plugin/blog-slots.md +71 -0
- package/skills/wix-app/references/dashboard-menu-plugin/bookings-slots.md +58 -0
- package/skills/wix-app/references/dashboard-menu-plugin/crm-slots.md +8 -0
- package/skills/wix-app/references/dashboard-menu-plugin/ecommerce-slots.md +17 -0
- package/skills/wix-app/references/dashboard-menu-plugin/events-slots.md +29 -0
- package/skills/wix-app/references/dashboard-menu-plugin/restaurants-slots.md +27 -0
- package/skills/wix-app/references/dashboard-menu-plugin/stores-slots.md +35 -0
- package/skills/wix-app/references/dashboard-page/API_SPEC.md +138 -0
- package/skills/wix-app/references/dashboard-page/DASHBOARD_API.md +573 -0
- package/skills/wix-app/references/dashboard-page/DYNAMIC_PARAMETERS.md +269 -0
- package/skills/wix-app/references/dashboard-page/ECOM_NAVIGATION.md +164 -0
- package/skills/wix-app/references/dashboard-plugin/SLOTS.md +294 -0
- package/skills/wix-app/references/data-collection/WIX_DATA.md +270 -0
- package/skills/wix-app/references/data-collection/extension-template.ts +107 -0
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +138 -0
- package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +454 -0
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +165 -0
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +576 -0
- package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +170 -0
- package/skills/wix-app/references/editor-react-component/EDIT-FLOW.md +6 -0
- package/skills/wix-app/references/editor-react-component/PARTS.md +25 -0
- package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +203 -0
- package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +167 -0
- package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +137 -0
- package/skills/wix-app/references/service-plugin/ADDITIONAL-FEES.md +112 -0
- package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +118 -0
- package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +87 -0
- package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +86 -0
- package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +135 -0
- package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +79 -0
- package/skills/wix-app/references/service-plugin/VALIDATIONS.md +68 -0
- package/skills/wix-app/references/site-plugin/EXAMPLES.md +311 -0
- package/skills/wix-app/references/site-plugin/SLOTS.md +263 -0
- package/skills/wix-design-system/SKILL.md +129 -0
- package/skills/wix-design-system/references/file-structure.md +56 -0
- package/skills/wix-design-system/scripts/wds.cjs +531 -0
- package/skills/wix-headless/SKILL.md +418 -0
- package/skills/wix-headless/references/DISCOVERY.md +332 -0
- package/skills/wix-headless/references/ORCHESTRATION.md +269 -0
- package/skills/wix-headless/references/SETUP.md +154 -0
- package/skills/wix-headless/references/blog/BLOG_CONTENT.md +152 -0
- package/skills/wix-headless/references/blog/BLOG_PAGES.md +299 -0
- package/skills/wix-headless/references/blog/BLOG_SETUP.md +218 -0
- package/skills/wix-headless/references/blog/INSTRUCTIONS.md +32 -0
- package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +373 -0
- package/skills/wix-headless/references/cms/FAQ_KNOWLEDGE_BASE.md +229 -0
- package/skills/wix-headless/references/cms/INSTRUCTIONS.md +40 -0
- package/skills/wix-headless/references/cms/PORTFOLIO.md +454 -0
- package/skills/wix-headless/references/cms/RESOURCE_LIBRARY.md +356 -0
- package/skills/wix-headless/references/cms/TEAM_DIRECTORY.md +299 -0
- package/skills/wix-headless/references/commands/install-app.md +42 -0
- package/skills/wix-headless/references/commands/known-apps.json +5 -0
- package/skills/wix-headless/references/commands/mcp-bootstrap.md +28 -0
- package/skills/wix-headless/references/designer/INSTRUCTIONS.md +828 -0
- package/skills/wix-headless/references/ecom/CART_PAGES.md +120 -0
- package/skills/wix-headless/references/ecom/CART_WIRING.md +103 -0
- package/skills/wix-headless/references/ecom/COMPONENTS_CSS.md +132 -0
- package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +59 -0
- package/skills/wix-headless/references/forms/CONTACT_FORM.md +477 -0
- package/skills/wix-headless/references/forms/INSTRUCTIONS.md +43 -0
- package/skills/wix-headless/references/gift-cards/COMPONENTS.md +119 -0
- package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +51 -0
- package/skills/wix-headless/references/gift-cards/PAGES.md +129 -0
- package/skills/wix-headless/references/images/INSTRUCTIONS.md +359 -0
- package/skills/wix-headless/references/shared/BUILD_NOISE.md +8 -0
- package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +185 -0
- package/skills/wix-headless/references/shared/IMPLEMENTER.md +155 -0
- package/skills/wix-headless/references/shared/MCP_PREFIX.md +105 -0
- package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +97 -0
- package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +423 -0
- package/skills/wix-headless/references/shared/STYLING.md +117 -0
- package/skills/wix-headless/references/stores/BACK_IN_STOCK.md +178 -0
- package/skills/wix-headless/references/stores/CATEGORY_PAGES.md +86 -0
- package/skills/wix-headless/references/stores/COMPONENTS_CSS.md +129 -0
- package/skills/wix-headless/references/stores/HOME_AND_NAV.md +227 -0
- package/skills/wix-headless/references/stores/INSTRUCTIONS.md +96 -0
- package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +249 -0
- package/skills/wix-headless/references/stores/PRODUCT_PAGES.md +213 -0
- package/skills/wix-headless/references/stores/SHARED_WIRING.md +164 -0
- package/skills/wix-headless/references/verticals/_schema.json +160 -0
- package/skills/wix-headless/references/verticals/_schema.md +185 -0
- package/skills/wix-headless/references/verticals/blog.md +125 -0
- package/skills/wix-headless/references/verticals/cms.md +121 -0
- package/skills/wix-headless/references/verticals/ecom.md +96 -0
- package/skills/wix-headless/references/verticals/forms.md +106 -0
- package/skills/wix-headless/references/verticals/gift-cards.md +121 -0
- package/skills/wix-headless/references/verticals/stores.md +167 -0
- package/skills/wix-headless/scripts/check-manifest.mjs +198 -0
- package/skills/wix-headless/scripts/copy-utility-templates.mjs +153 -0
- package/skills/wix-headless/scripts/emit-design-tokens.mjs +77 -0
- package/skills/wix-headless/scripts/finalize-run-json.mjs +141 -0
- package/skills/wix-headless/scripts/init-site-json.mjs +63 -0
- package/skills/wix-headless/scripts/patch-decorative-slots.mjs +124 -0
- package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +190 -0
- package/skills/wix-headless/scripts/preview.sh +45 -0
- package/skills/wix-headless/scripts/release.sh +73 -0
- package/skills/wix-headless/scripts/scaffold.sh +53 -0
- package/skills/wix-headless/scripts/seed-utilities.sh +55 -0
- package/skills/wix-headless/shared-utilities/analytics.ts +40 -0
- package/skills/wix-headless/shared-utilities/ricos.ts +179 -0
- package/skills/wix-headless/shared-utilities/wix-image.ts +72 -0
- package/skills/wix-headless/templates/ecom/CartBadge.tsx +84 -0
- package/skills/wix-headless/templates/ecom/CartView.tsx +543 -0
- package/skills/wix-headless/templates/ecom/cart.astro +13 -0
- package/skills/wix-headless/templates/ecom/components-ecom.css +215 -0
- package/skills/wix-headless/templates/ecom/discounts.ts +71 -0
- package/skills/wix-headless/templates/ecom/thank-you.astro +24 -0
- package/skills/wix-headless/templates/gift-cards/GiftCardPurchase.tsx +172 -0
- package/skills/wix-headless/templates/gift-cards/_home-teaser-snippet.astro +42 -0
- package/skills/wix-headless/templates/gift-cards/_nav-snippet.astro +11 -0
- package/skills/wix-headless/templates/gift-cards/components-gift-cards.css +219 -0
- package/skills/wix-headless/templates/gift-cards/gift-cards.astro +51 -0
- package/skills/wix-headless/templates/gift-cards/gift-cards.ts +75 -0
- package/skills/wix-headless/templates/stores/AddToCartButton.tsx +77 -0
- package/skills/wix-headless/templates/stores/BackInStockForm.tsx +176 -0
- package/skills/wix-headless/templates/stores/CategoryRail.astro +69 -0
- package/skills/wix-headless/templates/stores/ProductCard.astro +79 -0
- package/skills/wix-headless/templates/stores/ProductPurchase.tsx +397 -0
- package/skills/wix-headless/templates/stores/SeoTags.astro +21 -0
- package/skills/wix-headless/templates/stores/back-in-stock.ts +67 -0
- package/skills/wix-headless/templates/stores/categories.ts +155 -0
- package/skills/wix-headless/templates/stores/category/[slug].astro +130 -0
- package/skills/wix-headless/templates/stores/components-stores.css +295 -0
- package/skills/wix-headless/templates/stores/products/[slug].astro +128 -0
- package/skills/wix-headless/templates/stores/products/index.astro +101 -0
- package/skills/wix-manage/SKILL.md +280 -0
- package/skills/wix-manage/references/app-installation/install-wix-apps.md +155 -0
- package/skills/wix-manage/references/app-installation/list-installed-apps.md +124 -0
- package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +226 -0
- package/skills/wix-manage/references/bookings/booking-service-policy-setup.md +95 -0
- package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +416 -0
- package/skills/wix-manage/references/bookings/bookings-staff-setup.md +255 -0
- package/skills/wix-manage/references/bookings/create-and-update-booking-services.md +462 -0
- package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +278 -0
- package/skills/wix-manage/references/bookings/external-calendar-integration.md +258 -0
- package/skills/wix-manage/references/bookings/multi-resource-service-creation.md +231 -0
- package/skills/wix-manage/references/calendar/configure-default-business-hours.md +226 -0
- package/skills/wix-manage/references/cms/cms-data-items-crud.md +422 -0
- package/skills/wix-manage/references/cms/cms-data-operations-extended.md +263 -0
- package/skills/wix-manage/references/cms/cms-ecommerce-catalog-integration.md +136 -0
- package/skills/wix-manage/references/cms/cms-references-and-relationships.md +160 -0
- package/skills/wix-manage/references/cms/cms-schema-management.md +143 -0
- package/skills/wix-manage/references/contacts/bulk-delete-contacts.md +73 -0
- package/skills/wix-manage/references/contacts/bulk-label-and-unlabel-contacts.md +67 -0
- package/skills/wix-manage/references/domains/domain-search-and-purchase.md +434 -0
- package/skills/wix-manage/references/ecommerce/api-recommendation-tracking.md +420 -0
- package/skills/wix-manage/references/ecommerce/flow-add-free-shipping.md +267 -0
- package/skills/wix-manage/references/ecommerce/flow-bundle-and-save.md +290 -0
- package/skills/wix-manage/references/ecommerce/flow-fix-coverage-gaps.md +300 -0
- package/skills/wix-manage/references/ecommerce/flow-optimize-shipping-rates.md +364 -0
- package/skills/wix-manage/references/ecommerce/flow-seasonal-promotion.md +315 -0
- package/skills/wix-manage/references/ecommerce/flow-stock-mover.md +308 -0
- package/skills/wix-manage/references/ecommerce/flow-upsell-boost.md +271 -0
- package/skills/wix-manage/references/ecommerce/goal-clear-inventory.md +118 -0
- package/skills/wix-manage/references/ecommerce/goal-drive-cross-sells.md +122 -0
- package/skills/wix-manage/references/ecommerce/goal-increase-aov.md +132 -0
- package/skills/wix-manage/references/ecommerce/goal-reduce-cart-abandonment.md +148 -0
- package/skills/wix-manage/references/ecommerce/goal-seasonal-revenue.md +146 -0
- package/skills/wix-manage/references/ecommerce/guardrail-discount-conflicts.md +118 -0
- package/skills/wix-manage/references/ecommerce/guardrail-margin-protection.md +88 -0
- package/skills/wix-manage/references/ecommerce/guardrail-rate-pricing-sanity.md +108 -0
- package/skills/wix-manage/references/ecommerce/guardrail-shipping-health.md +124 -0
- package/skills/wix-manage/references/ecommerce/recipe-apply-shipping-recommendations.md +299 -0
- package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +582 -0
- package/skills/wix-manage/references/ecommerce/setup-coupons.md +338 -0
- package/skills/wix-manage/references/ecommerce/setup-discount-rules.md +444 -0
- package/skills/wix-manage/references/ecommerce/setup-shipping-rates.md +86 -0
- package/skills/wix-manage/references/ecommerce/setup-shipping-regions.md +56 -0
- package/skills/wix-manage/references/ecommerce/setup-store-pickup-location.md +209 -0
- package/skills/wix-manage/references/ecommerce/skill-graph.md +139 -0
- package/skills/wix-manage/references/ecommerce/troubleshoot-checkout-delivery-dropoff.md +124 -0
- package/skills/wix-manage/references/ecommerce/troubleshoot-discount-not-applying.md +95 -0
- package/skills/wix-manage/references/events/list-events.md +203 -0
- package/skills/wix-manage/references/forms/create-form.md +260 -0
- package/skills/wix-manage/references/get-paid/create-payment-links.md +212 -0
- package/skills/wix-manage/references/get-paid/how-to-setup-wix-payments.md +57 -0
- package/skills/wix-manage/references/get-paid/payment-links-for-bookings.md +101 -0
- package/skills/wix-manage/references/media/upload-media-to-wix.md +216 -0
- package/skills/wix-manage/references/pricing-plans/create-and-update-pricing-plans.md +77 -0
- package/skills/wix-manage/references/pricing-plans/pricing-plans-bookings-integration.md +166 -0
- package/skills/wix-manage/references/restaurants/wix-restaurants-setup.md +336 -0
- package/skills/wix-manage/references/rich-content/ricos-converter-service.md +295 -0
- package/skills/wix-manage/references/site-properties/change-payment-currency-site-properties.md +59 -0
- package/skills/wix-manage/references/sites/create-site-from-template.md +183 -0
- package/skills/wix-manage/references/sites/query-sites.md +125 -0
- package/skills/wix-manage/references/stores/add-store-pages-to-site.md +57 -0
- package/skills/wix-manage/references/stores/bulk-create-products-with-options.md +1041 -0
- package/skills/wix-manage/references/stores/create-product-catalog-v1.md +125 -0
- package/skills/wix-manage/references/stores/create-product-from-image.md +824 -0
- package/skills/wix-manage/references/stores/create-product-with-options-catalog-v3.md +566 -0
- package/skills/wix-manage/references/stores/find-products-query-and-search-catalog-v3.md +194 -0
- package/skills/wix-manage/references/stores/query-products-catalog-v1.md +80 -0
- package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +99 -0
- package/skills/wix-manage/references/stores/update-product-pre-order.md +213 -0
- 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 & 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).
|