@salesforce/b2c-dx-mcp 3.2.1 → 3.4.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/bin/run.js +5 -9
- package/content/guidance/b2c/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +1 -1
- package/content/guidance/b2c/b2c-onboarding/SKILL.md +4 -4
- package/content/guidance/b2c/b2c-ordering/SKILL.md +2 -2
- package/content/guidance/b2c/b2c-querying-data/SKILL.md +2 -2
- package/content/guidance/b2c/b2c-scapi-admin/SKILL.md +3 -3
- package/content/guidance/b2c/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +4 -4
- package/content/guidance/b2c/b2c-scapi-shopper/SKILL.md +6 -6
- package/content/guidance/b2c/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +8 -9
- package/content/guidance/b2c-cli/b2c-cip/SKILL.md +3 -3
- package/content/guidance/b2c-cli/b2c-cip/references/SALES_ANALYSIS.md +1 -1
- package/content/guidance/b2c-cli/b2c-config/SKILL.md +54 -25
- package/content/guidance/b2c-cli/b2c-content/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-debug/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-docs/SKILL.md +23 -2
- package/content/guidance/b2c-cli/b2c-ecdn/SKILL.md +2 -0
- package/content/guidance/b2c-cli/b2c-ecdn/references/ADVANCED.md +1 -1
- package/content/guidance/b2c-cli/b2c-job/SKILL.md +9 -3
- package/content/guidance/b2c-cli/b2c-job/references/IMPORT.md +1 -1
- package/content/guidance/b2c-cli/b2c-job/references/RUN-AND-MONITOR.md +35 -6
- package/content/guidance/b2c-cli/b2c-metrics/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-mrt/SKILL.md +3 -3
- package/content/guidance/b2c-cli/b2c-scapi-custom/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-scapi-schemas/SKILL.md +6 -2
- package/content/guidance/b2c-cli/b2c-site-import-export/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-sites/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-slas/SKILL.md +1 -1
- package/content/guidance/b2c-ops/b2c-checkout-triage/SKILL.md +2 -2
- package/content/guidance/b2c-ops/b2c-edge-traffic-triage/SKILL.md +69 -0
- package/content/guidance/b2c-ops/b2c-job-health/SKILL.md +13 -8
- package/content/guidance/b2c-ops/b2c-order-failure-triage/SKILL.md +1 -1
- package/content/guidance/b2c-ops/b2c-order-failure-triage/references/order-evidence.md +2 -2
- package/content/guidance/b2c-ops/b2c-production-triage/SKILL.md +5 -4
- package/content/guidance/index.json +981 -259
- package/content/guidance/mcp/{cip → b2c-mcp-cip}/SKILL.md +10 -8
- package/content/guidance/mcp/{b2c-config → b2c-mcp-config}/SKILL.md +10 -9
- package/content/guidance/mcp/{debugger → b2c-mcp-debugger}/SKILL.md +9 -8
- package/content/guidance/mcp/b2c-mcp-scapi/SKILL.md +98 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/authentication.md +34 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/compose-verify.md +25 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/confirmation.md +30 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/discover.md +94 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/jobs.md +72 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/workflows.md +28 -0
- package/content/guidance/mcp/{server → b2c-mcp-server}/SKILL.md +52 -25
- package/content/guidance/storefront-next/sfnext-accessibility/SKILL.md +103 -0
- package/content/guidance/storefront-next/sfnext-accessibility/references/checklist.md +64 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/SKILL.md +91 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
- package/content/guidance/storefront-next/sfnext-authentication/SKILL.md +86 -79
- package/content/guidance/storefront-next/sfnext-authentication/references/COOKIES.md +39 -0
- package/content/guidance/storefront-next/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/SKILL.md +67 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
- package/content/guidance/storefront-next/sfnext-components/SKILL.md +98 -136
- package/content/guidance/storefront-next/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
- package/content/guidance/storefront-next/sfnext-components/references/SHAPE-TOKENS.md +51 -0
- package/content/guidance/storefront-next/sfnext-components/references/STORYBOOK.md +54 -0
- package/content/guidance/storefront-next/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
- package/content/guidance/storefront-next/sfnext-components/references/TROUBLESHOOTING.md +19 -0
- package/content/guidance/storefront-next/sfnext-configuration/SKILL.md +116 -113
- package/content/guidance/storefront-next/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
- package/content/guidance/storefront-next/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/SKILL.md +100 -150
- package/content/guidance/storefront-next/sfnext-data-fetching/references/ACTIONS.md +53 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADERS.md +73 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/SCAPI-FETCHER.md +23 -77
- package/content/guidance/storefront-next/sfnext-deployment/SKILL.md +83 -97
- package/content/guidance/storefront-next/sfnext-deployment/references/MRT-DEPLOYMENT.md +37 -68
- package/content/guidance/storefront-next/sfnext-extensions/SKILL.md +73 -97
- package/content/guidance/storefront-next/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/BASE-AUDIT.md +47 -44
- package/content/guidance/storefront-next/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/EXTENSION-EXAMPLES.md +49 -86
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/SKILL.md +59 -114
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +53 -90
- package/content/guidance/storefront-next/sfnext-i18n/SKILL.md +96 -131
- package/content/guidance/storefront-next/sfnext-i18n/references/locale-config.md +35 -0
- package/content/guidance/storefront-next/sfnext-overview/SKILL.md +101 -0
- package/content/guidance/storefront-next/sfnext-page-designer/SKILL.md +152 -131
- package/content/guidance/storefront-next/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/COMPONENT-REGISTRY.md +86 -53
- package/content/guidance/storefront-next/sfnext-page-designer/references/DECORATOR-PATTERNS.md +119 -131
- package/content/guidance/storefront-next/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
- package/content/guidance/storefront-next/sfnext-performance/SKILL.md +75 -105
- package/content/guidance/storefront-next/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
- package/content/guidance/storefront-next/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
- package/content/guidance/storefront-next/sfnext-project-setup/SKILL.md +103 -116
- package/content/guidance/storefront-next/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -99
- package/content/guidance/storefront-next/sfnext-project-setup/references/SCRIPTS.md +47 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/SKILL.md +70 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
- package/content/guidance/storefront-next/sfnext-revalidation/SKILL.md +121 -0
- package/content/guidance/storefront-next/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
- package/content/guidance/storefront-next/sfnext-routing/SKILL.md +86 -143
- package/content/guidance/storefront-next/sfnext-routing/references/ROUTE-CONVENTIONS.md +51 -51
- package/content/guidance/storefront-next/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
- package/content/guidance/storefront-next/sfnext-scapi/SKILL.md +126 -0
- package/content/guidance/storefront-next/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/SKILL.md +129 -0
- package/content/guidance/storefront-next/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/references/TURNSTILE.md +43 -0
- package/content/guidance/storefront-next/sfnext-seo/SKILL.md +95 -0
- package/content/guidance/storefront-next/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
- package/content/guidance/storefront-next/sfnext-seo/references/SEO-ROUTES.md +31 -0
- package/content/guidance/storefront-next/sfnext-state-management/SKILL.md +80 -89
- package/content/guidance/storefront-next/sfnext-state-management/references/PATTERNS.md +45 -0
- package/content/guidance/storefront-next/sfnext-testing/SKILL.md +105 -138
- package/content/guidance/storefront-next/sfnext-testing/references/E2E.md +38 -0
- package/content/guidance/storefront-next/sfnext-testing/references/STORYBOOK-PATTERNS.md +73 -94
- package/content/guidance/storefront-next/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
- package/content/guidance/storefront-next/sfnext-theming/SKILL.md +104 -0
- package/content/guidance/storefront-next/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
- package/dist/commands/mcp.d.ts +8 -2
- package/dist/commands/mcp.js +54 -20
- package/dist/guidance.d.ts +4 -1
- package/dist/guidance.js +23 -5
- package/dist/registry.d.ts +2 -1
- package/dist/registry.js +3 -3
- package/dist/server.d.ts +10 -0
- package/dist/server.js +21 -0
- package/dist/skill-references.js +5 -5
- package/dist/tools/cartridges/index.js +1 -0
- package/dist/tools/cip/index.js +6 -3
- package/dist/tools/diagnostics/debug-capture-at-breakpoint.js +1 -1
- package/dist/tools/diagnostics/debug-set-breakpoints.js +1 -1
- package/dist/tools/diagnostics/debug-start-session.js +1 -1
- package/dist/tools/docs/docs-read.js +4 -2
- package/dist/tools/docs/docs-search.js +10 -8
- package/dist/tools/docs/topics.d.ts +5 -0
- package/dist/tools/docs/topics.js +5 -0
- package/dist/tools/scapi/index.d.ts +4 -1
- package/dist/tools/scapi/index.js +4 -2
- package/dist/tools/scapi/scapi-code.d.ts +2 -2
- package/dist/tools/scapi/scapi-code.js +106 -81
- package/dist/tools/scapi/scapi-schemas-list.js +93 -56
- package/dist/utils/types.d.ts +6 -0
- package/node_modules/@salesforce/b2c-agent-plugins/CHANGELOG.md +32 -0
- package/node_modules/@salesforce/b2c-agent-plugins/README.md +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/.codex-plugin/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-onboarding/SKILL.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-ordering/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-querying-data/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-admin/SKILL.md +3 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-shopper/SKILL.md +6 -6
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +8 -9
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/.codex-plugin/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-cip/SKILL.md +3 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-cip/references/SALES_ANALYSIS.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-config/SKILL.md +54 -25
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-content/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-debug/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-docs/SKILL.md +23 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-ecdn/SKILL.md +2 -0
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-ecdn/references/ADVANCED.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/SKILL.md +9 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/references/IMPORT.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/references/RUN-AND-MONITOR.md +35 -6
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-metrics/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-mrt/SKILL.md +3 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-scapi-custom/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-scapi-schemas/SKILL.md +6 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-site-import-export/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-sites/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-slas/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/.codex-plugin/plugin.json +4 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/README.md +1 -0
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/plugin.json +4 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-checkout-triage/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-edge-traffic-triage/SKILL.md +69 -0
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-job-health/SKILL.md +13 -8
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-order-failure-triage/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-order-failure-triage/references/order-evidence.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-production-triage/SKILL.md +5 -4
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/README.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/SKILL.md +76 -73
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/evals/trigger-evals.json +12 -10
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/references/PAGE-DESIGNER-SFN.md +49 -74
- package/node_modules/@salesforce/b2c-agent-plugins/package.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/.codex-plugin/plugin.json +9 -6
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/README.md +43 -22
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/plugin.json +9 -6
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/SKILL.md +103 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/references/checklist.md +64 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/SKILL.md +91 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/SKILL.md +86 -79
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/references/COOKIES.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/SKILL.md +67 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/SKILL.md +98 -136
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/SHAPE-TOKENS.md +51 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/STORYBOOK.md +54 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/TROUBLESHOOTING.md +19 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/SKILL.md +116 -113
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/SKILL.md +100 -150
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/ACTIONS.md +53 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/LOADERS.md +73 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/SCAPI-FETCHER.md +23 -77
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/SKILL.md +83 -97
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/references/MRT-DEPLOYMENT.md +37 -68
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/SKILL.md +73 -97
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/BASE-AUDIT.md +47 -44
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/EXTENSION-EXAMPLES.md +49 -86
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/SKILL.md +59 -114
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +53 -90
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/SKILL.md +96 -131
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/references/locale-config.md +35 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-overview/SKILL.md +101 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-overview/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/SKILL.md +152 -131
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/COMPONENT-REGISTRY.md +86 -53
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/DECORATOR-PATTERNS.md +119 -131
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/SKILL.md +75 -105
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/SKILL.md +103 -116
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -99
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/SCRIPTS.md +47 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/SKILL.md +70 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/SKILL.md +121 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/SKILL.md +86 -143
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/references/ROUTE-CONVENTIONS.md +51 -51
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/SKILL.md +126 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/SKILL.md +129 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/references/TURNSTILE.md +43 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/SKILL.md +95 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/references/SEO-ROUTES.md +31 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/SKILL.md +80 -89
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/references/PATTERNS.md +45 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/SKILL.md +105 -138
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/E2E.md +38 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/STORYBOOK-PATTERNS.md +73 -94
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/SKILL.md +104 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next-figma/skills/sfnext-create-figma-kit/SKILL.md +3 -3
- package/oclif.manifest.json +21 -4
- package/package.json +4 -4
- package/content/guidance/mcp/scapi/SKILL.md +0 -203
- package/content/guidance/mcp/scapi/references/jobs.md +0 -30
- package/content/guidance/storefront-next/sfnext-create-component/SKILL.md +0 -195
- package/content/guidance/storefront-next/sfnext-create-component/references/COMPONENT-AUTHORING.md +0 -206
- package/content/guidance/storefront-next/sfnext-create-component/references/PROJECT-STRUCTURE.md +0 -43
- package/content/guidance/storefront-next/sfnext-create-component/references/TOKEN-SYSTEM.md +0 -130
- package/content/guidance/storefront-next/sfnext-create-component/references/TROUBLESHOOTING.md +0 -34
- package/content/guidance/storefront-next/sfnext-create-vertical/SKILL.md +0 -135
- package/content/guidance/storefront-next/sfnext-create-vertical/references/COMPONENT-AUTHORING.md +0 -206
- package/content/guidance/storefront-next/sfnext-create-vertical/references/PROJECT-STRUCTURE.md +0 -43
- package/content/guidance/storefront-next/sfnext-create-vertical/references/TOKEN-SYSTEM.md +0 -130
- package/content/guidance/storefront-next/sfnext-create-vertical/references/TROUBLESHOOTING.md +0 -34
- package/content/guidance/storefront-next/sfnext-custom-apis/SKILL.md +0 -221
- package/content/guidance/storefront-next/sfnext-custom-apis/references/WORKFLOW-EXAMPLES.md +0 -294
- package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADER-PATTERNS.md +0 -102
- package/content/guidance/storefront-next/sfnext-project-setup/references/ENV-VARIABLES.md +0 -82
- package/content/guidance/storefront-next/sfnext-scapi-management/SKILL.md +0 -203
- package/content/guidance/storefront-next/sfnext-scapi-management/references/CLI-COMMANDS.md +0 -122
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/SKILL.md +0 -195
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/COMPONENT-AUTHORING.md +0 -206
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/PROJECT-STRUCTURE.md +0 -43
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/TOKEN-SYSTEM.md +0 -130
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/TROUBLESHOOTING.md +0 -34
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/SKILL.md +0 -135
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/COMPONENT-AUTHORING.md +0 -206
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/PROJECT-STRUCTURE.md +0 -43
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/TOKEN-SYSTEM.md +0 -130
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/TROUBLESHOOTING.md +0 -34
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/SKILL.md +0 -221
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/references/WORKFLOW-EXAMPLES.md +0 -294
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/LOADER-PATTERNS.md +0 -102
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/ENV-VARIABLES.md +0 -82
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/SKILL.md +0 -203
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/references/CLI-COMMANDS.md +0 -122
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/custom-apis.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/custom-properties.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/products.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/promotions.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/saving.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/snippets.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/tokens.md +0 -0
- /package/content/guidance/mcp/{server → b2c-mcp-server}/references/files.md +0 -0
|
@@ -1,180 +1,168 @@
|
|
|
1
|
-
# Decorator Patterns
|
|
1
|
+
# Decorator Patterns
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Marks a class as a Page Designer component:
|
|
3
|
+
All four decorators are imported from your project, not from the runtime package:
|
|
6
4
|
|
|
7
5
|
```typescript
|
|
8
|
-
|
|
9
|
-
name: 'Display Name',
|
|
10
|
-
description: 'Component description for merchants'
|
|
11
|
-
})
|
|
12
|
-
class MyComponentMeta {
|
|
13
|
-
// attribute definitions...
|
|
14
|
-
}
|
|
6
|
+
import { AttributeDefinition, Component, PageType, RegionDefinition } from '@/lib/decorators';
|
|
15
7
|
```
|
|
16
8
|
|
|
17
|
-
- `
|
|
18
|
-
- `name` — Display name in Page Designer sidebar
|
|
19
|
-
- `description` — Merchant-facing description
|
|
9
|
+
Deep imports (`@/lib/decorators/component`, `.../attribute-definition`, `.../page-type`, `.../region-definition`) also work and are used by some shipped files.
|
|
20
10
|
|
|
21
|
-
|
|
11
|
+
Decorators only attach metadata. They are stripped of behavior at runtime and read at build time by `pnpm cartridge:generate` (and by the registry plugin for `@Component`). Mistakes therefore show up as a missing or broken editor in Business Manager, not as a runtime error.
|
|
22
12
|
|
|
23
|
-
|
|
13
|
+
## `@Component(typeId, options)`
|
|
24
14
|
|
|
25
15
|
```typescript
|
|
26
|
-
@
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
16
|
+
@Component('productCarousel', {
|
|
17
|
+
name: 'Product Carousel',
|
|
18
|
+
description: 'Scrollable row of product cards. Pick a category or add product tiles.',
|
|
19
|
+
group: 'Layout',
|
|
20
|
+
})
|
|
21
|
+
```
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
| Option | Meaning |
|
|
24
|
+
|--------|---------|
|
|
25
|
+
| `typeId` (first arg) | String literal, camelCase by convention (`hero`, `heroCarousel`, `megaMenu`). The registry plugin rejects non-literals. |
|
|
26
|
+
| `name`, `description` | Shown to merchants in the palette. Be specific about which attributes drive which behavior. |
|
|
27
|
+
| `group` | Palette folder. Default `storefrontnext_base`. Shipped components use `Content` and `Layout`. |
|
|
28
|
+
| `embedded`, `component_id` | Marks a singleton content block that is referenced rather than dropped into regions. The component preview route and `fetchComponentWithComponentData` use this path. |
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
showBadge: boolean;
|
|
30
|
+
The stored, fully-qualified id is `<group>.<typeId>` (`Layout.productCarousel`). That is the id that appears in SCAPI responses, in the registry, and in region include/exclude lists.
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
alignment: string;
|
|
32
|
+
## `@AttributeDefinition(config)`
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
featuredProduct: string;
|
|
34
|
+
Put it on a field of the exported metadata class. The field name is the prop name your component receives.
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
```typescript
|
|
37
|
+
@AttributeDefinition({
|
|
38
|
+
id: 'limit',
|
|
39
|
+
name: 'Product Limit',
|
|
40
|
+
description: 'Maximum number of products to show.',
|
|
41
|
+
type: 'integer',
|
|
42
|
+
required: false,
|
|
43
|
+
defaultValue: 12,
|
|
44
|
+
})
|
|
45
|
+
limit?: number;
|
|
46
|
+
```
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
| Option | Notes |
|
|
49
|
+
|--------|-------|
|
|
50
|
+
| `id` | Attribute id written to metadata. Keep it identical to the field name; a mismatch means merchant values never reach the prop. |
|
|
51
|
+
| `name`, `description` | Merchant-facing label and help text. Without them Business Manager shows the raw id. |
|
|
52
|
+
| `type` | One of the types below. Default is a string attribute. An unknown string (such as `'number'`) is not type-checked and produces a broken editor. |
|
|
53
|
+
| `required` | Match the component: `required: true` only if it cannot render without a value. |
|
|
54
|
+
| `defaultValue` | Prefilled in the editor. Keep it equal to the component's destructuring default so editor and runtime agree. For `enum` it must be one of `values`. |
|
|
55
|
+
| `values` | Required for `enum`: the option list. |
|
|
56
|
+
| `editorDefinition` | For `type: 'custom'`: `{ type, configuration? }` selecting a custom editor. |
|
|
57
|
+
| `searching` | `{ searchable, refinable, boostFactor?, sortable? }`. Makes the attribute searchable in Business Manager. Both booleans are required. |
|
|
58
|
+
| `dynamicLookup` | `{ aspectAttributeAlias }`. Sources the value from an aspect attribute at render time instead of a stored value. Allowed on all types. |
|
|
49
59
|
|
|
50
|
-
|
|
51
|
-
maxItems: number;
|
|
52
|
-
```
|
|
60
|
+
### Attribute types
|
|
53
61
|
|
|
54
|
-
|
|
62
|
+
`string`, `text`, `markup`, `integer`, `boolean`, `product`, `category`, `file`, `page`, `image`, `url`, `enum`, `custom`, `cms_record`.
|
|
55
63
|
|
|
56
|
-
| Type |
|
|
57
|
-
|
|
58
|
-
| `string` |
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `file` |
|
|
66
|
-
| `url` | URL input | URL string |
|
|
67
|
-
| `category` | Category selector | Category ID |
|
|
68
|
-
| `product` | Product selector | Product ID |
|
|
64
|
+
| Type | Value your component receives |
|
|
65
|
+
|------|-------------------------------|
|
|
66
|
+
| `string`, `text` | string (`text` is multi-line) |
|
|
67
|
+
| `markup` | raw HTML string; render with `dangerouslySetInnerHTML` only after deciding it is trusted content |
|
|
68
|
+
| `integer`, `boolean` | number, boolean |
|
|
69
|
+
| `enum` | one of `values` |
|
|
70
|
+
| `image` | object `{ url, focalPoint?, metaData? }` (`Image` from `@/types`) |
|
|
71
|
+
| `url` | string |
|
|
72
|
+
| `product`, `category` | the id (string); fetch details in a `loader` |
|
|
73
|
+
| `file`, `page`, `custom`, `cms_record` | reference values; check the generated JSON and a live SCAPI payload before relying on the shape |
|
|
69
74
|
|
|
70
|
-
###
|
|
75
|
+
### `searching` combinations
|
|
71
76
|
|
|
72
|
-
|
|
77
|
+
Generation fails (and `cartridge:validate` reports it) when the combination is invalid:
|
|
73
78
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
| `is*`, `show*`, `has*`, `enable*` | `boolean` |
|
|
79
|
-
| `*Count`, `*Num`, `max*`, `min*` | `integer` |
|
|
80
|
-
| Other | `string` |
|
|
79
|
+
- `string`, `text`, `product`, `category`: all fields allowed.
|
|
80
|
+
- `markup`: `sortable` must be omitted or `false`.
|
|
81
|
+
- `custom`, `cms_record`: `refinable` must be `false`; `boostFactor` and `sortable` are not allowed.
|
|
82
|
+
- `integer`, `boolean`, `file`, `page`, `image`, `url`, `enum`: searching is not allowed.
|
|
81
83
|
|
|
82
|
-
##
|
|
84
|
+
## `@RegionDefinition(regions)`
|
|
83
85
|
|
|
84
|
-
|
|
86
|
+
Declares the slots a component (or a page route) exposes to merchants.
|
|
85
87
|
|
|
86
88
|
```typescript
|
|
87
|
-
@Component('content-grid', { name: 'Content Grid', description: '2-column grid' })
|
|
88
89
|
@RegionDefinition([
|
|
89
90
|
{
|
|
90
|
-
id: '
|
|
91
|
-
name: '
|
|
92
|
-
description: '
|
|
93
|
-
maxComponents:
|
|
94
|
-
|
|
95
|
-
{
|
|
96
|
-
id: 'right',
|
|
97
|
-
name: 'Right Column',
|
|
98
|
-
description: 'Right content area',
|
|
99
|
-
maxComponents: 3,
|
|
91
|
+
id: 'products',
|
|
92
|
+
name: 'Products',
|
|
93
|
+
description: 'Add Product Tile components to populate this carousel.',
|
|
94
|
+
maxComponents: 12,
|
|
95
|
+
componentTypeInclusions: ['Content.productTile'],
|
|
100
96
|
},
|
|
101
97
|
])
|
|
102
|
-
class ContentGridMeta {
|
|
103
|
-
@AttributeDefinition({ type: 'boolean' })
|
|
104
|
-
equalWidth: boolean;
|
|
105
|
-
}
|
|
106
98
|
```
|
|
107
99
|
|
|
108
|
-
|
|
100
|
+
| Field | Notes |
|
|
101
|
+
|-------|-------|
|
|
102
|
+
| `id`, `name` | Required. The `id` must match the `regionId` passed to `<Region>`. |
|
|
103
|
+
| `description` | Shown to merchants. |
|
|
104
|
+
| `maxComponents` | Set only when the layout structurally limits children. |
|
|
105
|
+
| `componentTypeInclusions`, `componentTypeExclusions` | Allow-list / deny-list of component types. Unqualified ids are prefixed with the host component's group; refer to another group with the full id (`'Content.productTile'` from a `Layout.*` host). |
|
|
106
|
+
| `defaultComponentConstructors` | `[{ id, typeId, data }]` components created when a merchant adds the region to a new page. `typeId` follows the same qualification rule. |
|
|
107
|
+
|
|
108
|
+
Leaf components may use `@RegionDefinition([])` or omit the decorator. A declared region that the implementation never renders is invisible to shoppers even when merchants fill it.
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
## `@PageType(config)`
|
|
111
111
|
|
|
112
112
|
```typescript
|
|
113
113
|
@PageType({
|
|
114
|
-
name: '
|
|
115
|
-
description: '
|
|
116
|
-
supportedAspectTypes: ['
|
|
114
|
+
name: 'Product Detail Page',
|
|
115
|
+
description: 'Product detail page with promotional and engagement regions',
|
|
116
|
+
supportedAspectTypes: ['pdp'],
|
|
117
117
|
})
|
|
118
|
-
@RegionDefinition([
|
|
119
|
-
|
|
120
|
-
{ id: 'content', name: 'Main Content' },
|
|
121
|
-
])
|
|
118
|
+
@RegionDefinition([{ id: 'pdpPromo', name: 'Promo Content Region', maxComponents: 1 }])
|
|
119
|
+
export class ProductPageMetadata {}
|
|
122
120
|
```
|
|
123
121
|
|
|
124
|
-
|
|
122
|
+
| Field | Notes |
|
|
123
|
+
|-------|-------|
|
|
124
|
+
| `name`, `description` | Human-readable. `name` is the template label merchants pick. |
|
|
125
|
+
| `supportedAspectTypes` | `['pdp']`, `['plp']`, or `[]` for routes not bound to an aspect (home, about-us, component preview). Must agree with the `aspectType` the route loader fetches. |
|
|
126
|
+
| `preview` | Only `'default'` is valid. Used by the component preview route. |
|
|
125
127
|
|
|
126
|
-
|
|
127
|
-
import { Component, AttributeDefinition, RegionDefinition } from '@salesforce/storefront-next-runtime/design';
|
|
128
|
-
|
|
129
|
-
@Component('promo-banner', {
|
|
130
|
-
name: 'Promotional Banner',
|
|
131
|
-
description: 'Banner with background image, text overlay, and CTA'
|
|
132
|
-
})
|
|
133
|
-
class PromoBannerMeta {
|
|
134
|
-
@AttributeDefinition({ type: 'image' })
|
|
135
|
-
backgroundImage: string;
|
|
136
|
-
|
|
137
|
-
@AttributeDefinition()
|
|
138
|
-
headline: string;
|
|
128
|
+
The class must be exported and empty. Never put `@AttributeDefinition` on a page type.
|
|
139
129
|
|
|
140
|
-
|
|
141
|
-
subheadline: string;
|
|
130
|
+
`sfnext generate-cartridge` parses decorators statically, so decorator arguments must be literals, not imported constants.
|
|
142
131
|
|
|
143
|
-
|
|
144
|
-
ctaUrl: string;
|
|
132
|
+
## Nested regions in a container
|
|
145
133
|
|
|
146
|
-
|
|
147
|
-
|
|
134
|
+
```tsx
|
|
135
|
+
import { Region } from '@/components/region';
|
|
148
136
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
137
|
+
@Component('twoColumn', { name: 'Two Column', description: 'Two side-by-side regions.', group: 'Layout' })
|
|
138
|
+
@RegionDefinition([
|
|
139
|
+
{ id: 'left', name: 'Left' },
|
|
140
|
+
{ id: 'right', name: 'Right' },
|
|
141
|
+
])
|
|
142
|
+
export class TwoColumnMetadata {}
|
|
155
143
|
|
|
156
|
-
export default function
|
|
157
|
-
backgroundImage,
|
|
158
|
-
headline,
|
|
159
|
-
subheadline,
|
|
160
|
-
ctaUrl,
|
|
161
|
-
ctaLabel,
|
|
162
|
-
theme = 'light',
|
|
163
|
-
fullWidth,
|
|
164
|
-
}: PromoBannerProps) {
|
|
144
|
+
export default function TwoColumn({ component }: { component: ComponentType }) {
|
|
165
145
|
return (
|
|
166
|
-
<div className=
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
theme === 'dark' ? 'text-white' : 'text-gray-900'
|
|
170
|
-
)}>
|
|
171
|
-
<DynamicImage src={backgroundImage} alt="" className="absolute inset-0" />
|
|
172
|
-
<div className="relative z-10 p-8">
|
|
173
|
-
<h2 className="text-3xl font-bold">{headline}</h2>
|
|
174
|
-
{subheadline && <p className="mt-2">{subheadline}</p>}
|
|
175
|
-
{ctaUrl && <a href={ctaUrl} className="mt-4 inline-block">{ctaLabel}</a>}
|
|
176
|
-
</div>
|
|
146
|
+
<div className="grid grid-cols-2 gap-4">
|
|
147
|
+
<Region component={component} regionId="left" />
|
|
148
|
+
<Region component={component} regionId="right" />
|
|
177
149
|
</div>
|
|
178
150
|
);
|
|
179
151
|
}
|
|
180
152
|
```
|
|
153
|
+
|
|
154
|
+
`ComponentType` is exported from `@/components/region`. Use `className` on `<Region>` for layout; the design-mode wrapper uses `display: contents`, so children stay direct grid/flex items. `src/components/grid/index.tsx` is the reference implementation.
|
|
155
|
+
|
|
156
|
+
## Images
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
import { DynamicImage } from '@/components/dynamic-image';
|
|
160
|
+
|
|
161
|
+
<DynamicImage src={image.url} alt="" />
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Always provide `alt` (empty for decorative images). Set `priority="high"` only on the LCP image, never on every image.
|
|
165
|
+
|
|
166
|
+
## Text that is not merchant content
|
|
167
|
+
|
|
168
|
+
Button labels and fallback messages that developers (not merchants) own should use `useTranslation()`. Text in attributes is edited and localized by merchants in Business Manager, so leave it raw.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Review Checklist
|
|
2
|
+
|
|
3
|
+
Use when reviewing or self-checking a Page Designer component (`@Component`) or page route (`@PageType`). Read-only: report findings with `file:line`, say why each matters, and group them as Bugs (break at runtime or in Business Manager), Conventions (drift from the rest of your project) and Polish.
|
|
4
|
+
|
|
5
|
+
A file is in scope if it uses `@Component` or `@PageType`, or is listed in `src/lib/page-designer/static-registry.ts`. Components use sections 1-4; page routes use sections 1 (page type part), 3 (region rendering) and 5.
|
|
6
|
+
|
|
7
|
+
## 1. Metadata
|
|
8
|
+
|
|
9
|
+
**`@Component`**
|
|
10
|
+
- `typeId` is a literal that matches the registry suffix (`Content.hero` -> `'hero'`). A mismatch means the component never resolves.
|
|
11
|
+
- `name` is human-readable and differs from `typeId`; `description` says which attributes drive which behavior.
|
|
12
|
+
- `group` is set (`Content` or `Layout`) rather than defaulting to `storefrontnext_base`.
|
|
13
|
+
- The metadata class is `export`ed.
|
|
14
|
+
|
|
15
|
+
**`@AttributeDefinition`** (every merchant-configurable prop needs one)
|
|
16
|
+
- `type` is one of the valid types (`integer`, not `number`). An invalid string is not caught by TypeScript.
|
|
17
|
+
- `enum` has `values`, and its `defaultValue` is one of them.
|
|
18
|
+
- `image` props are typed as the `Image` object (`image.url`), not `string`.
|
|
19
|
+
- `id` equals the field name; a mismatch means merchant values never reach the prop.
|
|
20
|
+
- `required` matches the component: a prop with a destructuring default should be `required: false`; a prop that crashes on `undefined` should be `true`.
|
|
21
|
+
- `defaultValue` equals the component's destructuring default (otherwise the editor pre-fills one value and runtime falls back to another).
|
|
22
|
+
- `name` and `description` present.
|
|
23
|
+
|
|
24
|
+
**`@RegionDefinition`**
|
|
25
|
+
- Every declared region id is rendered by a matching `<Region regionId>`, and every rendered id is declared.
|
|
26
|
+
- `componentTypeInclusions`/`Exclusions` are fully qualified when they cross groups (`'Content.productTile'` from a `Layout.*` host); unqualified ids take the host's group.
|
|
27
|
+
- `maxComponents` only where the layout limits children.
|
|
28
|
+
- `@RegionDefinition([])` or no decorator on a leaf is fine.
|
|
29
|
+
|
|
30
|
+
**`@PageType`** (routes)
|
|
31
|
+
- Exported, empty class with `name`, `description`, `supportedAspectTypes`. `[]` is valid for fixed-page routes.
|
|
32
|
+
- `supportedAspectTypes` agrees with the loader's `aspectType`. Flag a loader aspect not in the list, a listed aspect the loader never fetches, and aspect ids that do not fit the aspect (for example `productId` with a category aspect). This is the most valuable cross-file check: Business Manager shows the wrong template with no error.
|
|
33
|
+
- No `@AttributeDefinition` on page types.
|
|
34
|
+
|
|
35
|
+
## 2. Module contract (components)
|
|
36
|
+
|
|
37
|
+
- Default export is the component.
|
|
38
|
+
- Named `fallback` export exists, is light (no `useState`/`useEffect`, no fetching, nothing that suspends), uses the same attribute props, and reserves dimensions.
|
|
39
|
+
- Skeletons live in `fallback`, not in the main component.
|
|
40
|
+
- A `loader` export is a function with the `{ componentData, context, request }` signature; the registry has `{ loader: 'loader' }` (regenerate if not); attributes are read from `componentData.data`; `null` is returned for "nothing configured"; independent fetches use `Promise.all`; errors are not swallowed.
|
|
41
|
+
- Server-only imports (`*.server.ts`) appear only in loader files, never in the component body.
|
|
42
|
+
|
|
43
|
+
## 3. Rendering
|
|
44
|
+
|
|
45
|
+
- Injected props (`component`, `data`, `designMetadata`, `regionId`, and rarely `componentData`) are destructured out before any `...rest` spread onto a DOM element. Unused ones are prefixed with `_`.
|
|
46
|
+
- Nested regions use component mode: `<Region component={component} regionId="x" />`, with no `page` prop, no `fallbackElement`, no Suspense wrapper, no promises.
|
|
47
|
+
- Route regions use page mode: `<Region page={loaderData.page} regionId="x" />`. `critical` only on above-the-fold regions with an awaited page and no local `fallbackElement`.
|
|
48
|
+
- Instance-specific `<style>` output is scoped (for example with `useId()`); unscoped CSS collides when two instances share a page.
|
|
49
|
+
- Images: `Image` object, `DynamicImage` for responsive widths, `alt` always present (empty for decorative), `priority="high"` only on LCP candidates.
|
|
50
|
+
- No `'use client'` directives; this is React Router, not React Server Components.
|
|
51
|
+
- Developer-owned strings go through `useTranslation()`; merchant attribute text stays raw.
|
|
52
|
+
- `memo` only on components with stable props.
|
|
53
|
+
|
|
54
|
+
## 4. Anti-patterns
|
|
55
|
+
|
|
56
|
+
1. `errorElement` on a `<Region>` used to render hard-coded content for an unconfigured page.
|
|
57
|
+
2. A loader fetching data that only an `errorElement` uses.
|
|
58
|
+
3. Skeleton markup inside the main component.
|
|
59
|
+
4. `fetchPriority="high"` on every image.
|
|
60
|
+
5. An `@Component` that is not in `static-registry.ts` (registry not regenerated, or file outside `src/components`).
|
|
61
|
+
|
|
62
|
+
## 5. Do not flag
|
|
63
|
+
|
|
64
|
+
- `@PageType` with `supportedAspectTypes: []` on fixed-page routes.
|
|
65
|
+
- `@RegionDefinition([])` on leaves, or an omitted decorator on a leaf.
|
|
66
|
+
- Missing comments that justify valid choices.
|
|
67
|
+
- Formatting and import-order nits the linter already enforces.
|
|
68
|
+
|
|
69
|
+
## Report format
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
## Bugs
|
|
73
|
+
1. `src/components/foo/index.tsx:42` - Page Designer props leak to the DOM.
|
|
74
|
+
`designMetadata` and `component` are not destructured before `...rest` reaches a <div>; React warns in dev and emits `designmetadata="[object Object]"` in production.
|
|
75
|
+
|
|
76
|
+
## Conventions
|
|
77
|
+
2. `src/components/foo/index.tsx:18` - `@Component` has no `group`; peers use 'Content' or 'Layout'.
|
|
78
|
+
|
|
79
|
+
## Polish
|
|
80
|
+
3. `src/components/foo/index.tsx:25` - Description is generic.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
End with a one-line count per severity. A clean review should say so explicitly.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Troubleshooting Page Designer
|
|
2
|
+
|
|
3
|
+
Start with the command loop: `pnpm cartridge:generate`, `pnpm cartridge:validate`, `pnpm cartridge:deploy`, then hard-refresh Business Manager. Most "it does not show up" problems are one of these not having run against the right instance and code version.
|
|
4
|
+
|
|
5
|
+
| Symptom | Likely cause | Fix |
|
|
6
|
+
|---------|--------------|-----|
|
|
7
|
+
| Component absent from the Business Manager palette | Cartridge not regenerated or not deployed; deployed to a code version the site does not use; cartridge not on the site's path; metadata class not `export`ed | Export the class, run generate, validate and deploy, confirm the active code version, hard-refresh |
|
|
8
|
+
| `cartridge:generate` or `validate` fails | Invalid `searching` combination; unknown attribute `type`; non-literal decorator argument; `enum` without `values` | Fix the decorator; generation parses decorators statically, so use literals |
|
|
9
|
+
| Component is in the palette but renders nothing | `typeId` or `group` differs from the registry entry (`Content.hero` vs `Layout.hero`); registry stale; missing default export | Compare the decorator with `src/lib/page-designer/static-registry.ts`; restart `pnpm dev` or `pnpm build` |
|
|
10
|
+
| Component not in `static-registry.ts` | File outside `src/components`, or `@Component` typeId is not a string literal | Move it or make it a literal; restart the dev server |
|
|
11
|
+
| Page is empty on the storefront | No published page for that `pageId` or aspect assignment; wrong `pageId` in the loader; loader fetched a different aspect than the template | Check the page in Business Manager; `fetchPageWithComponentData` returns `null` on 404/API error |
|
|
12
|
+
| Wrong template offered for products or categories | `supportedAspectTypes` disagrees with the loader's `aspectType` | Make them agree (`['pdp']`/`'pdp'`, `['plp']`/`'plp'`) |
|
|
13
|
+
| Region shows nothing though merchants filled it | `<Region regionId>` not matching the `@RegionDefinition` id; region declared but never rendered | Cross-check ids in both directions |
|
|
14
|
+
| `data` prop is `undefined` | Exported `loader` is an object (`{ server }`) not a function; registry lacks `{ loader: 'loader' }`; loader reads attributes from the wrong place | `export const loader = loaders.server`; read `componentData.data.<attr>`; regenerate the registry |
|
|
15
|
+
| Loader data for an attribute is `undefined` | Attribute `id` differs from the field name; attribute not declared on the metadata class | Align `id` and field name |
|
|
16
|
+
| Image attribute crashes or shows nothing | Treated as a string | It is an object: use `image.url` and `image.focalPoint` |
|
|
17
|
+
| `markup` attribute shows literal tags | Rendered as text | Render as HTML only if the content is trusted |
|
|
18
|
+
| Blank space then content pops in (layout shift) | `fallback` missing or height-less | Export a `fallback` that reserves the final height |
|
|
19
|
+
| Suspense never resolves / whole region blank | `fallback` suspends (hooks, fetching); `critical` region given an unresolved page | Keep `fallback` synchronous; `await` the page for critical regions |
|
|
20
|
+
| React warns about `designMetadata`/`component` props on a DOM element | Spreading `...rest` onto a DOM element | Destructure the injected props (`component`, `data`, `designMetadata`, `regionId`) out before spreading |
|
|
21
|
+
| TypeScript error on `<Region>` | Mixed `page` and `component` props, or `fallbackElement` on a component-mode region | Use page mode at route level and component mode for nested regions, never both |
|
|
22
|
+
| Nested region empty | Page mode used inside a component, or `component` prop missing | `<Region component={component} regionId="..." />` |
|
|
23
|
+
| Design mode links navigate away | `PageDesignerInit` removed from `root.tsx` | Restore it |
|
|
24
|
+
| Edits in Business Manager not reflected on the storefront | Editing a different instance than the storefront reads; cached page | Check the environment and site; see `storefront-next:sfnext-revalidation` for caching |
|
|
25
|
+
|
|
26
|
+
## Debugging tips
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pnpm cartridge:generate # regenerate metadata; errors name the offending decorator
|
|
30
|
+
pnpm cartridge:validate # schema-check the generated JSON
|
|
31
|
+
grep -n "Content.hero" src/lib/page-designer/static-registry.ts # is the component registered?
|
|
32
|
+
ls cartridges/app_storefrontnext_base/cartridge/experience/components # is the metadata there?
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Deploy problems (auth, WebDAV, code version) are not Page Designer problems; use `b2c-cli:b2c-code` and `b2c-cli:b2c-webdav`, and rerun with `--log-level trace`.
|
|
@@ -1,132 +1,102 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sfnext-performance
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
Keep a Storefront Next storefront fast and self-review changes for performance: LCP, CLS and TBT, Suspense placement and granularity, stable promise identity, lazy-loaded modals and drawers with useDeferredUnmount, useDeferredRender, Region critical, DynamicImage and image priority, font loading, resource hints (links.preconnect), bundle size checks (pnpm bundlesize, BUNDLES_SIZE_ANALYZE), Lighthouse CI, and the performance.metrics / Server-Timing flags. Use for "page is slow", "LCP regression", "skeleton flashes", "bundle too big", "review my diff for performance", "hydration mismatch or extra re-renders", "waterfall of fetches", or before merging feature work that adds loaders, fetchers, modals and drawers or images. Do not use for loader/action mechanics (use `storefront-next:sfnext-data-fetching`), revalidation policy (use `storefront-next:sfnext-revalidation`), or accessibility (use `storefront-next:sfnext-accessibility`).
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
# Performance
|
|
7
|
-
|
|
8
|
-
This skill
|
|
9
|
-
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
7
|
+
# Storefront Next Performance
|
|
8
|
+
|
|
9
|
+
Performance rules are part of `AGENTS.md` ("Performance & Data Rules") and detailed in `docs/README-PERFORMANCE.md`, `docs/README-SUSPENSE.md`, `docs/README-IMAGES.md` and `docs/README-PERFORMANCE-METRICS.md` in your project. This skill is the working summary plus a checklist to run on your own diff: [PERFORMANCE-REVIEW-CHECKLIST.md](references/PERFORMANCE-REVIEW-CHECKLIST.md).
|
|
10
|
+
|
|
11
|
+
## Core rules
|
|
12
|
+
|
|
13
|
+
1. Server-load data. Await only what SEO, LCP, layout or the HTTP status needs; return promises for the rest (see `storefront-next:sfnext-data-fetching`).
|
|
14
|
+
2. One `<Suspense>` per async operation, with a skeleton that reserves the final size. No `fallback={null}` above the fold unless space is reserved.
|
|
15
|
+
3. Promise identity must be stable across renders: compose in the loader, read from `loaderData`/props, never `Promise.all`/`.then`/`new Promise` in render, never `useMemo` around a promise. Escape hatches: `useState(() => ...)` pinning or `useRef` re-pinning.
|
|
16
|
+
4. Every `use()`/`<Await>` consumer needs a `<Suspense>` ancestor; otherwise it blocks the first byte of the streamed shell.
|
|
17
|
+
5. Heavy or hidden UI (modals, drawers, dialogs, rich editors) is `React.lazy` and mounted only while needed.
|
|
18
|
+
6. Shape data in the loader, not in render.
|
|
19
|
+
7. Hints and third-party scripts cost: preconnect only to origins used on every page; load scripts `async`/`defer`.
|
|
20
|
+
|
|
21
|
+
## Lazy modals and drawers
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { lazy, Suspense, useState } from 'react';
|
|
25
|
+
import { useDeferredUnmount } from '@/hooks/use-deferred-unmount';
|
|
26
|
+
|
|
27
|
+
const SizeGuide = lazy(() => import('@/components/size-guide').then((m) => ({ default: m.SizeGuide })));
|
|
28
|
+
|
|
29
|
+
export function SizeGuideButton() {
|
|
30
|
+
const [open, setOpen] = useState(false);
|
|
31
|
+
const mounted = useDeferredUnmount(open); // stays mounted briefly after close for the exit animation
|
|
32
|
+
return (
|
|
33
|
+
<>
|
|
34
|
+
<button onClick={() => setOpen(true)}>Size guide</button>
|
|
35
|
+
{mounted && (
|
|
36
|
+
<Suspense fallback={null}>
|
|
37
|
+
<SizeGuide open={open} onOpenChange={setOpen} />
|
|
38
|
+
</Suspense>
|
|
39
|
+
)}
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
32
42
|
}
|
|
33
43
|
```
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
- SSR operations and rendering time
|
|
37
|
-
- SCAPI API calls with parallelization visibility
|
|
38
|
-
- Authentication operations
|
|
39
|
-
- Client-side navigation timing
|
|
40
|
-
|
|
41
|
-
## Parallel Data Fetching
|
|
42
|
-
|
|
43
|
-
Return all promises simultaneously in loaders — avoid sequential `await`:
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
// GOOD — Parallel (all requests start at once)
|
|
47
|
-
export function loader({ context }: LoaderFunctionArgs) {
|
|
48
|
-
const clients = createApiClients(context);
|
|
49
|
-
return {
|
|
50
|
-
product: clients.shopperProducts.getProduct({...}),
|
|
51
|
-
reviews: clients.shopperProducts.getReviews({...}),
|
|
52
|
-
recommendations: clients.shopperProducts.getRecommendations({...}),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
45
|
+
Avoid a sticky "loaded" latch (a state that flips true on first open and never resets): fetchers inside the modal stay registered and re-run on every later revalidation. See `src/components/product-tile/quick-add-button.tsx`.
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
export async function loader({ context }: LoaderFunctionArgs) {
|
|
58
|
-
const product = await clients.shopperProducts.getProduct({...});
|
|
59
|
-
const reviews = await clients.shopperProducts.getReviews({...});
|
|
60
|
-
return { product, reviews };
|
|
61
|
-
}
|
|
62
|
-
```
|
|
47
|
+
## Deferred rendering
|
|
63
48
|
|
|
64
|
-
|
|
49
|
+
`useDeferredRender(enabled, options)` (`@/hooks/use-deferred-render`) delays mounting a Suspense boundary until an idle frame; use it for large below-the-fold grids. `DeferredProductGrid` (`@/components/product-grid/deferred`) is the reference. `useDeferredRenderSequence(n)` fans out work one step per idle frame.
|
|
65
50
|
|
|
66
|
-
|
|
51
|
+
## Page Designer
|
|
67
52
|
|
|
68
|
-
|
|
69
|
-
import { DynamicImage } from '@/components/dynamic-image';
|
|
53
|
+
Mark a region `<Region critical>` only when it is required for the initial HTML or is an LCP candidate, and `await` that page in the loader (omit a region fallback). Below-the-fold regions stay streamed. See `storefront-next:sfnext-page-designer`.
|
|
70
54
|
|
|
71
|
-
|
|
72
|
-
src={product.image.link}
|
|
73
|
-
alt={product.image.alt}
|
|
74
|
-
width={400}
|
|
75
|
-
height={400}
|
|
76
|
-
format="webp"
|
|
77
|
-
/>
|
|
78
|
-
```
|
|
55
|
+
## Images, fonts, hints
|
|
79
56
|
|
|
80
|
-
|
|
57
|
+
- Images: use `DynamicImage` (`@/components/dynamic-image`). Props: `src`, `alt`, `widths`, `heights`, `imageProps`, `as`, `className`, `loading`, `priority`, `objectFit`. Give the LCP image `priority="high"` (React 19 preload) and never lazy-load it. Provide `widths` matching the layout, or wrap a group in `DynamicImageProvider` (`@/providers/dynamic-image`, `value={{ widths }}`). URL helpers are in `docs/README-IMAGES.md`.
|
|
58
|
+
- Fonts: the template self-hosts `public/fonts/sen-variable.woff2`, preloads it in `src/root.tsx` `links`, and declares `@font-face` with `font-display: swap` in `src/theme/base.css`. Keep fonts same-origin, preload only the one above-the-fold face, and consider system fonts for secondary text.
|
|
59
|
+
- Resource hints: configure `app.links.preconnect`, `prefetchDns`, `prefetch` in `config.server.ts` or via `PUBLIC__app__links__preconnect='["https://cdn.example.com"]'`. Default preconnects to the image host only.
|
|
81
60
|
|
|
82
|
-
|
|
83
|
-
- Set explicit `width` and `height` to prevent layout shifts
|
|
84
|
-
- Lazy load below-the-fold images
|
|
85
|
-
- Use SCAPI image alt text as the primary alt source
|
|
61
|
+
## Measure
|
|
86
62
|
|
|
87
|
-
|
|
63
|
+
| Task | Command |
|
|
64
|
+
|---|---|
|
|
65
|
+
| Check bundle size limits (block CI) | `pnpm bundlesize` |
|
|
66
|
+
| Interactive treemaps (`build/client-bundle-size.html`, `build/ssr-bundle-size.html`) | `cross-env BUNDLES_SIZE_ANALYZE=true pnpm build` |
|
|
67
|
+
| Compare size runs | `pnpm bundlesize:compare` |
|
|
68
|
+
| Lighthouse | `pnpm lighthouse:ci` |
|
|
69
|
+
| Request timings | `performance.metrics` flags in `config.server.ts` |
|
|
88
70
|
|
|
89
|
-
|
|
71
|
+
The limits live in the `bundlesize` block of `package.json`. If a legitimate change exceeds a limit, state the reason and raise it deliberately; do not use `manualChunks` to bucket components.
|
|
90
72
|
|
|
91
|
-
|
|
92
|
-
// Streams data as each promise resolves
|
|
93
|
-
export function loader({ context }: LoaderFunctionArgs) {
|
|
94
|
-
const clients = createApiClients(context);
|
|
95
|
-
return {
|
|
96
|
-
product: clients.shopperProducts.getProduct({...}), // Streams independently
|
|
97
|
-
reviews: clients.shopperProducts.getReviews({...}), // Streams independently
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
```
|
|
73
|
+
`performance.metrics` (`serverPerformanceMetricsEnabled`, `serverTimingHeaderEnabled`, `clientPerformanceMetricsEnabled`) are all `false` in the shipped `config.server.ts`; `docs/README-PERFORMANCE-METRICS.md` lists two of them as defaulting to `true`, but the shipped config wins. Enable them only while debugging, because `serverTimingHeaderEnabled` adds a `Server-Timing` header and costs response time. Override via `PUBLIC__app__...` environment variables (`storefront-next:sfnext-configuration`).
|
|
101
74
|
|
|
102
|
-
|
|
75
|
+
## Review workflow
|
|
103
76
|
|
|
104
|
-
|
|
77
|
+
1. Run the checklist on your diff (fetch topology, Suspense, promise stability, hydration, revalidation scope, client transforms).
|
|
78
|
+
2. `pnpm typecheck`, `pnpm lint`, `pnpm test`.
|
|
79
|
+
3. `pnpm bundlesize` when you add dependencies or routes.
|
|
80
|
+
4. Load the page with network throttling and CPU slowdown; confirm no layout shift when streamed sections resolve and that server HTML contains the LCP element.
|
|
105
81
|
|
|
106
|
-
|
|
82
|
+
Impact rule of thumb: traffic of the page x number of instances on it x cost per instance. A fetch in a product tile is multiplied by every tile.
|
|
107
83
|
|
|
108
|
-
|
|
109
|
-
pnpm lighthouse:ci # Run Lighthouse CI
|
|
110
|
-
```
|
|
84
|
+
## References
|
|
111
85
|
|
|
112
|
-
|
|
113
|
-
-
|
|
114
|
-
- Use WebP images by default
|
|
115
|
-
- Lazy load below-the-fold content
|
|
116
|
-
- Optimize font loading
|
|
117
|
-
- Minimize JavaScript bundle size
|
|
86
|
+
- [PERFORMANCE-REVIEW-CHECKLIST.md](references/PERFORMANCE-REVIEW-CHECKLIST.md) - self-review checklist with rules, bad/good forms and exceptions
|
|
87
|
+
- [SUSPENSE-AND-STREAMING.md](references/SUSPENSE-AND-STREAMING.md) - placement, granularity, promise stability recipes
|
|
118
88
|
|
|
119
|
-
##
|
|
89
|
+
## Finding more
|
|
120
90
|
|
|
121
|
-
|
|
122
|
-
|-------|-------|----------|
|
|
123
|
-
| Large bundle size | Unused imports or heavy dependencies | Run `bundlesize:analyze`; tree-shake or lazy load |
|
|
124
|
-
| Slow page transitions | Async loaders blocking | Use synchronous loaders returning promises |
|
|
125
|
-
| Layout shifts | Missing image dimensions | Set `width` and `height` on images |
|
|
126
|
-
| Slow SCAPI responses | Sequential API calls | Use parallel data fetching |
|
|
91
|
+
`AGENTS.md` "Key Documentation" and `docs/README-PERFORMANCE.md`. `b2c docs search "storefront next performance"` or `docs_search` MCP tool.
|
|
127
92
|
|
|
128
93
|
## Related Skills
|
|
129
94
|
|
|
130
|
-
- `storefront-next:sfnext-data-fetching` -
|
|
131
|
-
- `storefront-next:sfnext-
|
|
132
|
-
- `storefront-next:sfnext-
|
|
95
|
+
- `storefront-next:sfnext-data-fetching` - loaders, streaming
|
|
96
|
+
- `storefront-next:sfnext-revalidation` - cutting wasted loader re-runs
|
|
97
|
+
- `storefront-next:sfnext-state-management` - render scope and stores
|
|
98
|
+
- `storefront-next:sfnext-components` - component conventions
|
|
99
|
+
- `storefront-next:sfnext-page-designer` - critical regions
|
|
100
|
+
- `storefront-next:sfnext-quality-gates` - lint, typecheck, tests before merge
|
|
101
|
+
- `storefront-next:sfnext-deployment` - bundle and MRT limits
|
|
102
|
+
- `b2c-cli:b2c-mrt` - Managed Runtime logs and deploys
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
[
|
|
2
|
+
{"query": "My Storefront Next product page LCP got worse after I added a reviews section; help me review my changes for performance", "should_trigger": true},
|
|
3
|
+
{"query": "How do I lazy load a modal and avoid shipping it in the main bundle in my storefront?", "should_trigger": true},
|
|
4
|
+
{"query": "Add alt text and keyboard focus handling to the image carousel", "should_trigger": false}
|
|
5
|
+
]
|