@wix/agent-skills 1.6.0 → 1.7.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/README.md +2 -2
- package/package.json +1 -1
- package/skills/wix-app/SKILL.md +49 -42
- package/skills/wix-app/references/BACKEND_EVENT.md +10 -65
- package/skills/wix-app/references/CUSTOM_ELEMENT_WIDGET.md +101 -406
- package/skills/wix-app/references/DASHBOARD_MENU_PLUGIN.md +14 -111
- package/skills/wix-app/references/DASHBOARD_MODAL.md +56 -205
- package/skills/wix-app/references/DASHBOARD_PAGE.md +19 -98
- package/skills/wix-app/references/DASHBOARD_PLUGIN.md +6 -108
- package/skills/wix-app/references/DATA_COLLECTION.md +113 -198
- package/skills/wix-app/references/EMBEDDED_SCRIPT.md +41 -268
- package/skills/wix-app/references/EXTENSION_REGISTRATION.md +27 -76
- package/skills/wix-app/references/SERVICE_PLUGIN.md +35 -188
- package/skills/wix-app/references/SITE_PLUGIN.md +8 -92
- package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +0 -44
- package/skills/wix-app/references/custom-element-widget/SETTINGS_PANEL.md +19 -330
- package/skills/wix-app/references/dashboard-menu-plugin/bookings-slots.md +0 -12
- package/skills/wix-app/references/dashboard-menu-plugin/ecommerce-slots.md +7 -0
- package/skills/wix-app/references/dashboard-menu-plugin/restaurants-slots.md +0 -12
- package/skills/wix-app/references/dashboard-plugin/SLOTS.md +3 -15
- package/skills/wix-app/references/service-plugin/ADDITIONAL-FEES.md +2 -18
- package/skills/wix-app/references/service-plugin/BOOKINGS-STAFF-SORTING.md +2 -42
- package/skills/wix-app/references/service-plugin/DISCOUNT-TRIGGERS.md +1 -11
- package/skills/wix-app/references/service-plugin/GIFT-CARDS.md +1 -11
- package/skills/wix-app/references/service-plugin/PAYMENT-SETTINGS.md +2 -40
- package/skills/wix-app/references/service-plugin/SHIPPING-RATES.md +2 -19
- package/skills/wix-app/references/service-plugin/VALIDATIONS.md +2 -18
- package/skills/wix-app/references/site-plugin/SLOTS.md +17 -68
- package/skills/wix-headless/SKILL.md +111 -389
- package/skills/wix-headless/references/BUILD.md +307 -0
- package/skills/wix-headless/references/DESIGN_SYSTEM.md +115 -0
- package/skills/wix-headless/references/DISCOVERY.md +237 -112
- package/skills/wix-headless/references/PLAN.md +82 -0
- package/skills/wix-headless/references/SEED.md +205 -0
- package/skills/wix-headless/references/SETUP.md +140 -134
- package/skills/wix-headless/references/astro/COMPOSE.md +142 -0
- package/skills/wix-headless/references/{blog → astro/blog}/BLOG_PAGES.md +1 -1
- package/skills/wix-headless/references/{blog → astro/blog}/BLOG_SETUP.md +2 -2
- package/skills/wix-headless/references/astro/cms/CMS_FOUNDATIONS.md +214 -0
- package/skills/wix-headless/references/{cms → astro/cms}/FAQ_KNOWLEDGE_BASE.md +6 -4
- package/skills/wix-headless/references/{cms → astro/cms}/PORTFOLIO.md +5 -5
- package/skills/wix-headless/references/{cms → astro/cms}/RESOURCE_LIBRARY.md +5 -5
- package/skills/wix-headless/references/{cms → astro/cms}/TEAM_DIRECTORY.md +5 -5
- package/skills/wix-headless/references/astro/designer/INSTRUCTIONS.md +331 -0
- package/skills/wix-headless/references/{ecom → astro/ecom}/CART_PAGES.md +1 -1
- package/skills/wix-headless/references/{ecom → astro/ecom}/CART_WIRING.md +1 -1
- package/skills/wix-headless/references/{ecom → astro/ecom}/COMPONENTS_CSS.md +3 -3
- package/skills/wix-headless/references/{forms → astro/forms}/CONTACT_FORM.md +13 -13
- package/skills/wix-headless/references/{gift-cards → astro/gift-cards}/COMPONENTS.md +1 -1
- package/skills/wix-headless/references/{gift-cards → astro/gift-cards}/PAGES.md +1 -1
- package/skills/wix-headless/references/{stores → astro/stores}/BACK_IN_STOCK.md +1 -1
- package/skills/wix-headless/references/{stores → astro/stores}/CATEGORY_PAGES.md +12 -13
- package/skills/wix-headless/references/{stores → astro/stores}/COMPONENTS_CSS.md +4 -4
- package/skills/wix-headless/references/{stores → astro/stores}/HOME_AND_NAV.md +11 -9
- package/skills/wix-headless/references/{stores → astro/stores}/PRODUCT_PAGES.md +5 -3
- package/skills/wix-headless/references/{stores → astro/stores}/SHARED_WIRING.md +3 -3
- package/skills/wix-headless/references/astro/templates/Footer.astro +27 -0
- package/skills/wix-headless/references/astro/templates/Layout.astro +132 -0
- package/skills/wix-headless/references/astro/templates/Navigation.astro +38 -0
- package/skills/wix-headless/references/astro/templates/astro.config.mjs +41 -0
- package/skills/wix-headless/references/astro/templates/ecom/components-ecom.css +302 -0
- package/skills/wix-headless/references/astro/templates/global.css +286 -0
- package/skills/wix-headless/references/astro/templates/index.astro +56 -0
- package/skills/wix-headless/{templates → references/astro/templates}/stores/back-in-stock.ts +1 -1
- package/skills/wix-headless/{templates → references/astro/templates}/stores/components-stores.css +138 -33
- package/skills/wix-headless/references/blog/BLOG_CONTENT.md +10 -11
- package/skills/wix-headless/references/blog/INSTRUCTIONS.md +5 -5
- package/skills/wix-headless/references/cms/CMS_FOUNDATIONS.md +31 -230
- package/skills/wix-headless/references/cms/INSTRUCTIONS.md +13 -8
- package/skills/wix-headless/references/custom/INSTRUCTIONS.md +38 -0
- package/skills/wix-headless/references/ecom/INSTRUCTIONS.md +10 -10
- package/skills/wix-headless/references/forms/INSTRUCTIONS.md +5 -5
- package/skills/wix-headless/references/gift-cards/INSTRUCTIONS.md +11 -11
- package/skills/wix-headless/references/images/INSTRUCTIONS.md +47 -50
- package/skills/wix-headless/references/seed-recipes.md +49 -0
- package/skills/wix-headless/references/shared/AUTHENTICATION.md +110 -0
- package/skills/wix-headless/references/shared/BUILD_NOISE.md +2 -2
- package/skills/wix-headless/references/shared/DOCS_SEARCH.md +41 -0
- package/skills/wix-headless/references/shared/IMAGE_GENERATION.md +17 -17
- package/skills/wix-headless/references/shared/IMPLEMENTER.md +20 -29
- package/skills/wix-headless/references/shared/PRODUCTION_SHARP_EDGES.md +1 -1
- package/skills/wix-headless/references/shared/RETURN_CONTRACT.md +25 -16
- package/skills/wix-headless/references/shared/STYLING.md +47 -10
- package/skills/wix-headless/references/stores/INSTRUCTIONS.md +25 -25
- package/skills/wix-headless/references/stores/PRODUCT_CATALOG_DATA.md +17 -17
- package/skills/wix-headless/references/verticals/_schema.json +31 -117
- package/skills/wix-headless/references/verticals/_schema.md +60 -150
- package/skills/wix-headless/references/verticals/blog.md +5 -99
- package/skills/wix-headless/references/verticals/cms.md +9 -100
- package/skills/wix-headless/references/verticals/ecom.md +5 -76
- package/skills/wix-headless/references/verticals/forms.md +5 -85
- package/skills/wix-headless/references/verticals/gift-cards.md +6 -103
- package/skills/wix-headless/references/verticals/stores.md +10 -144
- package/skills/wix-headless/scripts/check-manifest.mjs +5 -5
- package/skills/wix-headless/scripts/emit-design-tokens.mjs +29 -23
- package/skills/wix-headless/scripts/init-site-json.mjs +59 -21
- package/skills/wix-headless/scripts/patch-decorative-slots.mjs +67 -43
- package/skills/wix-headless/scripts/plan-entity-image-waves.mjs +3 -3
- package/skills/wix-headless/scripts/preview.sh +3 -3
- package/skills/wix-headless/scripts/release.sh +4 -4
- package/skills/wix-headless/scripts/scaffold.sh +75 -20
- package/skills/wix-headless/scripts/seed-utilities.sh +50 -12
- package/skills/wix-manage/SKILL.md +4 -8
- package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +2 -0
- package/skills/wix-manage/references/cms/cms-data-items-crud.md +4 -0
- package/skills/wix-manage/references/cms/cms-references-and-relationships.md +2 -0
- package/skills/wix-manage/references/cms/cms-schema-management.md +4 -0
- package/skills/wix-manage/references/ecommerce/api-shipping.md +443 -0
- package/skills/wix-manage/references/ecommerce/flow-add-free-shipping.md +5 -6
- package/skills/wix-manage/references/ecommerce/flow-fix-coverage-gaps.md +4 -5
- package/skills/wix-manage/references/ecommerce/flow-optimize-shipping-rates.md +4 -5
- package/skills/wix-manage/references/ecommerce/goal-increase-aov.md +1 -1
- package/skills/wix-manage/references/ecommerce/goal-reduce-cart-abandonment.md +1 -2
- package/skills/wix-manage/references/ecommerce/guardrail-shipping-health.md +2 -2
- package/skills/wix-manage/references/ecommerce/recipe-apply-shipping-recommendations.md +4 -5
- package/skills/wix-manage/references/ecommerce/recommend-ecommerce-strategy.md +7 -7
- package/skills/wix-manage/references/ecommerce/setup-discount-rules.md +209 -72
- package/skills/wix-manage/references/ecommerce/setup-store-pickup-location.md +9 -10
- package/skills/wix-manage/references/ecommerce/skill-graph.md +4 -4
- package/skills/wix-manage/references/forms/create-form.md +2 -0
- package/skills/wix-manage/references/stores/bulk-create-products-with-options.md +2 -0
- package/skills/wix-manage/references/stores/create-product-from-image.md +91 -38
- package/skills/wix-manage/references/stores/setup-online-store-catalog-v3.md +2 -0
- package/skills/wix-app/references/custom-element-widget/default-thumbnail.png +0 -0
- package/skills/wix-app/references/data-collection/extension-template.ts +0 -107
- package/skills/wix-headless/references/ORCHESTRATION.md +0 -269
- package/skills/wix-headless/references/commands/install-app.md +0 -42
- package/skills/wix-headless/references/commands/mcp-bootstrap.md +0 -28
- package/skills/wix-headless/references/designer/INSTRUCTIONS.md +0 -828
- package/skills/wix-headless/references/shared/MCP_PREFIX.md +0 -105
- package/skills/wix-headless/scripts/copy-utility-templates.mjs +0 -153
- package/skills/wix-headless/templates/ecom/components-ecom.css +0 -215
- package/skills/wix-manage/references/events/list-events.md +0 -203
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/CartBadge.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/CartView.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/cart.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/discounts.ts +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/ecom/thank-you.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/GiftCardPurchase.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/_home-teaser-snippet.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/_nav-snippet.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/components-gift-cards.css +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/gift-cards.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/gift-cards/gift-cards.ts +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/AddToCartButton.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/BackInStockForm.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/CategoryRail.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/ProductCard.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/ProductPurchase.tsx +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/SeoTags.astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/categories.ts +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/category/[slug].astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/products/[slug].astro +0 -0
- /package/skills/wix-headless/{templates → references/astro/templates}/stores/products/index.astro +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Phase 4 Home Page + Nav — Stores
|
|
2
2
|
|
|
3
|
-
Scope: `pages-home-and-nav`. Launched in **Step 7
|
|
3
|
+
Scope: `pages-home-and-nav`. Launched in **Step 7**; imports the orchestrator-pre-copied `categories.ts` helper (and the rail `pages-categories` writes — resolved at build time). Patches the home page's stores-related placeholder data with live `productsV3` queries AND inserts the Shop submenu (categories list) into the persisted Navigation.
|
|
4
|
+
|
|
5
|
+
> **You patch the shared `Navigation.astro` + `index.astro` shells**, which other packs (e.g. gift-cards) also patch at their own markers. **Touch only your markers and preserve every other scope's siblings — never rewrite either file.** (Flow is the conductor's job: it serializes shell-patching scopes so concurrent marker edits don't collide — BUILD.md Step 7.)
|
|
4
6
|
|
|
5
7
|
## Scope
|
|
6
8
|
|
|
@@ -12,14 +14,14 @@ Files this agent PATCHES (does NOT rewrite):
|
|
|
12
14
|
Files this agent MUST NOT touch:
|
|
13
15
|
- Any other part of `index.astro` — hero, copy, newsletter, decorative ornaments are designer-owned
|
|
14
16
|
- Any part of `Navigation.astro` outside the `<!-- nav:links -->` marker — designer/ecom-owned (the marker model lets multiple verticals contribute siblings without conflict)
|
|
15
|
-
- `src/utils/categories.ts
|
|
17
|
+
- `src/utils/categories.ts` — pre-copied by the orchestrator; this scope only **imports** `listStoreCategories` from it. `src/components/CategoryRail.astro`, `src/pages/category/[slug].astro` — owned by `pages-categories`
|
|
16
18
|
- Any other component, page, or CSS
|
|
17
19
|
- `global.css`
|
|
18
20
|
|
|
19
21
|
## Inputs (from parent prompt)
|
|
20
22
|
|
|
21
23
|
- **Phase 1 stores return** — `products: [{id, name, slug, ...}]`. Needed for live query on home page; also useful for deciding how many to feature.
|
|
22
|
-
- **Design tokens** —
|
|
24
|
+
- **Design tokens** — the full `designTokens` JSON is inlined in your prompt for the published color/spacing/typography vocabulary; compose Tailwind utilities derived from those tokens at the call site rather than inventing semantic classes. See `references/shared/STYLING.md` for the three styling categories.
|
|
23
25
|
- **Designer output summary** — path of `src/pages/index.astro` and `src/components/Navigation.astro`, with notes on what placeholder data exists.
|
|
24
26
|
- **Categories (lookup)** — if the designer used category links with hardcoded slugs, call `categoriesV3` SDK to discover real category slugs and rewrite `href`s.
|
|
25
27
|
|
|
@@ -28,7 +30,7 @@ Files this agent MUST NOT touch:
|
|
|
28
30
|
1. **Surgical edits only.** Use `Edit` tool, not `Write`. Preserve everything the designer wrote — hero, copy, decorative elements, section structure, class names.
|
|
29
31
|
2. **Do NOT restructure layout.** If the designer didn't include featured products, don't add it.
|
|
30
32
|
3. **Do NOT mutate categories in the catalog.** Read-only. Match designer's category slugs against real ones; rewrite `href` if matched; fall back to `/products` if not.
|
|
31
|
-
4. **Never improvise category endpoint URLs.** Use `categoriesV3` SDK. If the SDK isn't available, fall back to
|
|
33
|
+
4. **Never improvise category endpoint URLs.** Use `categoriesV3` SDK. If the SDK isn't available, fall back to `curl` with `POST /categories/v1/categories/query` body `{"query":{}}`. Improvised `/stores/v3/categories/...` URLs cause a multi-minute stall.
|
|
32
34
|
5. **If another agent already wired the home page** (e.g., a previous run), leave it alone and note this in the return.
|
|
33
35
|
6. **ProductCard is a template** — always accepts `{ product }`. Pass raw SDK product objects, never flat-map. See § 1a.
|
|
34
36
|
|
|
@@ -72,7 +74,7 @@ try {
|
|
|
72
74
|
---
|
|
73
75
|
```
|
|
74
76
|
|
|
75
|
-
Then pass each raw product to `ProductCard`. The ribbon is fetched inside ProductCard itself — pages
|
|
77
|
+
Then pass each raw product to `ProductCard`. The ribbon is fetched inside ProductCard itself — pages don't wire offers:
|
|
76
78
|
```astro
|
|
77
79
|
{featured.map((p) => <ProductCard product={p} />)}
|
|
78
80
|
```
|
|
@@ -116,7 +118,7 @@ Handle this:
|
|
|
116
118
|
import { categoriesV3 } from "@wix/stores";
|
|
117
119
|
const { items: categories } = await categoriesV3.queryCategories().find();
|
|
118
120
|
```
|
|
119
|
-
Fall back to `
|
|
121
|
+
Fall back to `curl` with `POST https://www.wixapis.com/categories/v1/categories/query` body `{"query":{}}` if the SDK module is unavailable (headers per `AUTHENTICATION.md`).
|
|
120
122
|
2. **Match by name or slug** — case-insensitive substring match is fine (e.g., designer's "rubber" card matches a real category "Rubber Ducks").
|
|
121
123
|
3. **If a match exists** → rewrite the `href` to use the real category slug (and optionally real category name).
|
|
122
124
|
4. **If no match exists** → render the card with `/products` (no filter) rather than a dead filter URL. Keep the visual card intact.
|
|
@@ -128,7 +130,7 @@ Handle this:
|
|
|
128
130
|
|
|
129
131
|
The designer scaffolds `Navigation.astro` with a `<!-- nav:links -->` marker that vertical packs replace with their primary nav contributions. Stores contributes the Shop link (always) and a hover/focus submenu listing the merchant's visible categories (when any exist — empty by default, since Phase 1 does not seed them).
|
|
130
132
|
|
|
131
|
-
|
|
133
|
+
Import `listStoreCategories` from `src/utils/categories.ts` (already on disk — pre-copied by the orchestrator). At the marker, insert:
|
|
132
134
|
|
|
133
135
|
```astro
|
|
134
136
|
---
|
|
@@ -213,7 +215,7 @@ Keep the marker comment immediately after the inserted `<li>` so other vertical
|
|
|
213
215
|
- **Do NOT mutate** categories in the catalog — read-only.
|
|
214
216
|
- **Do NOT touch** `Navigation.astro` outside the `<!-- nav:links -->` marker. Other vertical packs use the same marker model and write siblings.
|
|
215
217
|
- **Do NOT touch** `CartBadge.tsx` or `CartView.tsx` — owned by ecom.
|
|
216
|
-
- **Do NOT rewrite** `src/utils/categories.ts` or `src/components/CategoryRail.astro`
|
|
218
|
+
- **Do NOT rewrite** `src/utils/categories.ts` (pre-copied by the orchestrator — import only) or `src/components/CategoryRail.astro` (owned by `pages-categories`).
|
|
217
219
|
- If home page already has a live query (another agent wired it), leave alone and note in return.
|
|
218
220
|
|
|
219
221
|
## Anti-patterns
|
|
@@ -224,4 +226,4 @@ Keep the marker comment immediately after the inserted `<li>` so other vertical
|
|
|
224
226
|
| Call `/stores/v3/categories/query` | Use `categoriesV3` SDK, or fall back to `/categories/v1/categories/query` |
|
|
225
227
|
| Invent category slugs that don't exist | Match real categories; fall back to `/products` for unmatched |
|
|
226
228
|
| Pass flat props (`name={p.name}`) when ProductCard expects `product={...}` object | ProductCard is a template — always `<ProductCard product={p} />` with the raw SDK object |
|
|
227
|
-
| `featured = products.map(p => ({name: p.name, ...}))` — flat-mapping SDK results | Store raw products: `featured = featuredProducts ?? []` as `any[]` |
|
|
229
|
+
| `featured = products.map(p => ({name: p.name, ...}))` — flat-mapping SDK results | Store raw products: `featured = featuredProducts ?? []` as `any[]` |
|
|
@@ -14,12 +14,14 @@ Files this agent MUST NOT touch:
|
|
|
14
14
|
- `src/components/ProductPurchase.tsx`, `src/components/AddToCartButton.tsx` — owned by `components`
|
|
15
15
|
- `src/pages/cart.astro`, `src/pages/thank-you.astro` — owned by `pages-cart-checkout`
|
|
16
16
|
- `src/pages/index.astro`, `src/components/Navigation.astro` — owned by `pages-home-and-nav`
|
|
17
|
+
- `src/components/CategoryRail.astro` — owned by `pages-categories`. **Import** from `../../components/CategoryRail.astro`; never `Write` it. If it's not on disk yet when you go to mount it, that means the orchestrator dispatched scopes out of order — return `status: "partial"` with `errors: [{ code: "MISSING_PAGES_CATEGORIES_OUTPUT", path: "src/components/CategoryRail.astro" }]` (never defensively `Write` it yourself — `pages-categories` is the only writer, and racing it trips the harness staleness guard).
|
|
18
|
+
- `src/utils/categories.ts` — pre-copied by the orchestrator before Phase 4 (BUILD.md Step 7 pre-batch). **Import** `listStoreCategories`/etc. from `../../utils/categories`; never `Write` it.
|
|
17
19
|
- `global.css`, any other `.astro` page, any other component — owned by designers
|
|
18
20
|
|
|
19
21
|
## Inputs (from parent prompt)
|
|
20
22
|
|
|
21
23
|
- **Phase 1 return data** — `products: [{id, name, slug, variantId, price, inventory, sku}]` — use slugs when needed (rarely; `queryProducts` returns them already).
|
|
22
|
-
- **Design tokens** —
|
|
24
|
+
- **Design tokens** — the full `designTokens` JSON is inlined in your prompt for the published color/spacing/typography vocabulary; compose Tailwind utilities derived from those tokens (`class="py-4xl flex flex-col gap-md font-display"`) at the call site rather than inventing semantic classes for layout/spacing/typography. Retained global semantic classes are limited to compound patterns (`offer-callout`, `cart-summary`), interactive primitives (`btn-primary`, `product-card`), and JS targets — see `references/shared/STYLING.md`.
|
|
23
25
|
- **Designer output summary** — paths of existing `products/index.astro`, `products/[slug].astro`, `ProductCard.astro` with placeholder data.
|
|
24
26
|
|
|
25
27
|
## Critical rules (all must be honored)
|
|
@@ -72,7 +74,7 @@ Preserves the designer's page structure (class names, layout) and replaces the p
|
|
|
72
74
|
|
|
73
75
|
> **Page size 24** — multiple of the 2/3/4-column grid, well under Wix's per-request cap of 100. Do not change without updating `CATEGORY_PAGES.md` to match.
|
|
74
76
|
|
|
75
|
-
> **No client-side filter.**
|
|
77
|
+
> **No client-side filter.** Do not ship every product and hide non-matching cards via JS — it doesn't scale and breaks SEO. Do not add `data-category-ids` on `<ProductCard>` or any DOM-hide script. Filtering is done by navigating to `/category/<slug>` (a real route), and `<ClientRouter />` from the designer's Layout handles the swap.
|
|
76
78
|
|
|
77
79
|
> **Why the double-script pattern:** Listing page is server-rendered but `AddProductImpression` must fire in the browser. The server-computed payload is serialized into an inert JSON `<script>` (`is:inline`) and read by a separate processed `<script>` (bundled by Astro — has ES `import`). `define:vars` + inline-script combinations cannot do ES imports.
|
|
78
80
|
|
|
@@ -210,4 +212,4 @@ If any of `wixMetadataExported`, `seoTagsMounted`, `useGetProductBySlug` ends up
|
|
|
210
212
|
| Pass `"INVENTORY"` in the `fields` array | No such enum value exists for `productsV3`. Valid values: `URL`, `CURRENCY`, `INFO_SECTION`, `MERCHANT_DATA`, `PLAIN_DESCRIPTION`, `INFO_SECTION_PLAIN_DESCRIPTION`, `SUBSCRIPTION_PRICES_INFO`, `BREADCRUMBS_INFO`, `WEIGHT_MEASUREMENT_UNIT_INFO`, `VARIANT_OPTION_CHOICE_NAMES`, `MEDIA_ITEMS_INFO`, `DESCRIPTION`, `DIRECT_CATEGORIES_INFO`, `ALL_CATEGORIES_INFO`, `INFO_SECTION_DESCRIPTION`, `THUMBNAIL`, `PRODUCT_CHOICES_MEDIA_REFERENCES`. Passing an invalid value makes the query throw. |
|
|
211
213
|
| Trust `variantsInfo[].inventoryStatus.inStock` as the OOS gate | It's a stale cached flag — a variant with real quantity 0 can still report `inStock: true`. Query `inventoryItemsV3.queryInventoryItems({ filter: { productId } })` at SSR and pass a `variantId → { quantity, trackQuantity, preorderEnabled }` map into `ProductPurchase`. The template already does this. |
|
|
212
214
|
| Skip the `backInStockEnabled` prop on `<ProductPurchase>` | Always pass it (template already imports `getBackInStockEnabled`). When the prop is missing, the OOS subscribe form never renders even if the merchant has enabled collecting requests. |
|
|
213
|
-
| Pass the formatted price string (`"$695"`) as `priceAmount` | Pass the numeric `priceAmount` already computed in frontmatter. The Wix back-in-stock service rejects formatted prices with `400 DECIMAL_GTE`. |
|
|
215
|
+
| Pass the formatted price string (`"$695"`) as `priceAmount` | Pass the numeric `priceAmount` already computed in frontmatter. The Wix back-in-stock service rejects formatted prices with `400 DECIMAL_GTE`. |
|
|
@@ -94,7 +94,7 @@ Handles variant selection, quantity selector, stock awareness, and wraps `AddToC
|
|
|
94
94
|
<ProductPurchase client:load product={product} inventoryByVariant={inventoryByVariant} />
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
**Prop contract — single `product` object.** The template accepts the full productsV3 product and destructures internally. This mirrors `ProductCard.astro`'s `{ product }` contract so both stores components take the same shape (prevents
|
|
97
|
+
**Prop contract — single `product` object.** The template accepts the full productsV3 product and destructures internally. This mirrors `ProductCard.astro`'s `{ product }` contract so both stores components take the same shape (prevents a shape mismatch where a fallback-written `[slug].astro` passes `product` as a whole while the component expects flat props).
|
|
98
98
|
|
|
99
99
|
Key behaviors:
|
|
100
100
|
- `hasMeaningfulOptions` — a product has meaningful options only when at least one option has >1 choice. Dummy single-choice options (e.g., "Type: Standard") are treated as no options.
|
|
@@ -159,6 +159,6 @@ Classes from contract (stores pack):
|
|
|
159
159
|
| Default Tailwind color utilities on React islands (`bg-green-50`, `bg-blue-500`) | Brand `@theme` utilities (`bg-bark`, `text-cream`) or contract class names |
|
|
160
160
|
| `<!--` HTML comments in `.astro` frontmatter | `//` or `/* */` — frontmatter is TypeScript |
|
|
161
161
|
| Omit `WIX_STORES_APP_ID` constant | Hardcoded `215238eb-22a5-4c36-9e7b-e7c08025e04e` in AddToCartButton for `catalogReference.appId` |
|
|
162
|
-
| Introspect `node_modules/@wix/*` | All symbols are documented here; if missing,
|
|
162
|
+
| Introspect `node_modules/@wix/*` | All symbols are documented here; if missing, use docs-search REST (see `DOCS_SEARCH.md`) |
|
|
163
163
|
| Write `CartView.tsx`, `CartBadge.tsx`, or `analytics.ts` | Not owned by this scope — do not write |
|
|
164
|
-
| Pass flat props to `ProductPurchase` (`productId`, `options`, `variantsInfo`, …) | Pass the whole product: `<ProductPurchase product={product} inventoryByVariant={inventoryByVariant} />` |
|
|
164
|
+
| Pass flat props to `ProductPurchase` (`productId`, `options`, `variantsInfo`, …) | Pass the whole product: `<ProductPurchase product={product} inventoryByVariant={inventoryByVariant} />` |
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
// ── Composer skeleton: src/components/Footer.astro ────────────────────────────
|
|
3
|
+
// Substitutions (see COMPOSE.md § "5. Footer.astro"):
|
|
4
|
+
// {{brand.name}} — brand name for the wordmark + copyright.
|
|
5
|
+
// {{shell.footerTagline}} — short brand-voice tagline from data.shell.
|
|
6
|
+
// {{nav.links}} — same inlined Navigation links array (mirror/subset);
|
|
7
|
+
// one <a href={href}>{label}</a> per entry, labels VERBATIM. No cart,
|
|
8
|
+
// login, or account links.
|
|
9
|
+
// Fixed bulk (keep literal): transition:persist, the year expression.
|
|
10
|
+
const year = new Date().getFullYear();
|
|
11
|
+
---
|
|
12
|
+
<footer class="site-footer" transition:persist="site-footer">
|
|
13
|
+
<div class="max-w-6xl mx-auto px-lg py-3xl flex flex-col md:flex-row md:items-start md:justify-between gap-xl">
|
|
14
|
+
<div class="flex flex-col gap-sm max-w-prose">
|
|
15
|
+
<span class="font-display text-lg text-ink">{{brand.name}}</span>
|
|
16
|
+
<p class="text-sm">{{shell.footerTagline}}</p>
|
|
17
|
+
</div>
|
|
18
|
+
<nav>
|
|
19
|
+
<ul class="flex flex-col gap-sm text-sm">
|
|
20
|
+
{{nav.links}}
|
|
21
|
+
</ul>
|
|
22
|
+
</nav>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="max-w-6xl mx-auto px-lg pb-xl text-xs">
|
|
25
|
+
<p>© {year} {{brand.name}}. All rights reserved.</p>
|
|
26
|
+
</div>
|
|
27
|
+
</footer>
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
// ── Composer skeleton: src/layouts/Layout.astro ──────────────────────────────
|
|
3
|
+
// Fully replaces the scaffold's bare stub. The <script> below and the View
|
|
4
|
+
// Transitions wiring are LITERAL fixed bulk — do not re-author. Composer's only
|
|
5
|
+
// substitutions (see COMPOSE.md § "3. Layout.astro"):
|
|
6
|
+
// {{components-css-imports}} — one `import '../styles/components-<pack>.css';`
|
|
7
|
+
// per pack in "Packs with components" (omit entirely when none).
|
|
8
|
+
// {{fonts.googleHref}} — the Google Fonts <link> href built from designTokens
|
|
9
|
+
// .fonts (display + body families). Omit the <link> if fonts are system.
|
|
10
|
+
// {{brand.name}} — default <title>.
|
|
11
|
+
import '../styles/global.css';
|
|
12
|
+
{{components-css-imports}}
|
|
13
|
+
import { ClientRouter } from 'astro:transitions';
|
|
14
|
+
import Navigation from '../components/Navigation.astro';
|
|
15
|
+
import Footer from '../components/Footer.astro';
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
title?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
hasSeoTags?: boolean;
|
|
21
|
+
}
|
|
22
|
+
const { title, description, hasSeoTags = false } = Astro.props;
|
|
23
|
+
---
|
|
24
|
+
<!doctype html>
|
|
25
|
+
<html lang="en">
|
|
26
|
+
<head>
|
|
27
|
+
<meta charset="utf-8" />
|
|
28
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
29
|
+
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E" />
|
|
30
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
31
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
32
|
+
<link rel="stylesheet" href="{{fonts.googleHref}}" />
|
|
33
|
+
{!hasSeoTags && (
|
|
34
|
+
<>
|
|
35
|
+
<title>{title ? `${title} · {{brand.name}}` : "{{brand.name}}"}</title>
|
|
36
|
+
{description && <meta name="description" content={description} />}
|
|
37
|
+
</>
|
|
38
|
+
)}
|
|
39
|
+
<slot name="head" />
|
|
40
|
+
<ClientRouter />
|
|
41
|
+
</head>
|
|
42
|
+
<body>
|
|
43
|
+
<div class="nav-progress" data-nav-progress aria-hidden="true"></div>
|
|
44
|
+
<Navigation />
|
|
45
|
+
<main><slot /></main>
|
|
46
|
+
<Footer />
|
|
47
|
+
<script>
|
|
48
|
+
// Persisted rail aria-current sync + top loading bar + rail-anchored
|
|
49
|
+
// scroll across listing-to-listing navigation. Stores pack relies on
|
|
50
|
+
// all three; do not split into separate scripts.
|
|
51
|
+
function syncCategoryRail() {
|
|
52
|
+
const path = window.location.pathname;
|
|
53
|
+
const activeSlug = path.startsWith("/category/")
|
|
54
|
+
? path.slice("/category/".length).replace(/\/$/, "")
|
|
55
|
+
: path === "/products" || path === "/products/"
|
|
56
|
+
? ""
|
|
57
|
+
: null;
|
|
58
|
+
if (activeSlug === null) return;
|
|
59
|
+
const pills = document.querySelectorAll<HTMLAnchorElement>(
|
|
60
|
+
"[data-category-rail] .category-pill",
|
|
61
|
+
);
|
|
62
|
+
for (const pill of pills) {
|
|
63
|
+
const slug = pill.dataset.categorySlug ?? "";
|
|
64
|
+
if (slug === activeSlug) pill.setAttribute("aria-current", "page");
|
|
65
|
+
else pill.removeAttribute("aria-current");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Eager click feedback — flip aria-current before the network call.
|
|
69
|
+
document.addEventListener("click", (event) => {
|
|
70
|
+
const target = event.target as HTMLElement | null;
|
|
71
|
+
const pill = target?.closest<HTMLAnchorElement>(
|
|
72
|
+
"[data-category-rail] .category-pill",
|
|
73
|
+
);
|
|
74
|
+
if (!pill) return;
|
|
75
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
76
|
+
const pills = document.querySelectorAll<HTMLAnchorElement>(
|
|
77
|
+
"[data-category-rail] .category-pill",
|
|
78
|
+
);
|
|
79
|
+
for (const p of pills) p.removeAttribute("aria-current");
|
|
80
|
+
pill.setAttribute("aria-current", "page");
|
|
81
|
+
}, true);
|
|
82
|
+
const progress = document.querySelector<HTMLElement>("[data-nav-progress]");
|
|
83
|
+
function startProgress() {
|
|
84
|
+
if (!progress) return;
|
|
85
|
+
progress.dataset.state = "loading";
|
|
86
|
+
document.body.dataset.navigating = "true";
|
|
87
|
+
}
|
|
88
|
+
function endProgress() {
|
|
89
|
+
if (!progress) return;
|
|
90
|
+
progress.dataset.state = "done";
|
|
91
|
+
delete document.body.dataset.navigating;
|
|
92
|
+
window.setTimeout(() => {
|
|
93
|
+
if (progress.dataset.state === "done") delete progress.dataset.state;
|
|
94
|
+
}, 320);
|
|
95
|
+
}
|
|
96
|
+
// Anchor the persisted rail across listing-to-listing navigation. The
|
|
97
|
+
// page-header above the rail differs between /products and /category/[slug]
|
|
98
|
+
// (breadcrumbs, lede, optional image), so naive scroll preservation reads
|
|
99
|
+
// as a jump. Capture rail.getBoundingClientRect().top before the swap and
|
|
100
|
+
// re-equalize after.
|
|
101
|
+
const isListing = (p: string) =>
|
|
102
|
+
p === "/products" || p === "/products/" || p.startsWith("/category/");
|
|
103
|
+
let railAnchorTop: number | null = null;
|
|
104
|
+
document.addEventListener("astro:before-preparation", (event: any) => {
|
|
105
|
+
const from = window.location.pathname;
|
|
106
|
+
const to = event?.to?.pathname ?? from;
|
|
107
|
+
const rail = document.querySelector<HTMLElement>("[data-category-rail]");
|
|
108
|
+
railAnchorTop =
|
|
109
|
+
rail && isListing(from) && isListing(to)
|
|
110
|
+
? rail.getBoundingClientRect().top
|
|
111
|
+
: null;
|
|
112
|
+
startProgress();
|
|
113
|
+
});
|
|
114
|
+
document.addEventListener("astro:after-swap", () => {
|
|
115
|
+
syncCategoryRail();
|
|
116
|
+
if (railAnchorTop !== null) {
|
|
117
|
+
const rail = document.querySelector<HTMLElement>("[data-category-rail]");
|
|
118
|
+
if (rail) {
|
|
119
|
+
const delta = rail.getBoundingClientRect().top - railAnchorTop;
|
|
120
|
+
if (Math.abs(delta) > 0.5) {
|
|
121
|
+
window.scrollBy({ top: delta, left: 0, behavior: "instant" as ScrollBehavior });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
railAnchorTop = null;
|
|
126
|
+
endProgress();
|
|
127
|
+
});
|
|
128
|
+
document.addEventListener("astro:page-load", endProgress);
|
|
129
|
+
syncCategoryRail();
|
|
130
|
+
</script>
|
|
131
|
+
</body>
|
|
132
|
+
</html>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
// ── Composer skeleton: src/components/Navigation.astro ────────────────────────
|
|
3
|
+
// Substitutions (see COMPOSE.md § "4. Navigation.astro"):
|
|
4
|
+
// {{shell.navBrandMark}} — brand mark / wordmark text from data.shell.
|
|
5
|
+
// {{nav.links}} — one <a href={href}>{label}</a> per entry in the inlined
|
|
6
|
+
// Navigation links array, labels VERBATIM (no editorial rebrands). Render
|
|
7
|
+
// each inside a <li class="site-nav-item">.
|
|
8
|
+
// Fixed bulk (keep literal): transition:persist, the <!-- nav:links --> marker,
|
|
9
|
+
// the empty <div class="nav-actions"> mount, the mobile hamburger toggle.
|
|
10
|
+
---
|
|
11
|
+
<header class="site-nav" transition:persist="site-nav">
|
|
12
|
+
<nav class="max-w-6xl mx-auto px-lg flex items-center justify-between gap-lg py-md">
|
|
13
|
+
<a href="/" class="font-display text-lg tracking-tight">{{shell.navBrandMark}}</a>
|
|
14
|
+
|
|
15
|
+
<input type="checkbox" id="nav-toggle" class="peer hidden" aria-hidden="true" />
|
|
16
|
+
<label
|
|
17
|
+
for="nav-toggle"
|
|
18
|
+
class="md:hidden inline-flex flex-col gap-[5px] cursor-pointer"
|
|
19
|
+
aria-label="Toggle navigation"
|
|
20
|
+
>
|
|
21
|
+
<span class="block h-[2px] w-6 bg-ink"></span>
|
|
22
|
+
<span class="block h-[2px] w-6 bg-ink"></span>
|
|
23
|
+
<span class="block h-[2px] w-6 bg-ink"></span>
|
|
24
|
+
</label>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
class="hidden peer-checked:flex md:flex absolute md:static top-full left-0 right-0 md:right-auto
|
|
28
|
+
flex-col md:flex-row gap-md md:gap-lg items-start md:items-center
|
|
29
|
+
bg-paper md:bg-transparent border-b md:border-0 border-rule px-lg md:px-0 py-md md:py-0"
|
|
30
|
+
>
|
|
31
|
+
<ul class="flex flex-col md:flex-row gap-md md:gap-lg items-start md:items-center">
|
|
32
|
+
{{nav.links}}
|
|
33
|
+
<!-- nav:links -->
|
|
34
|
+
</ul>
|
|
35
|
+
<div class="nav-actions"></div>
|
|
36
|
+
</div>
|
|
37
|
+
</nav>
|
|
38
|
+
</header>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// ── Composer skeleton: astro.config.mjs ───────────────────────────────────────
|
|
2
|
+
// UNLIKE the other skeletons, this one is a MERGE TARGET, not a clobber. The
|
|
3
|
+
// scaffold's generated astro.config.mjs varies (integrations args, image.domains,
|
|
4
|
+
// vite.server settings differ run to run). Composer must NOT overwrite it with
|
|
5
|
+
// this file — it applies exactly two mutations to the scaffold's own config and
|
|
6
|
+
// preserves everything else (see COMPOSE.md § "2. astro.config.mjs"):
|
|
7
|
+
//
|
|
8
|
+
// (1) register the Tailwind v4 Vite plugin → vite.plugins: [tailwindcss()]
|
|
9
|
+
// (2) fix the bare `process.env` reference → globalThis guard (TS-safe)
|
|
10
|
+
//
|
|
11
|
+
// The shape below is the canonical post-mutation result for a typical scaffold —
|
|
12
|
+
// use it as the reference for what those two edits should produce.
|
|
13
|
+
// @ts-check
|
|
14
|
+
import { defineConfig } from "astro/config";
|
|
15
|
+
import wix from "@wix/astro";
|
|
16
|
+
import wixPages from "@wix/astro-pages";
|
|
17
|
+
import react from "@astrojs/react";
|
|
18
|
+
import cloudProviderFetchAdapter from "@wix/cloud-provider-fetch-adapter";
|
|
19
|
+
import tailwindcss from "@tailwindcss/vite"; // (1) added by Composer
|
|
20
|
+
|
|
21
|
+
// (2) `process.env` guarded so strict `tsc --noEmit` does not fail with
|
|
22
|
+
// "Cannot find name 'process'" without an @types/node dependency.
|
|
23
|
+
const isBuild =
|
|
24
|
+
(/** @type {any} */ (globalThis)).process?.env?.NODE_ENV === "production";
|
|
25
|
+
|
|
26
|
+
// https://astro.build/config
|
|
27
|
+
export default defineConfig({
|
|
28
|
+
integrations: [wix(), wixPages(), react()],
|
|
29
|
+
security: { checkOrigin: false },
|
|
30
|
+
...(isBuild && { adapter: cloudProviderFetchAdapter({}) }),
|
|
31
|
+
|
|
32
|
+
image: {
|
|
33
|
+
domains: ["static.wixstatic.com"],
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
vite: {
|
|
37
|
+
plugins: [tailwindcss()], // (1) merge into any existing vite config
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
output: "server",
|
|
41
|
+
});
|