@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,181 +1,202 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sfnext-page-designer
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
Build merchant-editable Page Designer content in a Storefront Next project: components decorated with @Component/@AttributeDefinition/@RegionDefinition, page routes decorated with @PageType, <Region> rendering, fetchPageWithComponentData, component loaders and fallbacks, the generated static registry, and the pnpm cartridge:generate / cartridge:validate / cartridge:deploy workflow. Use when adding or editing a Page Designer component, exposing a region on a route (home, PDP, PLP, search), fetching a page by pageId or aspectType, marking a Region critical, debugging a component that does not appear in the Business Manager palette or renders empty, or reviewing Page Designer code. Do not use for classic ISML/SFRA Page Designer (use `b2c:b2c-page-designer`), for turning a Figma frame into blocks (use `figma-to-sfnext-pagedesigner:figma-to-sfnext-pagedesigner`), or for plain React components that merchants never edit (use `storefront-next:sfnext-components`).
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
# Page Designer
|
|
7
|
+
# Page Designer in Storefront Next
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
In Storefront Next your React components are the Page Designer components. You annotate them with decorators, the build generates Business Manager metadata (JSON) from those decorators, and at runtime a route loader fetches the page structure from the Shopper Experience API and `<Region>` renders it.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
The in-project guide is `docs/README-PAGE-DESIGNER.md` and the rules in `AGENTS.md` apply; this skill is the task-oriented path through them. Where the guide and the source disagree, trust the source.
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
## Pieces and where they live
|
|
13
14
|
|
|
14
|
-
|
|
|
15
|
-
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
15
|
+
| Piece | Location in your project |
|
|
16
|
+
|-------|--------------------------|
|
|
17
|
+
| Decorators (`Component`, `AttributeDefinition`, `RegionDefinition`, `PageType`) | `@/lib/decorators` (`src/lib/decorators/`) |
|
|
18
|
+
| Page fetch with per-component loader promises | `fetchPageWithComponentData` in `@/lib/page-designer/page-loader.server` |
|
|
19
|
+
| Single-component fetch (preview, embedded) | `fetchComponentWithComponentData` in `@/lib/page-designer/component-loader.server` |
|
|
20
|
+
| Region renderer | `Region` from `@/components/region` |
|
|
21
|
+
| Generated registry (do not hand-edit) | `src/lib/page-designer/static-registry.ts` |
|
|
22
|
+
| Runtime hooks (`usePageDesignerMode`) | `@salesforce/storefront-next-runtime/design/react/core` |
|
|
23
|
+
| Design/preview mode detection in loaders | `isDesignModeActive` / `isPreviewModeActive` from `@salesforce/storefront-next-runtime/design/mode` |
|
|
24
|
+
| Generated Business Manager metadata | `cartridges/app_storefrontnext_base/cartridge/experience/{components,pages,aspects}` |
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
The runtime package's `/design` entry exports only the registry. Decorators come from your project, not from `@salesforce/storefront-next-runtime`.
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|--------------------|----------|
|
|
25
|
-
| Home (`homepage`), Category/PLP, Search, Product/PDP | Cart, Checkout, Account, Auth |
|
|
28
|
+
## Workflow
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
1. Create or edit the component (metadata class, props, default export, `fallback`, optional `loader`) under `src/components/<name>/index.tsx`.
|
|
31
|
+
2. Run `pnpm dev` (or `pnpm build`). The Vite plugin scans `src/components` for `@Component` and rewrites the registry between the `STATIC_REGISTRY_START/END` markers.
|
|
32
|
+
3. `pnpm cartridge:generate` writes the metadata JSON (`pnpm build` runs it for you).
|
|
33
|
+
4. `pnpm cartridge:validate` checks the generated JSON against the schemas. Generation also fails on an invalid attribute config (for example a bad `searching` combination).
|
|
34
|
+
5. `pnpm cartridge:deploy` uploads the cartridge to the B2C instance (`pnpm cartridge:deploy -- --delete` removes old cartridge files first). The optional MCP tool `cartridge_deploy` does the same. See `b2c-cli:b2c-code` for credentials and code-version handling.
|
|
35
|
+
6. In Business Manager, merchants build pages from the new palette entries. See [Business Manager](references/BUSINESS-MANAGER.md).
|
|
28
36
|
|
|
29
|
-
|
|
37
|
+
## A component
|
|
30
38
|
|
|
31
|
-
```
|
|
32
|
-
|
|
39
|
+
```tsx
|
|
40
|
+
// src/components/promo-banner/index.tsx
|
|
41
|
+
import { AttributeDefinition, Component, RegionDefinition } from '@/lib/decorators';
|
|
42
|
+
import { DynamicImage } from '@/components/dynamic-image';
|
|
43
|
+
import { type Image } from '@/types';
|
|
44
|
+
import { cn } from '@/lib/utils';
|
|
33
45
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
46
|
+
@Component('promoBanner', {
|
|
47
|
+
name: 'Promo Banner',
|
|
48
|
+
description: 'Headline and optional image. Headline text and alignment are editable.',
|
|
49
|
+
group: 'Content',
|
|
50
|
+
})
|
|
51
|
+
@RegionDefinition([])
|
|
52
|
+
export class PromoBannerMetadata {
|
|
53
|
+
@AttributeDefinition({ id: 'headline', name: 'Headline', type: 'string', required: true, defaultValue: 'Spring sale' })
|
|
54
|
+
headline?: string;
|
|
37
55
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
componentData,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
```
|
|
56
|
+
@AttributeDefinition({ id: 'image', name: 'Image', type: 'image' })
|
|
57
|
+
image?: Image;
|
|
44
58
|
|
|
45
|
-
|
|
59
|
+
@AttributeDefinition({ id: 'align', name: 'Alignment', type: 'enum', values: ['left', 'center'], defaultValue: 'left' })
|
|
60
|
+
align?: 'left' | 'center';
|
|
61
|
+
}
|
|
46
62
|
|
|
47
|
-
|
|
48
|
-
|
|
63
|
+
interface PromoBannerProps {
|
|
64
|
+
headline?: string;
|
|
65
|
+
image?: Image;
|
|
66
|
+
align?: 'left' | 'center';
|
|
67
|
+
className?: string;
|
|
68
|
+
}
|
|
49
69
|
|
|
50
|
-
|
|
70
|
+
// Page Designer also injects component, data, designMetadata and regionId.
|
|
71
|
+
// Never spread them onto a DOM element; destructure them out first if you forward ...rest.
|
|
72
|
+
export default function PromoBanner({ headline = 'Spring sale', image, align = 'left', className }: PromoBannerProps) {
|
|
51
73
|
return (
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
<Region page={page} regionId="content" componentData={componentData}
|
|
58
|
-
fallbackElement={<ContentSkeleton />} />
|
|
59
|
-
</div>
|
|
74
|
+
<section className={cn('relative', align === 'center' && 'text-center', className)}>
|
|
75
|
+
{image?.url && <DynamicImage src={image.url} alt="" />}
|
|
76
|
+
<h2>{headline}</h2>
|
|
77
|
+
</section>
|
|
60
78
|
);
|
|
61
79
|
}
|
|
62
|
-
```
|
|
63
80
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
81
|
+
// REQUIRED. Rendered in a Suspense boundary; receives the same attribute props. Keep it light.
|
|
82
|
+
export function fallback() {
|
|
83
|
+
return <div className="h-48 animate-pulse bg-muted" />;
|
|
84
|
+
}
|
|
85
|
+
```
|
|
67
86
|
|
|
68
|
-
|
|
69
|
-
import { Component, AttributeDefinition, RegionDefinition } from '@salesforce/storefront-next-runtime/design';
|
|
87
|
+
Rules that matter:
|
|
70
88
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
image: string;
|
|
89
|
+
- Attribute values arrive as props named after the class field, so the field name and `id` must agree.
|
|
90
|
+
- The metadata class must be `export`ed; the generator only sees exported classes.
|
|
91
|
+
- The `typeId` must be a string literal. It is stored as `<group>.<typeId>` (default group `storefrontnext_base`), for example `Content.promoBanner`. Use the `group` option (`Content`, `Layout`, ...) so related components sit together in the palette.
|
|
92
|
+
- An `image` attribute delivers an object (`{ url, focalPoint?, metaData? }`), typed `Image` from `@/types`, not a string. Check `src/components/hero/index.tsx` for the pattern.
|
|
93
|
+
- `name` and `description` are what merchants read in Business Manager; omitted ones fall back to the raw id.
|
|
94
|
+
- Full option tables, attribute types, enums, nested regions and cross-group refs: [Decorator Patterns](references/DECORATOR-PATTERNS.md).
|
|
78
95
|
|
|
79
|
-
|
|
80
|
-
headline: string;
|
|
96
|
+
## A loader
|
|
81
97
|
|
|
82
|
-
|
|
83
|
-
ctaUrl: string;
|
|
98
|
+
Export a callable named `loader` when the component needs data (products, categories, your own API). It receives `{ componentData, context, request }`; `componentData` is the whole SCAPI component object, so merchant-set attributes live at `componentData.data`.
|
|
84
99
|
|
|
85
|
-
|
|
86
|
-
|
|
100
|
+
```tsx
|
|
101
|
+
// src/components/promo-products/loaders.ts
|
|
102
|
+
import type { LoaderFunctionArgs } from 'react-router';
|
|
103
|
+
import type { ShopperExperience } from '@/scapi';
|
|
104
|
+
import { fetchProductsByIds } from '@/lib/api/products.server';
|
|
87
105
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
106
|
+
export const loader = async (args: { componentData: unknown; context: LoaderFunctionArgs['context'] }) => {
|
|
107
|
+
const comp = args.componentData as ShopperExperience.schemas['Component'];
|
|
108
|
+
const { productIds } = (comp.data ?? {}) as { productIds?: string };
|
|
109
|
+
if (!productIds) return null;
|
|
110
|
+
return fetchProductsByIds(args.context, productIds.split(','));
|
|
111
|
+
};
|
|
91
112
|
```
|
|
92
113
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
export
|
|
97
|
-
|
|
98
|
-
<div className={cn('relative', fullWidth && 'w-full')}>
|
|
99
|
-
<DynamicImage src={image} alt={headline} />
|
|
100
|
-
<h1>{headline}</h1>
|
|
101
|
-
{ctaUrl && <a href={ctaUrl}>{ctaText}</a>}
|
|
102
|
-
</div>
|
|
103
|
-
);
|
|
104
|
-
}
|
|
114
|
+
```tsx
|
|
115
|
+
// src/components/promo-products/index.tsx
|
|
116
|
+
export { loader } from './loaders';
|
|
117
|
+
export function fallback() { /* skeleton with reserved height */ }
|
|
118
|
+
export default function PromoProducts({ data }: { data?: Product[] | null }) { /* ... */ }
|
|
105
119
|
```
|
|
106
120
|
|
|
107
|
-
|
|
121
|
+
- The exported `loader` must be a function. An object such as `{ server: fn }` is silently ignored and `data` stays undefined; unwrap it (`export const loader = loaders.server`), as `product-tile/index.tsx` does.
|
|
122
|
+
- The loader runs on the server only (stripped from the client bundle), so it may import `*.server` modules; the component file must not. An optional `clientLoader` export is client-only.
|
|
123
|
+
- Return `null` when nothing is configured, fetch in parallel with `Promise.all`, and let errors propagate so only that component is hidden.
|
|
124
|
+
- The registry records `{ loader: 'loader' }` and `{ fallback: 'fallback' }` capability flags for you on regeneration.
|
|
108
125
|
|
|
109
|
-
|
|
126
|
+
More on the registry shape, group-qualified ids, preload manifest and entry wiring: [Registry and Loading](references/COMPONENT-REGISTRY.md).
|
|
110
127
|
|
|
111
|
-
|
|
128
|
+
## A page route
|
|
112
129
|
|
|
113
|
-
|
|
114
|
-
// Export a loader for the component
|
|
115
|
-
export function loader({ componentData, context }) {
|
|
116
|
-
const clients = createApiClients(context);
|
|
117
|
-
return clients.shopperProducts.getProducts({
|
|
118
|
-
params: { query: { ids: componentData.productIds } }
|
|
119
|
-
}).then(({ data }) => data);
|
|
120
|
-
}
|
|
130
|
+
Routes bind a URL to a Page Designer page template and render its regions. Routes with `@PageType` today: home (`_app._index.tsx`), PLP (`_app.c.$.tsx`), PDP (`_app.p.$.tsx`), search (`_app.search.tsx`), about-us (`_app.about-us.tsx`), and the component preview route. Cart, checkout, account and auth do not use Page Designer.
|
|
121
131
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
132
|
+
```tsx
|
|
133
|
+
import { Region } from '@/components/region';
|
|
134
|
+
import { PageType } from '@/lib/decorators/page-type';
|
|
135
|
+
import { RegionDefinition } from '@/lib/decorators/region-definition';
|
|
136
|
+
import { fetchPageWithComponentData } from '@/lib/page-designer/page-loader.server';
|
|
137
|
+
|
|
138
|
+
@PageType({
|
|
139
|
+
name: 'Landing Page',
|
|
140
|
+
description: 'Campaign landing page with a banner and a main content area',
|
|
141
|
+
supportedAspectTypes: [],
|
|
142
|
+
})
|
|
143
|
+
@RegionDefinition([
|
|
144
|
+
{ id: 'banner', name: 'Banner Region', maxComponents: 1 },
|
|
145
|
+
{ id: 'main', name: 'Main Region' },
|
|
146
|
+
])
|
|
147
|
+
export class LandingPageMetadata {}
|
|
148
|
+
|
|
149
|
+
export function loader(args: Route.LoaderArgs) {
|
|
150
|
+
return { page: fetchPageWithComponentData(args, { pageId: 'landing' }) };
|
|
125
151
|
}
|
|
126
152
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
153
|
+
export default function Landing({ loaderData }: Route.ComponentProps) {
|
|
154
|
+
return (
|
|
155
|
+
<>
|
|
156
|
+
<Region page={loaderData.page} regionId="banner" />
|
|
157
|
+
<Region page={loaderData.page} regionId="main" />
|
|
158
|
+
</>
|
|
159
|
+
);
|
|
130
160
|
}
|
|
131
161
|
```
|
|
132
162
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
163
|
+
- Fetch by `{ pageId }` for a fixed page, or by aspect: `{ aspectType: 'pdp', productId, categoryId? }` and `{ aspectType: 'plp', categoryId }`. The `aspectType` passed to the fetch must agree with `@PageType.supportedAspectTypes` (`['pdp']`, `['plp']`, or `[]` for fixed-page routes such as home); a mismatch shows the wrong template in Business Manager with no error.
|
|
164
|
+
- `fetchPageWithComponentData` attaches the per-component loader promises to the page (`page.componentData`). `<Region>` reads them itself; it takes no `componentData` prop, and the loader returns just `{ page }`. It resolves to `null` when the page is missing (404) or SCAPI errors, so empty regions are the normal unconfigured state.
|
|
165
|
+
- `<Region page={...}>` accepts a promise and renders in Suspense. Add `fallbackElement` only for a visible skeleton.
|
|
166
|
+
- Add `critical` to a page-level region only for above-the-fold or LCP content, and only with an awaited page (`page: await fetchPageWithComponentData(...)`), as `_app._index.tsx` does. Never on below-the-fold or catch-all regions. Details in [Registry and Loading](references/COMPONENT-REGISTRY.md).
|
|
167
|
+
- Nested regions inside a component use component mode, synchronously: `<Region component={component} regionId="content" />`. No Suspense wrapper, no `fallbackElement`, no promises. See `src/components/grid/index.tsx`.
|
|
168
|
+
- Do not use `errorElement` to render hard-coded content for an unconfigured page: it defeats merchant control and forces loaders to fetch data only for the fallback. The home route still contains such an `errorElement`; do not copy it. Use `fallbackElement` for loading and render nothing for empty.
|
|
169
|
+
- Metadata classes on routes are empty, exported, and never carry `@AttributeDefinition`.
|
|
136
170
|
|
|
137
|
-
|
|
171
|
+
## Design and preview mode
|
|
138
172
|
|
|
139
|
-
|
|
140
|
-
import { isDesignModeActive, isPreviewModeActive } from '@salesforce/storefront-next-runtime/design/mode';
|
|
173
|
+
Business Manager loads your storefront in an iframe. In loaders use `isDesignModeActive(request)` / `isPreviewModeActive(request)` (the page loader already does and switches to the `pageId`/`pdToken` passed by Business Manager). In components use `usePageDesignerMode()` from `@salesforce/storefront-next-runtime/design/react/core`. `PageDesignerInit` (`src/page-designer-init.tsx`, rendered by `root.tsx`) blocks link navigation while editing and loads design-mode styles; do not remove it.
|
|
141
174
|
|
|
142
|
-
|
|
143
|
-
const isDesignMode = isDesignModeActive(request);
|
|
144
|
-
const isPreview = isPreviewModeActive(request);
|
|
145
|
-
|
|
146
|
-
// Root layout exposes pageDesignerMode in loader data
|
|
147
|
-
// 'EDIT' | 'PREVIEW' | undefined
|
|
148
|
-
```
|
|
175
|
+
## Verify before you finish
|
|
149
176
|
|
|
150
|
-
|
|
177
|
+
- [ ] Metadata class exported; `typeId` literal; `group` set; every attribute has `name`, `description`, correct `type`
|
|
178
|
+
- [ ] Default export is the component; `fallback` exported and lightweight; `loader` (if any) is a function
|
|
179
|
+
- [ ] Every `<Region regionId>` matches a `@RegionDefinition` id, and vice versa
|
|
180
|
+
- [ ] `pnpm cartridge:generate && pnpm cartridge:validate` pass; the component is in `static-registry.ts`
|
|
181
|
+
- [ ] Review against [Review Checklist](references/REVIEW-CHECKLIST.md); symptoms in [Troubleshooting](references/TROUBLESHOOTING.md)
|
|
151
182
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
1. **`storefront_next_page_designer_decorator`** — Adds decorators to components (auto mode or interactive)
|
|
155
|
-
2. **`storefront_next_generate_page_designer_metadata`** — Generates metadata JSON for Business Manager
|
|
156
|
-
3. **`cartridge_deploy`** — Deploys cartridge to Commerce Cloud
|
|
157
|
-
|
|
158
|
-
### Typical Workflow
|
|
159
|
-
|
|
160
|
-
1. Add decorators to component (use `storefront_next_page_designer_decorator` with autoMode)
|
|
161
|
-
2. Generate metadata JSON (`storefront_next_generate_page_designer_metadata`)
|
|
162
|
-
3. Deploy cartridge (`cartridge_deploy`)
|
|
163
|
-
|
|
164
|
-
## Best Practices
|
|
183
|
+
## Reference Documentation
|
|
165
184
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
185
|
+
- [Decorator Patterns](references/DECORATOR-PATTERNS.md) - options, attribute types, regions, page types
|
|
186
|
+
- [Registry and Loading](references/COMPONENT-REGISTRY.md) - static registry, loaders, critical regions, entry wiring
|
|
187
|
+
- [Business Manager](references/BUSINESS-MANAGER.md) - `route` and `aspectTypeIds`, page setup, palette
|
|
188
|
+
- [Review Checklist](references/REVIEW-CHECKLIST.md) - what to check in a component or page route
|
|
189
|
+
- [Troubleshooting](references/TROUBLESHOOTING.md) - component missing, empty, or wrong data
|
|
171
190
|
|
|
172
191
|
## Related Skills
|
|
173
192
|
|
|
174
|
-
- `storefront-next:sfnext-
|
|
175
|
-
- `storefront-next:sfnext-
|
|
176
|
-
- `
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
193
|
+
- `storefront-next:sfnext-components` - component conventions, shadcn primitives, Storybook
|
|
194
|
+
- `storefront-next:sfnext-data-fetching` - loaders, `createApiClients`, streaming with Suspense/Await
|
|
195
|
+
- `storefront-next:sfnext-scapi` - calling SCAPI from loaders and actions
|
|
196
|
+
- `storefront-next:sfnext-performance` - LCP, preload, critical data
|
|
197
|
+
- `storefront-next:sfnext-theming` - tokens and brand styling for new components
|
|
198
|
+
- `storefront-next:sfnext-testing` - component and story tests
|
|
199
|
+
- `storefront-next:sfnext-deployment` - shipping the storefront bundle
|
|
200
|
+
- `figma-to-sfnext-pagedesigner:figma-to-sfnext-pagedesigner` - Figma frame to Page Designer blocks
|
|
201
|
+
- `b2c:b2c-page-designer` - classic (ISML/SFRA) Page Designer
|
|
202
|
+
- `b2c-cli:b2c-code` - deploying cartridges and code versions
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Business Manager Integration
|
|
2
|
+
|
|
3
|
+
How code becomes something merchants can use. The long-form version is the "Business Manager Integration" section of `docs/README-PAGE-DESIGNER.md`.
|
|
4
|
+
|
|
5
|
+
## What gets generated
|
|
6
|
+
|
|
7
|
+
`pnpm cartridge:generate` (also part of `pnpm build`) scans your decorators and writes JSON under `cartridges/app_storefrontnext_base/cartridge/experience/`:
|
|
8
|
+
|
|
9
|
+
| Folder | Source | Content |
|
|
10
|
+
|--------|--------|---------|
|
|
11
|
+
| `components/<group>/<typeId>.json` | `@Component` + `@AttributeDefinition` + `@RegionDefinition` | Palette entries and their attribute editors |
|
|
12
|
+
| `pages/<name>.json` | `@PageType` + `@RegionDefinition` on a route | Page templates, with `route` and `aspectTypeIds` |
|
|
13
|
+
| `aspects/*.json` | aspect types (`pdp`, `plp`) | Aspect definitions for product and category pages |
|
|
14
|
+
|
|
15
|
+
Never hand-edit these files; regenerate. `pnpm cartridge:validate` checks them against the schemas. `pnpm cartridge:deploy` uploads the cartridge; `pnpm cartridge:deploy -- --delete` clears old cartridge files first.
|
|
16
|
+
|
|
17
|
+
The first time you set up an instance, `sfnext setup-base-cartridge --slas-client-id <id>` registers what the base cartridge needs on your SLAS client (see `docs/README-EMAIL-CARTRIDGE.md` in your project and `b2c-cli:b2c-slas`).
|
|
18
|
+
|
|
19
|
+
## `route` and `aspectTypeIds`
|
|
20
|
+
|
|
21
|
+
The generated page JSON carries two fields that tie a route to Business Manager:
|
|
22
|
+
|
|
23
|
+
- `route`: the URL pattern Business Manager loads in its preview iframe, with `:param` placeholders replaced by the product, category or search term the merchant selected (for example `/:siteId/:localeId/product/:productId`, `/:siteId/:localeId/category/:categoryId`, `/:siteId/:localeId`). It comes from the route file, so a renamed route file changes it on the next generate.
|
|
24
|
+
- `aspectTypeIds`: from `@PageType.supportedAspectTypes`. It decides which page templates are offered when a merchant creates a page for a product (`pdp`) or category (`plp`). An empty array means the template is for a fixed page.
|
|
25
|
+
|
|
26
|
+
The route's loader must fetch with the same aspect the decorator advertises (`fetchPageWithComponentData(args, { aspectType: 'pdp', productId })` with `supportedAspectTypes: ['pdp']`). This cross-file agreement is the most common page-level bug and produces no error, only the wrong template in Business Manager.
|
|
27
|
+
|
|
28
|
+
## Merchant setup checklist
|
|
29
|
+
|
|
30
|
+
After deploying the cartridge:
|
|
31
|
+
|
|
32
|
+
1. Make sure the cartridge is on the cartridge path of the site and the active code version holds the upload.
|
|
33
|
+
2. If the storefront was created outside Business Manager, connect it to Business Manager so Page Designer and Storefront Preview can see it (Administration > Sites > Storefronts > Connect Existing; needs an administrator role; confirm current steps in the Salesforce Storefront Next documentation).
|
|
34
|
+
3. Merchant Tools > Content > Page Designer: create a page, choose the template (page type) that matches the route, add components to its regions.
|
|
35
|
+
4. For aspect pages, assign the page to the product or category; for fixed pages, use the `pageId` your loader requests (for example `homepage`, `aboutus`).
|
|
36
|
+
5. Publish, then check the storefront. A `null` page (missing or unpublished) renders empty regions rather than an error.
|
|
37
|
+
|
|
38
|
+
## Design vs preview mode
|
|
39
|
+
|
|
40
|
+
Business Manager opens your storefront with `mode` and `pdToken` query parameters. `fetchPageFromLoader` switches to the page Business Manager specifies while in these modes, and `PageDesignerInit` blocks link navigation in edit mode. Keep both; neither needs changes when you add components.
|
|
41
|
+
|
|
42
|
+
## Where to look next
|
|
43
|
+
|
|
44
|
+
- Component missing or empty: [Troubleshooting](TROUBLESHOOTING.md)
|
|
45
|
+
- Deploy credentials and code versions: `b2c-cli:b2c-code`, `b2c-cli:b2c-webdav`
|
|
46
|
+
- Pushing the storefront bundle itself: `storefront-next:sfnext-deployment`
|
package/content/guidance/storefront-next/sfnext-page-designer/references/COMPONENT-REGISTRY.md
CHANGED
|
@@ -1,78 +1,111 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Registry and Loading
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## The static registry
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`src/lib/page-designer/static-registry.ts` maps fully-qualified component ids to lazy importers. The `staticRegistry` Vite plugin generates it from every `@Component` under `src/components` when `pnpm dev` or `pnpm build` starts, and again on hot updates. Everything between `// STATIC_REGISTRY_START` and `// STATIC_REGISTRY_END` is overwritten; do not edit it by hand and do not add entries manually.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Shape of the generated code (your file lists your project's components):
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```typescript
|
|
10
|
+
const staticRegistryImporters = [
|
|
11
|
+
() => import('../../components/hero/index'),
|
|
12
|
+
() => import('../../components/product-carousel/index'),
|
|
13
|
+
// ...
|
|
14
|
+
] as const;
|
|
15
|
+
|
|
16
|
+
export function initializeRegistry(targetRegistry = registry): void {
|
|
17
|
+
targetRegistry.registerImporter('Content.hero', staticRegistryImporters[0]);
|
|
18
|
+
targetRegistry.registerImporter('Layout.productCarousel', staticRegistryImporters[1], {
|
|
19
|
+
loader: 'loader',
|
|
20
|
+
fallback: 'fallback',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
```
|
|
10
24
|
|
|
11
|
-
|
|
25
|
+
- Ids are `<group>.<typeId>`, so the `typeId` in `@Component('hero', ...)` plus `group: 'Content'` becomes `Content.hero`. These ids must match what Business Manager sends.
|
|
26
|
+
- The third argument records which named exports the module has: `loader` (server data) and `fallback` (Suspense skeleton). The plugin derives them from your exports.
|
|
27
|
+
- To see which components your project registers, read the generated file rather than relying on a fixed list.
|
|
12
28
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
pnpm dev # Hot reload regenerates automatically
|
|
17
|
-
```
|
|
29
|
+
If a new component is missing from the registry, the usual cause is that it is outside `src/components`, the `@Component` first argument is not a string literal, or the dev server was not running when the file changed. Restart `pnpm dev` or run `pnpm build`.
|
|
30
|
+
|
|
31
|
+
## Entry wiring (do not break)
|
|
18
32
|
|
|
19
|
-
|
|
33
|
+
`initializeRegistry()` is called once at module top level in `src/entry.server.tsx` and synchronously in `src/entry.client.tsx`, before any component markers are scanned. Keep it there; moving it into a React render function breaks registration ordering.
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
`vite-plugins/storefront-next.ts` enables the plugin with:
|
|
22
36
|
|
|
23
37
|
```typescript
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'product-carousel': () => import('@/components/product-carousel'),
|
|
29
|
-
'content-card': () => import('@/components/content-card'),
|
|
38
|
+
staticRegistry: {
|
|
39
|
+
componentPath: 'src/components',
|
|
40
|
+
registryPath: 'src/lib/page-designer/static-registry.ts',
|
|
41
|
+
preloadManifest: true,
|
|
30
42
|
}
|
|
31
43
|
```
|
|
32
44
|
|
|
33
|
-
|
|
45
|
+
`preloadManifest: true` builds the resource-hint manifest that `critical` regions and per-component preload hints depend on. Keep it on.
|
|
46
|
+
|
|
47
|
+
## How a page renders
|
|
34
48
|
|
|
35
|
-
|
|
49
|
+
1. The route loader calls `fetchPageWithComponentData(args, params)`.
|
|
50
|
+
2. It fetches the page (SCAPI Shopper Experience, resolved from the Data Store when that middleware is active), walks every region and nested region, and for each component whose registry entry has a `loader` calls it with `{ componentData, context, request }`. The resulting promises are stored as `page.componentData[component.id]`.
|
|
51
|
+
3. `<Region page={page} regionId="..." />` resolves each component's module from the registry, wraps it in Suspense (using the module's `fallback`), awaits that component's promise, and renders the default export with the attribute props plus `data`, `component`, `designMetadata` and `regionId`.
|
|
52
|
+
|
|
53
|
+
Because data is attached to the page, there is no separate `componentData` return key and no `componentData` prop on `<Region>`.
|
|
54
|
+
|
|
55
|
+
## Fetching a page
|
|
36
56
|
|
|
37
57
|
```typescript
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
import { fetchPageWithComponentData } from '@/lib/page-designer/page-loader.server';
|
|
59
|
+
|
|
60
|
+
// Fixed page by id
|
|
61
|
+
fetchPageWithComponentData(args, { pageId: 'homepage' });
|
|
62
|
+
|
|
63
|
+
// By aspect (page assigned to a product or category in Business Manager)
|
|
64
|
+
fetchPageWithComponentData(args, { aspectType: 'pdp', productId, categoryId });
|
|
65
|
+
fetchPageWithComponentData(args, { aspectType: 'plp', categoryId });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Return the promise unawaited for a non-critical page (React Router streams it), or `await` it when a `critical` region needs the page synchronously. `fetchPageFromLoader` (same module) is the lower-level call that returns the raw page without `componentData`; routes use `fetchPageWithComponentData`.
|
|
69
|
+
|
|
70
|
+
Single components (for example an embedded content block or the preview route) use `fetchComponentWithComponentData` from `@/lib/page-designer/component-loader.server`.
|
|
71
|
+
|
|
72
|
+
## Module contract
|
|
73
|
+
|
|
74
|
+
| Export | Required | Notes |
|
|
75
|
+
|--------|----------|-------|
|
|
76
|
+
| default | yes | The React component. `forwardRef` components are fine. |
|
|
77
|
+
| `fallback` | yes | Lightweight skeleton; gets the same attribute props; reserve dimensions to avoid layout shift. No hooks that suspend, no fetching. |
|
|
78
|
+
| `loader` | optional | Must be a function `({ componentData, context, request }) => Promise`. Server only (stripped from the client bundle). Attributes are at `componentData.data`. |
|
|
79
|
+
| `clientLoader` | optional | Client-only counterpart (stripped from the server bundle). |
|
|
80
|
+
|
|
81
|
+
A `loader` that is an object (`{ server, client }`) is not callable; the loader never runs and `data` is undefined. Export the function: `export const loader = loaders.server`.
|
|
47
82
|
|
|
48
|
-
|
|
49
|
-
|
|
83
|
+
Loader guidance: return `null` when nothing is configured, fetch independent resources with `Promise.all`, do not swallow errors (the component's error boundary hides only that component), and reuse the shared `@/lib/api/*.server` helpers rather than building SCAPI calls inline.
|
|
84
|
+
|
|
85
|
+
## Critical regions
|
|
86
|
+
|
|
87
|
+
By default regions stream: the shell renders, then each component swaps in. For above-the-fold content that must be in the first HTML (hero, LCP image), make the region critical.
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
export async function loader(args: Route.LoaderArgs) {
|
|
91
|
+
const page = await fetchPageWithComponentData(args, { pageId: 'homepage' }); // must be resolved
|
|
92
|
+
const recommendations = fetchRecommendations(args.context); // stay deferred
|
|
93
|
+
return { page, recommendations };
|
|
50
94
|
}
|
|
51
95
|
|
|
52
|
-
export default function
|
|
53
|
-
|
|
54
|
-
return <div>{data.products.map(p => <ProductTile key={p.id} product={p} />)}</div>;
|
|
96
|
+
export default function Home({ loaderData }: Route.ComponentProps) {
|
|
97
|
+
return <Region page={loaderData.page} regionId="headerbanner" critical />;
|
|
55
98
|
}
|
|
56
99
|
```
|
|
57
100
|
|
|
58
|
-
|
|
101
|
+
- `critical` is page mode only; nested component regions inherit it.
|
|
102
|
+
- The page must already be resolved; omit `fallbackElement` on a critical region.
|
|
103
|
+
- Each component's own `loader` data still streams inside its local Suspense boundary.
|
|
104
|
+
- Use it sparingly; it delays the initial shell. Never on below-the-fold or catch-all regions.
|
|
105
|
+
- Stylesheets added through a route's `links` export should use `createStorefrontStylesheetLink` from `@salesforce/storefront-next-runtime/design/react/preload` so critical component styles keep a stable cascade order.
|
|
59
106
|
|
|
60
|
-
|
|
61
|
-
Route loader
|
|
62
|
-
|-- fetchPageFromLoader(args, { pageId }) -> page promise
|
|
63
|
-
+-- collectComponentDataPromises(args, page) -> componentData map
|
|
64
|
-
|
|
|
65
|
-
For each component with a loader:
|
|
66
|
-
component.loader({ componentData, context }) -> data promise
|
|
67
|
-
|
|
|
68
|
-
<Region> renders components with resolved data
|
|
69
|
-
```
|
|
107
|
+
See "Critical Page Regions" in `docs/README-PAGE-DESIGNER.md` for the full behavior.
|
|
70
108
|
|
|
71
|
-
##
|
|
109
|
+
## Error handling
|
|
72
110
|
|
|
73
|
-
|
|
74
|
-
2. Implement the component's render function
|
|
75
|
-
3. (Optional) Export `loader` and `fallback` if server data is needed
|
|
76
|
-
4. Rebuild to regenerate static registry
|
|
77
|
-
5. Generate metadata JSON via MCP tool (`storefront_next_generate_page_designer_metadata`)
|
|
78
|
-
6. Deploy cartridge via MCP tool (`cartridge_deploy`)
|
|
111
|
+
Do not pass `errorElement` to show hard-coded content when a page is unconfigured. That hides setup problems, forces extra fetches in the loader, and bypasses merchant control. Use `fallbackElement` for loading states, or render nothing when a region is empty. The home route's existing `errorElement` is a legacy pattern; do not copy it to new routes.
|