@salesforce/b2c-cli 2.3.0 → 2.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/dev.js +8 -8
- package/bin/run.js +5 -7
- package/content/guidance/b2c/b2c-business-manager-extensions/SKILL.md +361 -0
- package/content/guidance/b2c/b2c-business-manager-extensions/references/EXTENSIONS-XML.md +458 -0
- package/content/guidance/b2c/b2c-controllers/SKILL.md +301 -0
- package/content/guidance/b2c/b2c-controllers/references/CLASSIC-PATTERNS.md +335 -0
- package/content/guidance/b2c/b2c-controllers/references/SFRA-PATTERNS.md +400 -0
- package/content/guidance/b2c/b2c-custom-api-development/SKILL.md +281 -0
- package/content/guidance/b2c/b2c-custom-api-development/references/CONTRACT.md +142 -0
- package/content/guidance/b2c/b2c-custom-api-development/references/IMPLEMENTATION.md +153 -0
- package/content/guidance/b2c/b2c-custom-api-development/references/TESTING.md +118 -0
- package/content/guidance/b2c/b2c-custom-caches/SKILL.md +279 -0
- package/content/guidance/b2c/b2c-custom-job-steps/SKILL.md +520 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/CHUNK-ORIENTED.md +377 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/JOBS-XML.md +212 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/STEPTYPES-JSON.md +373 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/TASK-ORIENTED.md +344 -0
- package/content/guidance/b2c/b2c-custom-objects/SKILL.md +327 -0
- package/content/guidance/b2c/b2c-custom-objects/references/OCAPI-SEARCH.md +298 -0
- package/content/guidance/b2c/b2c-forms/SKILL.md +242 -0
- package/content/guidance/b2c/b2c-forms/references/FORM-XML.md +409 -0
- package/content/guidance/b2c/b2c-hooks/SKILL.md +500 -0
- package/content/guidance/b2c/b2c-hooks/references/OCAPI-SCAPI-HOOKS.md +403 -0
- package/content/guidance/b2c/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +169 -0
- package/content/guidance/b2c/b2c-hooks/references/SYSTEM-HOOKS.md +433 -0
- package/content/guidance/b2c/b2c-isml/SKILL.md +320 -0
- package/content/guidance/b2c/b2c-isml/references/EXPRESSIONS.md +366 -0
- package/content/guidance/b2c/b2c-isml/references/TAGS.md +443 -0
- package/content/guidance/b2c/b2c-localization/SKILL.md +344 -0
- package/content/guidance/b2c/b2c-localization/references/PATTERNS.md +407 -0
- package/content/guidance/b2c/b2c-logging/SKILL.md +352 -0
- package/content/guidance/b2c/b2c-logging/references/LOG-FILES.md +282 -0
- package/content/guidance/b2c/b2c-metadata/SKILL.md +406 -0
- package/content/guidance/b2c/b2c-metadata/references/SYSTEM-OBJECTS.md +320 -0
- package/content/guidance/b2c/b2c-metadata/references/XML-EXAMPLES.md +366 -0
- package/content/guidance/b2c/b2c-onboarding/SKILL.md +154 -0
- package/content/guidance/b2c/b2c-ordering/SKILL.md +391 -0
- package/content/guidance/b2c/b2c-page-designer/SKILL.md +410 -0
- package/content/guidance/b2c/b2c-page-designer/references/ATTRIBUTE-TYPES.md +436 -0
- package/content/guidance/b2c/b2c-page-designer/references/META-DEFINITIONS.md +340 -0
- package/content/guidance/b2c/b2c-querying-data/SKILL.md +289 -0
- package/content/guidance/b2c/b2c-querying-data/references/PERFORMANCE-APIS.md +74 -0
- package/content/guidance/b2c/b2c-scapi-admin/SKILL.md +53 -0
- package/content/guidance/b2c/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +440 -0
- package/content/guidance/b2c/b2c-scapi-admin/references/INTEGRATION-PATTERNS.md +518 -0
- package/content/guidance/b2c/b2c-scapi-admin/references/OAUTH-SCOPES.md +337 -0
- package/content/guidance/b2c/b2c-scapi-shopper/SKILL.md +56 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/CHECKOUT-FLOW.md +466 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +351 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/COMMON-PATTERNS.md +390 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/SCOPES.md +290 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/SKILL.md +420 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/references/PASSKEYS.md +126 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/references/SESSION-BRIDGE.md +267 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/references/TOKEN-LIFECYCLE.md +367 -0
- package/content/guidance/b2c/b2c-webservices/SKILL.md +318 -0
- package/content/guidance/b2c/b2c-webservices/references/FTP-SERVICES.md +524 -0
- package/content/guidance/b2c/b2c-webservices/references/HTTP-SERVICES.md +578 -0
- package/content/guidance/b2c/b2c-webservices/references/SERVICES-XML.md +351 -0
- package/content/guidance/b2c/b2c-webservices/references/SOAP-SERVICES.md +587 -0
- package/content/guidance/b2c-cli/b2c-am/SKILL.md +277 -0
- package/content/guidance/b2c-cli/b2c-bm-users-roles/SKILL.md +210 -0
- package/content/guidance/b2c-cli/b2c-cap/SKILL.md +131 -0
- package/content/guidance/b2c-cli/b2c-cip/SKILL.md +116 -0
- package/content/guidance/b2c-cli/b2c-cip/references/KNOWN_TABLES.md +105 -0
- package/content/guidance/b2c-cli/b2c-cip/references/SALES_ANALYSIS.md +50 -0
- package/content/guidance/b2c-cli/b2c-cip/references/STARTER_QUERIES.md +147 -0
- package/content/guidance/b2c-cli/b2c-code/SKILL.md +146 -0
- package/content/guidance/b2c-cli/b2c-config/SKILL.md +462 -0
- package/content/guidance/b2c-cli/b2c-content/SKILL.md +176 -0
- package/content/guidance/b2c-cli/b2c-debug/SKILL.md +138 -0
- package/content/guidance/b2c-cli/b2c-docs/SKILL.md +301 -0
- package/content/guidance/b2c-cli/b2c-ecdn/SKILL.md +135 -0
- package/content/guidance/b2c-cli/b2c-ecdn/references/ADVANCED.md +97 -0
- package/content/guidance/b2c-cli/b2c-ecdn/references/SECURITY.md +75 -0
- package/content/guidance/b2c-cli/b2c-import-set-migrations/SKILL.md +265 -0
- package/content/guidance/b2c-cli/b2c-job/SKILL.md +64 -0
- package/content/guidance/b2c-cli/b2c-job/references/EXPORT.md +121 -0
- package/content/guidance/b2c-cli/b2c-job/references/IMPORT.md +55 -0
- package/content/guidance/b2c-cli/b2c-job/references/RUN-AND-MONITOR.md +119 -0
- package/content/guidance/b2c-cli/b2c-logs/SKILL.md +249 -0
- package/content/guidance/b2c-cli/b2c-metrics/SKILL.md +315 -0
- package/content/guidance/b2c-cli/b2c-mrt/SKILL.md +207 -0
- package/content/guidance/b2c-cli/b2c-mrt/references/BUNDLE-COMMANDS.md +203 -0
- package/content/guidance/b2c-cli/b2c-mrt/references/ENVIRONMENT-COMMANDS.md +218 -0
- package/content/guidance/b2c-cli/b2c-mrt/references/PROJECT-COMMANDS.md +154 -0
- package/content/guidance/b2c-cli/b2c-sandbox/SKILL.md +112 -0
- package/content/guidance/b2c-cli/b2c-scapi-custom/SKILL.md +126 -0
- package/content/guidance/b2c-cli/b2c-scapi-schemas/SKILL.md +66 -0
- package/content/guidance/b2c-cli/b2c-scapi-schemas/references/CLI-EXAMPLES.md +108 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/SKILL.md +57 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/references/IMPORT-OPTIONS.md +118 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/references/METADATA-XML.md +381 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/references/WORKFLOWS.md +182 -0
- package/content/guidance/b2c-cli/b2c-sites/SKILL.md +112 -0
- package/content/guidance/b2c-cli/b2c-slas/SKILL.md +182 -0
- package/content/guidance/b2c-cli/b2c-webdav/SKILL.md +186 -0
- package/content/guidance/b2c-ops/b2c-checkout-triage/SKILL.md +68 -0
- package/content/guidance/b2c-ops/b2c-job-health/SKILL.md +75 -0
- package/content/guidance/b2c-ops/b2c-job-health/references/job-logs.md +21 -0
- package/content/guidance/b2c-ops/b2c-order-failure-triage/SKILL.md +66 -0
- package/content/guidance/b2c-ops/b2c-order-failure-triage/references/order-evidence.md +87 -0
- package/content/guidance/b2c-ops/b2c-production-triage/SKILL.md +87 -0
- package/content/guidance/b2c-ops/b2c-production-triage/references/escalation.md +57 -0
- package/content/guidance/index.json +1949 -0
- 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 +127 -0
- 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 +153 -0
- 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 +163 -0
- 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 +140 -0
- 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 +39 -0
- package/content/guidance/storefront-next/sfnext-deployment/SKILL.md +127 -0
- package/content/guidance/storefront-next/sfnext-deployment/references/MRT-DEPLOYMENT.md +59 -0
- package/content/guidance/storefront-next/sfnext-extensions/SKILL.md +118 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/BASE-AUDIT.md +68 -0
- 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 +79 -0
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/SKILL.md +93 -0
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +86 -0
- package/content/guidance/storefront-next/sfnext-i18n/SKILL.md +152 -0
- 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 +202 -0
- 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 +111 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/DECORATOR-PATTERNS.md +168 -0
- 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 +102 -0
- 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 +147 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -0
- 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 +123 -0
- package/content/guidance/storefront-next/sfnext-routing/references/ROUTE-CONVENTIONS.md +65 -0
- 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 +114 -0
- package/content/guidance/storefront-next/sfnext-state-management/references/PATTERNS.md +45 -0
- package/content/guidance/storefront-next/sfnext-testing/SKILL.md +151 -0
- package/content/guidance/storefront-next/sfnext-testing/references/E2E.md +38 -0
- package/content/guidance/storefront-next/sfnext-testing/references/STORYBOOK-PATTERNS.md +97 -0
- 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/cap/install.d.ts +1 -0
- package/dist/commands/cap/list.d.ts +1 -0
- package/dist/commands/cap/pull.d.ts +1 -0
- package/dist/commands/cap/tasks.d.ts +1 -0
- package/dist/commands/cap/uninstall.d.ts +1 -0
- package/dist/commands/cip/describe.d.ts +1 -0
- package/dist/commands/cip/query.d.ts +1 -0
- package/dist/commands/cip/report/bot-traffic-share.d.ts +1 -0
- package/dist/commands/cip/report/checkout-funnel-dropoff.d.ts +1 -0
- package/dist/commands/cip/report/controller-error-rate-trend.d.ts +1 -0
- package/dist/commands/cip/report/controller-health-scorecard.d.ts +1 -0
- package/dist/commands/cip/report/customer-registration-trends.d.ts +1 -0
- package/dist/commands/cip/report/discount-depth-breakdown.d.ts +1 -0
- package/dist/commands/cip/report/inventory-stockout-by-location.d.ts +1 -0
- package/dist/commands/cip/report/new-vs-returning-buyer-revenue.d.ts +1 -0
- package/dist/commands/cip/report/ocapi-client-usage.d.ts +1 -0
- package/dist/commands/cip/report/ocapi-requests.d.ts +1 -0
- package/dist/commands/cip/report/payment-method-performance.d.ts +1 -0
- package/dist/commands/cip/report/product-co-purchase-analysis.d.ts +1 -0
- package/dist/commands/cip/report/promotion-discount-analysis.d.ts +1 -0
- package/dist/commands/cip/report/promotion-roi-leaderboard.d.ts +1 -0
- package/dist/commands/cip/report/recommender-effectiveness.d.ts +1 -0
- package/dist/commands/cip/report/remote-include-performance.d.ts +1 -0
- package/dist/commands/cip/report/revenue-by-channel.d.ts +1 -0
- package/dist/commands/cip/report/sales-analytics.d.ts +1 -0
- package/dist/commands/cip/report/sales-summary.d.ts +1 -0
- package/dist/commands/cip/report/scapi-cache-hit-ratio.d.ts +1 -0
- package/dist/commands/cip/report/scapi-error-rate-by-status.d.ts +1 -0
- package/dist/commands/cip/report/scapi-latency-distribution.d.ts +1 -0
- package/dist/commands/cip/report/scapi-traffic-latency.d.ts +1 -0
- package/dist/commands/cip/report/search-query-performance.d.ts +1 -0
- package/dist/commands/cip/report/top-referrers.d.ts +1 -0
- package/dist/commands/cip/report/top-selling-products.d.ts +1 -0
- package/dist/commands/cip/report/zero-result-searches.d.ts +1 -0
- package/dist/commands/cip/tables.d.ts +1 -0
- package/dist/commands/code/activate.d.ts +1 -0
- package/dist/commands/code/delete.d.ts +1 -0
- package/dist/commands/code/deploy.d.ts +1 -0
- package/dist/commands/code/download.d.ts +1 -0
- package/dist/commands/code/watch.d.ts +1 -0
- package/dist/commands/commands/search.d.ts +35 -0
- package/dist/commands/commands/search.js +85 -0
- package/dist/commands/commands/search.js.map +1 -0
- package/dist/commands/content/export.d.ts +1 -0
- package/dist/commands/content/list.d.ts +1 -0
- package/dist/commands/content/validate.d.ts +1 -0
- package/dist/commands/debug/cli.d.ts +1 -0
- package/dist/commands/debug/index.d.ts +1 -0
- package/dist/commands/docs/cache.d.ts +1 -0
- package/dist/commands/docs/download.d.ts +1 -0
- package/dist/commands/docs/read.d.ts +1 -0
- package/dist/commands/docs/schema.d.ts +1 -0
- package/dist/commands/docs/search.d.ts +1 -0
- package/dist/commands/docs/skill.d.ts +41 -0
- package/dist/commands/docs/skill.js +183 -0
- package/dist/commands/docs/skill.js.map +1 -0
- package/dist/commands/ecdn/cache/purge.d.ts +1 -0
- package/dist/commands/ecdn/certificates/add.d.ts +1 -0
- package/dist/commands/ecdn/certificates/delete.d.ts +1 -0
- package/dist/commands/ecdn/certificates/list.d.ts +1 -0
- package/dist/commands/ecdn/certificates/update.d.ts +1 -0
- package/dist/commands/ecdn/certificates/validate.d.ts +1 -0
- package/dist/commands/ecdn/cipher-suites/get.d.ts +1 -0
- package/dist/commands/ecdn/cipher-suites/update.d.ts +1 -0
- package/dist/commands/ecdn/firewall/create.d.ts +1 -0
- package/dist/commands/ecdn/firewall/delete.d.ts +1 -0
- package/dist/commands/ecdn/firewall/get.d.ts +1 -0
- package/dist/commands/ecdn/firewall/list.d.ts +1 -0
- package/dist/commands/ecdn/firewall/reorder.d.ts +1 -0
- package/dist/commands/ecdn/firewall/update.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/create.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/delete.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/get.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/list.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/update.d.ts +1 -0
- package/dist/commands/ecdn/logpush/ownership.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/create.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/delete.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/get.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/rules/delete.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/rules/update.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/update.d.ts +1 -0
- package/dist/commands/ecdn/mtls/create.d.ts +1 -0
- package/dist/commands/ecdn/mtls/delete.d.ts +1 -0
- package/dist/commands/ecdn/mtls/get.d.ts +1 -0
- package/dist/commands/ecdn/mtls/issue.d.ts +1 -0
- package/dist/commands/ecdn/mtls/list.d.ts +1 -0
- package/dist/commands/ecdn/mtls/setup.d.ts +1 -0
- package/dist/commands/ecdn/origin-headers/delete.d.ts +1 -0
- package/dist/commands/ecdn/origin-headers/get.d.ts +1 -0
- package/dist/commands/ecdn/origin-headers/set.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/notifications/create.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/notifications/delete.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/notifications/list.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/create.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/delete.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/get.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/list.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/update.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/scripts/get.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/scripts/list.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/create.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/delete.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/get.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/list.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/update.d.ts +1 -0
- package/dist/commands/ecdn/security/get.d.ts +1 -0
- package/dist/commands/ecdn/security/update.d.ts +1 -0
- package/dist/commands/ecdn/speed/get.d.ts +1 -0
- package/dist/commands/ecdn/speed/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/groups/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/groups/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/managed-rules/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/managed-rules/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/migrate.d.ts +1 -0
- package/dist/commands/ecdn/waf/owasp/get.d.ts +1 -0
- package/dist/commands/ecdn/waf/owasp/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/rules/get.d.ts +1 -0
- package/dist/commands/ecdn/waf/rules/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/rules/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/rulesets/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/rulesets/update.d.ts +1 -0
- package/dist/commands/ecdn/zones/create.d.ts +1 -0
- package/dist/commands/ecdn/zones/list.d.ts +1 -0
- package/dist/commands/job/execution/delete.d.ts +1 -0
- package/dist/commands/job/export.d.ts +1 -0
- package/dist/commands/job/import-set.d.ts +1 -0
- package/dist/commands/job/import.d.ts +1 -0
- package/dist/commands/job/log.d.ts +1 -0
- package/dist/commands/job/run.d.ts +1 -0
- package/dist/commands/job/search.d.ts +1 -0
- package/dist/commands/job/wait.d.ts +1 -0
- package/dist/commands/logs/get.d.ts +1 -0
- package/dist/commands/logs/list.d.ts +1 -0
- package/dist/commands/logs/tail.d.ts +1 -0
- package/dist/commands/metrics/controller.d.ts +1 -0
- package/dist/commands/metrics/ecdn.d.ts +1 -0
- package/dist/commands/metrics/mrt.d.ts +1 -0
- package/dist/commands/metrics/ocapi.d.ts +1 -0
- package/dist/commands/metrics/overall.d.ts +1 -0
- package/dist/commands/metrics/sales.d.ts +1 -0
- package/dist/commands/metrics/scapi-hooks.d.ts +1 -0
- package/dist/commands/metrics/scapi.d.ts +1 -0
- package/dist/commands/metrics/third-party.d.ts +1 -0
- package/dist/commands/mrt/bundle/delete.d.ts +1 -0
- package/dist/commands/mrt/bundle/deploy.d.ts +1 -0
- package/dist/commands/mrt/bundle/download.d.ts +1 -0
- package/dist/commands/mrt/bundle/history.d.ts +1 -0
- package/dist/commands/mrt/bundle/list.d.ts +1 -0
- package/dist/commands/mrt/bundle/save.d.ts +1 -0
- package/dist/commands/mrt/bundle/upload-v2.d.ts +1 -0
- package/dist/commands/mrt/env/access-control/list.d.ts +1 -0
- package/dist/commands/mrt/env/b2c.d.ts +1 -0
- package/dist/commands/mrt/env/clone.d.ts +1 -0
- package/dist/commands/mrt/env/create.d.ts +1 -0
- package/dist/commands/mrt/env/delete.d.ts +1 -0
- package/dist/commands/mrt/env/get.d.ts +1 -0
- package/dist/commands/mrt/env/invalidate.d.ts +1 -0
- package/dist/commands/mrt/env/list.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/clone.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/create.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/delete.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/list.d.ts +1 -0
- package/dist/commands/mrt/env/update.d.ts +1 -0
- package/dist/commands/mrt/env/var/delete.d.ts +1 -0
- package/dist/commands/mrt/env/var/list.d.ts +1 -0
- package/dist/commands/mrt/env/var/push.d.ts +1 -0
- package/dist/commands/mrt/env/var/set.d.ts +1 -0
- package/dist/commands/mrt/org/b2c.d.ts +1 -0
- package/dist/commands/mrt/org/cert/create.d.ts +1 -0
- package/dist/commands/mrt/org/cert/delete.d.ts +1 -0
- package/dist/commands/mrt/org/cert/get.d.ts +1 -0
- package/dist/commands/mrt/org/cert/list.d.ts +1 -0
- package/dist/commands/mrt/org/cert/restart-validation.d.ts +1 -0
- package/dist/commands/mrt/org/list.d.ts +1 -0
- package/dist/commands/mrt/org/member/add.d.ts +1 -0
- package/dist/commands/mrt/org/member/get.d.ts +1 -0
- package/dist/commands/mrt/org/member/list.d.ts +1 -0
- package/dist/commands/mrt/org/member/remove.d.ts +1 -0
- package/dist/commands/mrt/org/member/update.d.ts +1 -0
- package/dist/commands/mrt/project/create.d.ts +1 -0
- package/dist/commands/mrt/project/delete.d.ts +1 -0
- package/dist/commands/mrt/project/get.d.ts +1 -0
- package/dist/commands/mrt/project/list.d.ts +1 -0
- package/dist/commands/mrt/project/member/add.d.ts +1 -0
- package/dist/commands/mrt/project/member/get.d.ts +1 -0
- package/dist/commands/mrt/project/member/list.d.ts +1 -0
- package/dist/commands/mrt/project/member/remove.d.ts +1 -0
- package/dist/commands/mrt/project/member/update.d.ts +1 -0
- package/dist/commands/mrt/project/notification/delete.d.ts +1 -0
- package/dist/commands/mrt/project/notification/get.d.ts +1 -0
- package/dist/commands/mrt/project/update.d.ts +1 -0
- package/dist/commands/mrt/save-credentials.d.ts +1 -0
- package/dist/commands/mrt/tail-logs.d.ts +1 -0
- package/dist/commands/mrt/user/api-key.d.ts +1 -0
- package/dist/commands/mrt/user/email-prefs.d.ts +1 -0
- package/dist/commands/mrt/user/profile.d.ts +1 -0
- package/dist/commands/scaffold/init.js +2 -1
- package/dist/commands/scaffold/init.js.map +1 -1
- package/dist/commands/scapi/custom/status.d.ts +1 -0
- package/dist/commands/scapi/schemas/get.d.ts +1 -0
- package/dist/commands/scapi/schemas/list.d.ts +1 -0
- package/dist/commands/setup/ide/tsserver-plugin.d.ts +1 -0
- package/dist/commands/setup/ide/vscode-types.d.ts +1 -0
- package/dist/commands/setup/index.js +4 -3
- package/dist/commands/setup/index.js.map +1 -1
- package/dist/commands/setup/inspect.d.ts +1 -0
- package/dist/commands/setup/inspect.js +17 -2
- package/dist/commands/setup/inspect.js.map +1 -1
- package/dist/commands/setup/instance/create.d.ts +1 -0
- package/dist/commands/setup/instance/list.d.ts +1 -0
- package/dist/commands/setup/instance/remove.d.ts +1 -0
- package/dist/commands/setup/instance/set-active.d.ts +1 -0
- package/dist/commands/setup/openshell.d.ts +1 -0
- package/dist/commands/setup/skills.d.ts +1 -0
- package/dist/commands/slas/client/create.d.ts +1 -0
- package/dist/commands/slas/client/delete.d.ts +1 -0
- package/dist/commands/slas/client/get.d.ts +1 -0
- package/dist/commands/slas/client/list.d.ts +1 -0
- package/dist/commands/slas/client/open.d.ts +1 -0
- package/dist/commands/slas/client/update.d.ts +1 -0
- package/dist/commands/slas/token.d.ts +1 -0
- package/dist/commands/slas/token.js +2 -1
- package/dist/commands/slas/token.js.map +1 -1
- package/dist/commands/webdav/get.d.ts +1 -0
- package/dist/commands/webdav/mkdir.d.ts +2 -0
- package/dist/commands/webdav/mkdir.js +5 -3
- package/dist/commands/webdav/mkdir.js.map +1 -1
- package/dist/commands/webdav/put.d.ts +2 -0
- package/dist/commands/webdav/put.js +5 -3
- package/dist/commands/webdav/put.js.map +1 -1
- package/dist/commands/webdav/rm.d.ts +1 -0
- package/dist/help.d.ts +25 -0
- package/dist/help.js +96 -0
- package/dist/help.js.map +1 -0
- package/dist/lib/scaffold/generate-helper.js +3 -2
- package/dist/lib/scaffold/generate-helper.js.map +1 -1
- package/dist/lib/skills.d.ts +19 -0
- package/dist/lib/skills.js +75 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/utils/cip/command.d.ts +1 -0
- package/dist/utils/ecdn/zone-command.d.ts +1 -0
- package/dist/utils/slas/client.d.ts +1 -0
- package/oclif.manifest.json +10994 -7653
- package/package.json +11 -5
|
@@ -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`.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sfnext-performance
|
|
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`).
|
|
5
|
+
---
|
|
6
|
+
|
|
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
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
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`.
|
|
46
|
+
|
|
47
|
+
## Deferred rendering
|
|
48
|
+
|
|
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.
|
|
50
|
+
|
|
51
|
+
## Page Designer
|
|
52
|
+
|
|
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`.
|
|
54
|
+
|
|
55
|
+
## Images, fonts, hints
|
|
56
|
+
|
|
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.
|
|
60
|
+
|
|
61
|
+
## Measure
|
|
62
|
+
|
|
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` |
|
|
70
|
+
|
|
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.
|
|
72
|
+
|
|
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`).
|
|
74
|
+
|
|
75
|
+
## Review workflow
|
|
76
|
+
|
|
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.
|
|
81
|
+
|
|
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.
|
|
83
|
+
|
|
84
|
+
## References
|
|
85
|
+
|
|
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
|
|
88
|
+
|
|
89
|
+
## Finding more
|
|
90
|
+
|
|
91
|
+
`AGENTS.md` "Key Documentation" and `docs/README-PERFORMANCE.md`. `b2c docs search "storefront next performance"` or `docs_search` MCP tool.
|
|
92
|
+
|
|
93
|
+
## Related Skills
|
|
94
|
+
|
|
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,85 @@
|
|
|
1
|
+
# Performance self-review checklist
|
|
2
|
+
|
|
3
|
+
Run this on your own diff before you call a change done, especially when it adds a loader, fetcher, Suspense boundary, modal, context or action. For each section, find the relevant lines in the diff, answer the questions, and fix what fails. Related docs in your project: `docs/README-DATA.md`, `docs/README-SUSPENSE.md`, `docs/README-REVALIDATION.md`, `docs/README-PERFORMANCE.md`.
|
|
4
|
+
|
|
5
|
+
Impact of a problem is roughly: traffic of the page x instances of the component on it x cost of one occurrence. A fetch in a product tile on a listing page multiplies by every tile; a layout loader re-run multiplies by every action on every page.
|
|
6
|
+
|
|
7
|
+
## 1. Fetch efficiency
|
|
8
|
+
|
|
9
|
+
Map the fetch topology for each user gesture (load, navigation, add to cart, open modal): which loaders, fetchers and SCAPI calls run, and in what order.
|
|
10
|
+
|
|
11
|
+
- [ ] Overlapping loaders: do two active loaders read the same resource? Move it to the lowest common layout and share via `useRouteLoaderData`.
|
|
12
|
+
- [ ] Dependent data chained across round trips (fetch A, then B using A, then enrichment) belongs in one loader, with independent calls started in parallel first.
|
|
13
|
+
- [ ] Write-in-read: does a GET path create or mutate server state (for example "get or create basket")? Reads called from many places then race or duplicate writes. Separate creation from reads.
|
|
14
|
+
- [ ] Prefetch and consume: if one component prefetches and another consumes the same data, they must share one fetcher key, or the data is fetched twice.
|
|
15
|
+
- [ ] Unstable references in effect dependencies (object or array literals, fresh callbacks) re-fire fetches on every render. Depend on primitives or stable refs.
|
|
16
|
+
- [ ] Fetcher hooks inside list items: N items means N registered fetchers and, when they load on mount, N requests. A `useFetcher` used only on interaction is not amplification; one that loads on mount is. Lift the data into the parent loader or a single batched call (`fetchProductsByIds`).
|
|
17
|
+
- [ ] Payload: only the `expand`/`select` values the UI renders.
|
|
18
|
+
|
|
19
|
+
## 2. Fetcher misuse
|
|
20
|
+
|
|
21
|
+
Is this a fetcher that should be a loader?
|
|
22
|
+
|
|
23
|
+
- [ ] A fetch on mount or render whose inputs are known at request time (route params, search params, cookies, context) belongs in the loader. This includes indirect forms: `useEffect` calls an async function that calls `fetch` or `fetcher.load()`, and fetches inside error fallbacks.
|
|
24
|
+
- [ ] Does the component ignore `loaderData` and re-fetch the same data? Use the loader data.
|
|
25
|
+
- [ ] Legitimate uses: gesture-gated loads (click, hover, open), client-only inputs (geolocation, local selection), re-fetching after a mutation, intent-based prefetch.
|
|
26
|
+
|
|
27
|
+
## 3. Suspense placement
|
|
28
|
+
|
|
29
|
+
- [ ] Every `use(promise)` and `<Await>` has a `<Suspense>` ancestor.
|
|
30
|
+
- [ ] The boundary is as low as possible: it wraps only the subtree that reads the promise, not the page or layout.
|
|
31
|
+
- [ ] The fallback reserves the final size (no layout shift) and is not `null` above the fold without reserved space.
|
|
32
|
+
|
|
33
|
+
## 4. Suspense granularity
|
|
34
|
+
|
|
35
|
+
- [ ] Independent consumers have sibling boundaries, so a slow promise does not hold back a fast one.
|
|
36
|
+
- [ ] One logical unit that must appear together shares one boundary and one promise composed in the loader.
|
|
37
|
+
- [ ] No boundary wrapped around content that is already resolved.
|
|
38
|
+
|
|
39
|
+
## 5. Promise stability
|
|
40
|
+
|
|
41
|
+
A new promise object on each render restarts suspension and flashes the fallback.
|
|
42
|
+
|
|
43
|
+
- [ ] Stable sources only: `loaderData`, `useRouteLoaderData`, `useOutletContext`, props derived from them, `useRef`, `useState` lazy-pinned, module constants.
|
|
44
|
+
- [ ] No `Promise.all/race/allSettled`, `.then/.catch/.finally`, `new Promise`, or async IIFE in render. No `useMemo` around a promise.
|
|
45
|
+
- [ ] Fixes: compose and transform in the loader (`.then` there); split into separate boundaries; pin with `useState(() => ...)` or re-pin with `useRef` keyed on inputs.
|
|
46
|
+
|
|
47
|
+
## 6. Hydration and render stability
|
|
48
|
+
|
|
49
|
+
Render scope should not exceed data-change scope.
|
|
50
|
+
|
|
51
|
+
- [ ] Values read only inside event handlers or callbacks live in `useRef`, or are read at call time (for example `matchMedia` inside the handler), not in state or Context.
|
|
52
|
+
- [ ] Hidden subscribers: components that subscribe to a store but render nothing visible still re-render; return `null` early or move the subscription to the component that renders.
|
|
53
|
+
- [ ] Context values are memoized (`useMemo`/`useCallback`); check every field each consumer reads during render, and split state from updaters.
|
|
54
|
+
- [ ] Subscriptions sit at the consumer, or in a render-nothing manager that writes to a ref/store.
|
|
55
|
+
- [ ] `useSyncExternalStore`: `getServerSnapshot` matches the first client render; `getSnapshot` returns a stable reference when nothing changed.
|
|
56
|
+
|
|
57
|
+
## 7. Revalidation scope
|
|
58
|
+
|
|
59
|
+
After an action, every active loader re-runs by default.
|
|
60
|
+
|
|
61
|
+
- [ ] For each new or changed action and each active loader (matched chain, mounted resource fetchers, open modals and drawers): is there overlap (does the result change what the loader reads) and is the value otherwise unavailable (provider not already updated)? If either is false, gate the loader with `shouldRevalidate`.
|
|
62
|
+
- [ ] Confirm the trigger is a real submission (`Form`, `useSubmit`, `fetcher.submit`). Raw `fetch` or SCAPI client calls trigger nothing.
|
|
63
|
+
- [ ] Modals and drawers count twice: as targets (fetchers they load when open) and as triggers (actions they submit). Unmount them when closed (`useDeferredUnmount`).
|
|
64
|
+
- [ ] A gate must inspect the action path or `actionResult`; checking only that `formAction` is set still re-runs on everything.
|
|
65
|
+
- [ ] Do not gate off a re-run that is the sync mechanism for a provider.
|
|
66
|
+
|
|
67
|
+
See `storefront-next:sfnext-revalidation`.
|
|
68
|
+
|
|
69
|
+
## 8. Client-side transforms
|
|
70
|
+
|
|
71
|
+
- [ ] Shape data in the loader, not during render: lookup maps, chained filter/map passes, deep spreads, slug or URL normalization.
|
|
72
|
+
- [ ] `useMemo` does not fix transforming loader data on every mount; move it to the loader.
|
|
73
|
+
- [ ] Exceptions: values derived from UI state (selected variant, local filter), and work inside event handlers.
|
|
74
|
+
|
|
75
|
+
## 9. Also check
|
|
76
|
+
|
|
77
|
+
- [ ] Images: LCP image has `priority="high"` and is not lazy; `widths` match the layout.
|
|
78
|
+
- [ ] New dependency: check bundle impact with `pnpm bundlesize`; lazy-load heavy, hidden UI.
|
|
79
|
+
- [ ] Third-party scripts: `async` or `defer`, loaded after consent where required.
|
|
80
|
+
- [ ] New preconnect only for origins used on every page.
|
|
81
|
+
- [ ] Added routes export the right `shouldRevalidate`.
|
|
82
|
+
|
|
83
|
+
## Reporting
|
|
84
|
+
|
|
85
|
+
For each finding note where it is (file and line), the rule it breaks, who pays (every shopper, every tile, every action), and the smallest fix. Prefer fixing the highest-multiplier problems first.
|
package/content/guidance/storefront-next/sfnext-performance/references/SUSPENSE-AND-STREAMING.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Suspense and streaming recipes
|
|
2
|
+
|
|
3
|
+
Read `docs/README-SUSPENSE.md` in your project for the full guide.
|
|
4
|
+
|
|
5
|
+
## Placement
|
|
6
|
+
|
|
7
|
+
Every component that calls `use(promise)` or renders `<Await>` must sit under a `<Suspense>`. Place the boundary as low as possible, around only the subtree that reads the promise, so the rest of the page is not held back. A consumer with no boundary above it suspends the nearest ancestor (often the whole route) and blocks the shell.
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
// Bad: boundary wraps the page; one slow promise hides everything
|
|
11
|
+
<Suspense fallback={<PageSkeleton />}><Page /></Suspense>
|
|
12
|
+
|
|
13
|
+
// Good: boundary wraps only the reader
|
|
14
|
+
<Header />
|
|
15
|
+
<Suspense fallback={<ReviewsSkeleton />}><Reviews promise={loaderData.reviews} /></Suspense>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Granularity
|
|
19
|
+
|
|
20
|
+
- Independent data: sibling boundaries, so each resolves on its own.
|
|
21
|
+
- One logical unit that must appear together: one promise composed in the loader, one boundary.
|
|
22
|
+
- Do not nest a boundary per field of one entity; do not share one boundary across unrelated promises.
|
|
23
|
+
|
|
24
|
+
## Promise stability
|
|
25
|
+
|
|
26
|
+
Stable sources: `loaderData`, `useRouteLoaderData`, `useOutletContext`, props passed from those, `useRef`, `useState` lazy pinned, module-level constants.
|
|
27
|
+
|
|
28
|
+
Unstable (new identity each render): `Promise.all/race/allSettled` in render, `.then`/`.catch`/`.finally` chains in render, `new Promise`, async IIFEs, `useMemo(() => promise)`.
|
|
29
|
+
|
|
30
|
+
Fixes:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
// in the loader: compose there
|
|
34
|
+
const summary = Promise.all([a(), b()]).then(([x, y]) => ({ x, y }));
|
|
35
|
+
return { summary };
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
// component-local promise that depends on props: pin it
|
|
40
|
+
const [promise] = useState(() => fetchSomething(id)); // lazy pin, fixed for mount
|
|
41
|
+
// or re-pin only when the key changes
|
|
42
|
+
const ref = useRef<{ key: string; p: Promise<Data> }>();
|
|
43
|
+
if (ref.current?.key !== id) ref.current = { key: id, p: fetchSomething(id) };
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Client-side `fetchSomething` here must be a fetcher-driven or already-started promise; prefer composing in the loader whenever the data is knowable there.
|
|
47
|
+
|
|
48
|
+
## Skeletons
|
|
49
|
+
|
|
50
|
+
Size the skeleton to the final content (same height and grid) to avoid layout shift. For listing grids reuse the product-grid skeleton and `DeferredProductGrid`.
|
|
51
|
+
|
|
52
|
+
## Critical Page Designer regions
|
|
53
|
+
|
|
54
|
+
Page-level LCP region: `await` the page in the loader and render `<Region critical>` (no region fallback element). Component-level data inside keeps its own boundaries.
|
|
55
|
+
|
|
56
|
+
## Errors in streamed data
|
|
57
|
+
|
|
58
|
+
A rejected promise reaches the nearest `errorElement` on `<Await>` or the route `ErrorBoundary`. For optional sections use `errorElement={null}` and log in the loader; for important ones show an inline retry.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sfnext-project-setup
|
|
3
|
+
description: >-
|
|
4
|
+
Create and bootstrap a Storefront Next project, and learn its layout, npm scripts, and first-run workflow.
|
|
5
|
+
Use when creating a new storefront, running `sfnext create-storefront` (`--vertical` starter theme, `--defaults`,
|
|
6
|
+
`--template`, `--output-dir`), choosing between Business Manager Storefront Setup and the CLI, fixing
|
|
7
|
+
`pnpm install` / Node 24 problems, copying `.env.default` to `.env`, asking "what does this folder do" or
|
|
8
|
+
"which pnpm script do I run", or running `b2c sfnext` / `pnpm sfnext` commands for the first time.
|
|
9
|
+
Do not use for config.server.ts or PUBLIC__ env var rules (use `storefront-next:sfnext-configuration`),
|
|
10
|
+
building/pushing to Managed Runtime (use `storefront-next:sfnext-deployment`), or a conceptual tour of the
|
|
11
|
+
architecture (use `storefront-next:sfnext-overview`).
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Storefront Next Project Setup
|
|
15
|
+
|
|
16
|
+
A Storefront Next project is a server-rendered React 19 / React Router 7 / Vite / Tailwind v4 app that runs on Managed Runtime (MRT). All SCAPI calls run server-side. You own the project code after it is created.
|
|
17
|
+
|
|
18
|
+
**Read the project's own `AGENTS.md` first.** It ships in every project (`CLAUDE.md` is a copy) and is the authority for data-loading, Suspense, state, image, and navigation rules. This skill never overrides it. Detailed guides live in the project's `docs/README-*.md`.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
- Node.js >= 24 (`package.json` `engines`; MRT also runs Node 24)
|
|
23
|
+
- pnpm >= 10.28
|
|
24
|
+
- A B2C Commerce instance with a SLAS public client, your organization ID, and the SCAPI short code (unless you only want the bundled demo backend)
|
|
25
|
+
|
|
26
|
+
## Choose how to start
|
|
27
|
+
|
|
28
|
+
| Path | Use when |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| Business Manager **Storefront Setup** (GitHub or local-code workflow) | You want an instance-connected storefront. It creates the SLAS client, the MRT project/environments, initial config, and a first deployment. Reuse those resources; do not create replacement SLAS clients or MRT projects as routine setup. Use the downloaded `env.txt` as `.env`. Guides: [GitHub workflow](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-quick-start-create-bm-github.html), [local-code workflow](https://developer.salesforce.com/docs/commerce/sfnext/guide/sfnext-quick-start-create-bm.html) |
|
|
31
|
+
| `sfnext create-storefront` | You want a fresh local project from a starter theme, with your own extension selection and credentials |
|
|
32
|
+
| Clone / "Use this template" of a published starter repo | You prefer plain git; the project README lists the starter repositories |
|
|
33
|
+
|
|
34
|
+
Never invent tenant/site IDs and never echo secrets from `env.txt`.
|
|
35
|
+
|
|
36
|
+
## Create a project with the CLI
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Interactive: pick a starter theme, name, extensions, and credentials
|
|
40
|
+
pnpm dlx @salesforce/storefront-next-dev create-storefront
|
|
41
|
+
# or, with the b2c CLI (auto-installs the sfnext plugin on first use)
|
|
42
|
+
b2c sfnext create-storefront
|
|
43
|
+
|
|
44
|
+
# Non-interactive
|
|
45
|
+
sfnext create-storefront -n my-storefront --vertical cosmetic -o ./projects
|
|
46
|
+
sfnext create-storefront -n my-storefront --defaults
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
| Flag | Meaning |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| `-n, --name` | Project name |
|
|
52
|
+
| `-V, --vertical` | Starter theme: `fashion` (default with `--defaults`), `cosmetic`, `foundations`, `footwear`, `furniture`, `luxury` |
|
|
53
|
+
| `-t, --template` | Template repo URL or local path (overrides `--vertical`) |
|
|
54
|
+
| `-b, --template-branch` | Branch or tag to clone |
|
|
55
|
+
| `-d, --defaults` | Accept all defaults, no prompts (CI) |
|
|
56
|
+
| `-o, --output-dir` | Where to create the project |
|
|
57
|
+
|
|
58
|
+
What it does: shallow-clones the chosen starter, removes `.git`, asks which **extensions** to keep (and trims the rest; manage them later with `sfnext extensions ...`, see `storefront-next:sfnext-extensions`), prompts for the values in `config-meta.json` (SLAS client ID, organization ID, short code), and writes `.env` from `.env.default`.
|
|
59
|
+
|
|
60
|
+
Then:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
cd my-storefront
|
|
64
|
+
pnpm install
|
|
65
|
+
pnpm dev # http://localhost:5173
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## First run
|
|
69
|
+
|
|
70
|
+
`.env.default` ships with a public demo backend so `cp .env.default .env && pnpm dev` boots. **Only `.env` is read**; `.env.default` is never loaded. Replace the three required values with your own before pointing at real data:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
PUBLIC__app__commerce__api__clientId=...
|
|
74
|
+
PUBLIC__app__commerce__api__organizationId=...
|
|
75
|
+
PUBLIC__app__commerce__api__shortCode=...
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Restart the dev server after editing `.env`. Dev fails fast if the short code is missing. Everything else has defaults in `config.server.ts`; see `storefront-next:sfnext-configuration`. If the project should target your own site, also set `PUBLIC__app__defaultSiteId` and `PUBLIC__app__commerce__sites` (JSON array) as described there.
|
|
79
|
+
|
|
80
|
+
Before shipping, run through the pre-launch gate in `storefront-next:sfnext-deployment` (demo analytics IDs, staging image host, demo credentials).
|
|
81
|
+
|
|
82
|
+
## Project layout (short form)
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
my-storefront/
|
|
86
|
+
├── AGENTS.md / CLAUDE.md # Rules for coding agents -- read first
|
|
87
|
+
├── config.server.ts # All app config defaults (metadata / runtime / app)
|
|
88
|
+
├── config-meta.json # Values create-storefront prompts for
|
|
89
|
+
├── .env.default, .env # Required credentials; only .env is loaded
|
|
90
|
+
├── package.json # Scripts + storefrontNext version stamp
|
|
91
|
+
├── react-router.config.ts, vite.config.ts, vite-plugins/
|
|
92
|
+
├── src/
|
|
93
|
+
│ ├── routes/ # Flat file routes (_app.*, _checkout.*, _empty.*, action.*, resource.*)
|
|
94
|
+
│ ├── components/ (ui/ = primitives), hooks/, providers/, lib/, middlewares/
|
|
95
|
+
│ ├── extensions/ # Optional feature modules + config.json registry
|
|
96
|
+
│ ├── theme/ # index.css entry, tokens/, overrides/
|
|
97
|
+
│ ├── locales/ # <lang-REGION>/translations.json
|
|
98
|
+
│ ├── scapi/ # Generated + custom SCAPI clients
|
|
99
|
+
│ ├── targets/ # UI target (extension point) system
|
|
100
|
+
│ └── types/config.ts # AppConfig type
|
|
101
|
+
├── cartridges/app_storefrontnext_base # Page Designer metadata cartridge
|
|
102
|
+
├── docs/ # README-*.md guides, COMPATIBILITY.md, migrations/
|
|
103
|
+
├── instructions/ # Extension install/uninstall guides (.mdc)
|
|
104
|
+
├── e2e/ # Playwright suite (own package)
|
|
105
|
+
└── public/
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
See [PROJECT-STRUCTURE.md](references/PROJECT-STRUCTURE.md) for route families, key files, and where to go for each concern.
|
|
109
|
+
|
|
110
|
+
## Scripts and CLI
|
|
111
|
+
|
|
112
|
+
Run `pnpm <script>`. The most used: `dev`, `build`, `start` (preview the production build on :3000), `typecheck`, `lint`, `test`, `push`, `cartridge:generate|validate|deploy`, `config:inspect`, `config:push-env`, `bundlesize`, `storybook`. Full table in [SCRIPTS.md](references/SCRIPTS.md). The project's `package.json` `scripts` is the source of truth; grep it instead of guessing.
|
|
113
|
+
|
|
114
|
+
The `sfnext` binary (from `@salesforce/storefront-next-dev`, already a project dependency) is also reachable as `pnpm sfnext <cmd>` or `b2c sfnext <cmd>` (the b2c CLI prefers the project-local copy when run inside the project). Command reference: [SFNEXT-CLI.md](references/SFNEXT-CLI.md). The template also exposes `pnpm b2c` for the b2c CLI.
|
|
115
|
+
|
|
116
|
+
## Conventions worth knowing up front
|
|
117
|
+
|
|
118
|
+
- Application code is TypeScript/TSX only (`node scripts/check-typescript-only.js` flags stray `.js`). Linting is OxLint (`pnpm lint`, zero warnings), formatting is Biome (`pnpm format`).
|
|
119
|
+
- Imports use the `@/` alias to `src/`. Server-only modules are suffixed `.server.ts`.
|
|
120
|
+
- Use the site-aware `Link`/`NavLink` from `@/components/link` and `useNavigate` from `@/hooks/use-navigate`, not the React Router originals.
|
|
121
|
+
- Server `loader`/`action` only; no `clientLoader`/`clientAction`. Await only critical data; return non-critical data as promises (`storefront-next:sfnext-data-fetching`).
|
|
122
|
+
- Version compatibility between your project and the SDK: `package.json#storefrontNext` and `docs/COMPATIBILITY.md`.
|
|
123
|
+
|
|
124
|
+
## Troubleshooting
|
|
125
|
+
|
|
126
|
+
| Symptom | Cause / fix |
|
|
127
|
+
| --- | --- |
|
|
128
|
+
| `pnpm install` fails or engine warning | Node < 24 or pnpm < 10.28; upgrade both |
|
|
129
|
+
| Dev server exits immediately about short code | `PUBLIC__app__commerce__api__shortCode` missing in `.env` (not `.env.default`) |
|
|
130
|
+
| SCAPI 401/403 | Client ID / organization ID / short code do not match the same org, or the SLAS client lacks scopes; run `sfnext setup-base-cartridge --slas-client-id <id>` only if the base cartridge scopes are the issue |
|
|
131
|
+
| `.env` change ignored | Restart `pnpm dev`; check with `pnpm config:inspect` |
|
|
132
|
+
| Unknown `sfnext` command via `b2c` | First use installs the plugin; run inside the project so the local copy is used |
|
|
133
|
+
|
|
134
|
+
## Finding more
|
|
135
|
+
|
|
136
|
+
- Project `AGENTS.md` doc index and `docs/README-*.md`
|
|
137
|
+
- `b2c docs search "<topic>" --category sfnext` (or MCP `docs_search`) for the published Storefront Next guides
|
|
138
|
+
|
|
139
|
+
## Related Skills
|
|
140
|
+
|
|
141
|
+
- `storefront-next:sfnext-overview` - Architecture and concept tour
|
|
142
|
+
- `storefront-next:sfnext-configuration` - config.server.ts, PUBLIC__ env vars, multi-site URLs
|
|
143
|
+
- `storefront-next:sfnext-deployment` - Build, push to MRT, cartridge deploy, pre-launch gate
|
|
144
|
+
- `storefront-next:sfnext-routing` - File routes and site-aware links
|
|
145
|
+
- `storefront-next:sfnext-extensions` - Install, remove, and create extensions
|
|
146
|
+
- `storefront-next:sfnext-theming` - Rebranding `src/theme/`
|
|
147
|
+
- `b2c-cli:b2c-mrt` - Generic MRT project/environment management
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Project Structure
|
|
2
|
+
|
|
3
|
+
A short map of a Storefront Next project. The project's `AGENTS.md` ("Project Structure") is authoritative and kept current; use `ls` on the project rather than trusting any long listing, including this one.
|
|
4
|
+
|
|
5
|
+
## Top level
|
|
6
|
+
|
|
7
|
+
| Path | Purpose |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `AGENTS.md`, `CLAUDE.md` | Rules and doc index for coding agents |
|
|
10
|
+
| `config.server.ts` | Typed defaults for the whole app (`metadata`, `runtime`, `app`). Edited by you; overridden per environment with `PUBLIC__` env vars |
|
|
11
|
+
| `config-meta.json`, `config-metadata/` | Values `sfnext create-storefront` prompts for; config metadata |
|
|
12
|
+
| `.env.default` / `.env` | Required credentials and MRT target. Only `.env` is read |
|
|
13
|
+
| `package.json` | Scripts, dependencies, and `storefrontNext` (`templateRelease`, `templateVersion`, `minSdkVersion`) |
|
|
14
|
+
| `react-router.config.ts`, `vite.config.ts`, `vite-plugins/` | Framework and build config; plugins for bundle size, env validation, hybrid proxy, server-only-config guard |
|
|
15
|
+
| `components.json` | shadcn config (CSS entry is `src/theme/index.css`) |
|
|
16
|
+
| `cartridges/app_storefrontnext_base/` | Base cartridge; Page Designer metadata is generated into it |
|
|
17
|
+
| `docs/` | `README-*.md` guides, `COMPATIBILITY.md`, `migrations/` upgrade guides |
|
|
18
|
+
| `instructions/` | Install/uninstall instructions for extensions (`.mdc`) |
|
|
19
|
+
| `e2e/` | Playwright end-to-end and accessibility suite (its own package) |
|
|
20
|
+
| `scripts/` | Helper scripts behind `lint:a11y`, `lint:css`, `bundlesize:compare`, `storybook:test`, `extensions:list`, ... |
|
|
21
|
+
| `.storybook/`, `.github/`, `.devcontainer/`, `.claude/skills/sync-shadcn` | Storybook, CI workflows, dev container, in-project skill for syncing shadcn primitives |
|
|
22
|
+
| `public/` | Static assets (fonts, images, robots.txt, favicon) |
|
|
23
|
+
|
|
24
|
+
## `src/`
|
|
25
|
+
|
|
26
|
+
| Path | Notes |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `routes/` | Flat file routes. Families: `_app.*` (storefront shell), `_checkout.*`, `_empty.*` (login, signup, maintenance; minimal chrome), `action.*` (server mutations), `resource.*` (resource routes). Products and categories are splats: `_app.p.$.tsx`, `_app.c.$.tsx`. Orders use `$orderNo`. See `storefront-next:sfnext-routing` |
|
|
29
|
+
| `routes.ts`, `route-paths.ts` | Route registration and typed path helpers (`routeHref`) |
|
|
30
|
+
| `root.tsx`, `entry.client.tsx`, `entry.server.tsx`, `app-wrapper.tsx` | App shell and entry points. `root.tsx` imports `src/theme/index.css` |
|
|
31
|
+
| `components/` | Feature components; `components/ui/` holds UI primitives you own; `components/link` is the site-aware `Link`/`NavLink` |
|
|
32
|
+
| `hooks/` | Includes `use-navigate` and `use-current-site-and-locale-ref` |
|
|
33
|
+
| `providers/` | React context providers |
|
|
34
|
+
| `lib/` | Domain folders (`auth/`, `cart/`, `checkout/`, `product/`, `order/`, ...), `api-clients.server.ts` (`createApiClients(context)`), `url.server.ts` (`buildUrlFromContext`), `page-designer/` (registry, loader), `decorators/`, `revalidation/` |
|
|
35
|
+
| `middlewares/` | Server middlewares (`app-config`, `site-context`, `i18next`, `auth`, `basket`, `security-headers`, `logging`, ...). Ordering is in `src/server/middleware-registry.ts` |
|
|
36
|
+
| `scapi/` | Generated and custom SCAPI clients (`@/scapi` barrel); see `storefront-next:sfnext-scapi` |
|
|
37
|
+
| `extensions/` | Optional feature modules; `config.json` is the extension registry; per-extension `config.ts` / `server-config.ts` feed app config |
|
|
38
|
+
| `targets/` | UI target (extension point) system |
|
|
39
|
+
| `theme/` | `index.css` entry, `base.css`, `tailwind.css`, `tokens/`, `overrides/`, `animations.css`; see `storefront-next:sfnext-theming` |
|
|
40
|
+
| `locales/` | One folder per language-region (`en-US`, `de-DE`, ...) with `translations.json`; see `storefront-next:sfnext-i18n` |
|
|
41
|
+
| `types/config.ts` | `AppConfig` / `Config` types and the `getConfig` / `useConfig` type augmentation |
|
|
42
|
+
| `analytics/`, `design-system/`, `test-utils/` | Tracking components, design-system docs stories, shared test helpers (`@/test-utils/config`, `context-provider`, `request-helpers`, ...) |
|
|
43
|
+
|
|
44
|
+
## Where to look for each concern
|
|
45
|
+
|
|
46
|
+
| Concern | Start here |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| Data loading, Suspense, state, images | `AGENTS.md` "Performance & Data Rules", `docs/README-DATA.md`, `README-SUSPENSE.md`, `README-STATE.md` |
|
|
49
|
+
| All config options | `docs/README-CONFIG.md` (required/optional tables), `docs/README-CONFIG-OPTIONS.md` |
|
|
50
|
+
| Multi-site, locale URLs, SEO routes | `docs/README-MULTI-SITE.md` |
|
|
51
|
+
| Auth and cookies | `docs/README-AUTH.md` |
|
|
52
|
+
| Page Designer | `docs/README-PAGE-DESIGNER.md` |
|
|
53
|
+
| Upgrading | `docs/COMPATIBILITY.md`, `docs/migrations/` |
|
|
54
|
+
|
|
55
|
+
## Page Designer metadata
|
|
56
|
+
|
|
57
|
+
Component metadata is generated from decorators by `pnpm cartridge:generate` (also run by `pnpm build`) into `cartridges/app_storefrontnext_base/`, validated with `pnpm cartridge:validate`, and deployed to the B2C instance with `pnpm cartridge:deploy` (not part of `pnpm push`). See `storefront-next:sfnext-deployment` and `storefront-next:sfnext-page-designer`.
|
|
58
|
+
|
|
59
|
+
## Adding UI primitives
|
|
60
|
+
|
|
61
|
+
The project ships an in-project `sync-shadcn` skill (`.claude/skills/sync-shadcn`) and `scripts/upgrade-shadcn.js` for pulling updated shadcn primitives into `src/components/ui/` without losing local changes. Prefer that over a raw `npx shadcn add`.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Project Scripts
|
|
2
|
+
|
|
3
|
+
Scripts in a Storefront Next project's `package.json`. Run with `pnpm <name>`; extra flags after the name are forwarded (`pnpm test --coverage`). If a script here is missing in your project, `grep -A60 '"scripts"' package.json` -- your project is the source of truth.
|
|
4
|
+
|
|
5
|
+
## Develop and run
|
|
6
|
+
|
|
7
|
+
| Script | Does |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `dev` | Aggregates extension locales and config, then starts `sfnext dev` (Vite SSR, HMR) on http://localhost:5173. Runs with the `dev-data-store` Node condition |
|
|
10
|
+
| `dev:debug` | Same with `--inspect` for a Node debugger |
|
|
11
|
+
| `dev:log` | Dev with `SFCC_LOG_LEVEL=debug` |
|
|
12
|
+
| `build` | `locales:aggregate-extensions`, `config:aggregate-extensions`, `cartridge:generate`, then `react-router build` -> `build/` |
|
|
13
|
+
| `start` / `preview` | `sfnext preview`: serves the production build on http://localhost:3000 (builds if needed; `SFNEXT_DATA_STORE_UNAVAILABLE_MODE=fallback`) |
|
|
14
|
+
|
|
15
|
+
## Deploy and operate
|
|
16
|
+
|
|
17
|
+
| Script | Does |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `push` | `sfnext push --project-directory .` -- uploads `build/` to Managed Runtime. Build first. Pass flags after it: `pnpm push -- --wait -e staging` |
|
|
20
|
+
| `cartridge:generate` | `sfnext generate-cartridge` -- Page Designer metadata from decorators |
|
|
21
|
+
| `cartridge:validate` | `sfnext validate-cartridge` -- validate metadata JSON against schemas |
|
|
22
|
+
| `cartridge:deploy` | `sfnext deploy-cartridge` -- upload cartridges to the B2C instance (`-- --delete` wipes old files first) |
|
|
23
|
+
| `config:inspect` | `sfnext config inspect` -- show which `config.server.ts` values are overridden by `.env` or MRT |
|
|
24
|
+
| `config:push-env` | `b2c mrt env var push` -- sync `.env` variables to an MRT environment |
|
|
25
|
+
| `config:aggregate-extensions`, `locales:aggregate-extensions` | Merge per-extension config / translations; run automatically by `dev`, `build`, `typecheck` |
|
|
26
|
+
| `b2c` | Run the b2c CLI from the project (`pnpm b2c --help`) |
|
|
27
|
+
|
|
28
|
+
## Quality
|
|
29
|
+
|
|
30
|
+
| Script | Does |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `typecheck` | Aggregate extension config, `react-router typegen`, then `tsc --noEmit` |
|
|
33
|
+
| `lint` / `lint:fix` | OxLint (type-aware, zero warnings) plus Biome format check / fix |
|
|
34
|
+
| `format` / `format:check` | Biome |
|
|
35
|
+
| `lint:a11y`, `lint:css`, `a11y:scan-coverage` | Static accessibility lint, CSS/token lint, a11y scan coverage report |
|
|
36
|
+
| `test` / `test:watch` | Vitest (`pnpm test src/components/foo` for one path) |
|
|
37
|
+
| `storybook` | Storybook on http://localhost:6006 |
|
|
38
|
+
| `storybook:build` | Static Storybook build |
|
|
39
|
+
| `storybook:test` | Story tests: `--type=snapshot \| interaction \| a11y`, `--static`, `--update` |
|
|
40
|
+
| `bundlesize` | Build with `BUNDLES_SIZE_CHECK=true` to enforce bundle limits |
|
|
41
|
+
| `bundlesize:compare` | Compare bundle sizes between builds |
|
|
42
|
+
| `lighthouse:ci` | Lighthouse CI run |
|
|
43
|
+
| `extensions:list` | List extension points |
|
|
44
|
+
| `e2e`, `e2e:turnstile`, `a11y` | Playwright suites in `e2e/` |
|
|
45
|
+
| `chromatic:core` | Chromatic visual-test helper |
|
|
46
|
+
|
|
47
|
+
Bundle treemap: `cross-env BUNDLES_SIZE_ANALYZE=true pnpm build` (writes `build/client-bundle-size.html`).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# `sfnext` CLI
|
|
2
|
+
|
|
3
|
+
The `sfnext` binary comes from `@salesforce/storefront-next-dev`. Ways to run it:
|
|
4
|
+
|
|
5
|
+
- `pnpm sfnext <command>` or a project script (`pnpm dev`, `pnpm push`, ...) inside the project
|
|
6
|
+
- `b2c sfnext <command>` -- the b2c CLI installs the plugin on first use and, when run inside a project, prefers the project's local copy
|
|
7
|
+
- `pnpm dlx @salesforce/storefront-next-dev <command>` for commands that run before a project exists (`create-storefront`)
|
|
8
|
+
|
|
9
|
+
Most commands take `-d, --project-directory` (default: current directory). `.env` in the project directory is loaded automatically (not `.env.default`).
|
|
10
|
+
|
|
11
|
+
## Project lifecycle
|
|
12
|
+
|
|
13
|
+
| Command | Purpose |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `create-storefront` | Create a project from a starter theme. Flags: `-n` name, `-V` starter theme (`fashion`, `cosmetic`, `foundations`, `footwear`, `furniture`, `luxury`), `-t` template URL/path, `-b` branch/tag, `-d` defaults, `-o` output dir |
|
|
16
|
+
| `dev` | Vite dev server with SSR. `-p, --port` (default 5173) |
|
|
17
|
+
| `preview` | Serve the production build, building if needed. `-p, --port` (default 3000) |
|
|
18
|
+
| `create-bundle` | Create an MRT bundle in `.bundle/` without pushing. `-b` build dir, `-o` output dir, `-m` message, `-s` project slug |
|
|
19
|
+
| `push` | Upload the build to Managed Runtime. See below |
|
|
20
|
+
|
|
21
|
+
## Managed Runtime push
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm build && pnpm push -- -m "Release notes" -e staging --wait
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Flag | Meaning |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| `-m, --message` | Bundle message (default: git branch:commit) |
|
|
30
|
+
| `-w, --wait` | Wait for the deployment to finish; requires a target environment |
|
|
31
|
+
| `-b, --build-directory` | Build dir (default: auto-detected `build/`) |
|
|
32
|
+
| `-p, --project` | MRT project slug (env `MRT_PROJECT`, then `SFCC_MRT_PROJECT`, then dw.json `mrtProject`) |
|
|
33
|
+
| `-e, --environment` | Target environment (env `MRT_TARGET`). Without one the bundle is uploaded but not deployed |
|
|
34
|
+
| `--api-key`, `--credentials-file`, `--cloud-origin` | MRT credentials (env `MRT_API_KEY`, `MRT_CREDENTIALS_FILE`, `MRT_CLOUD_ORIGIN`; or `~/.mobify`) |
|
|
35
|
+
|
|
36
|
+
`push` does not build; it fails if the build directory is missing.
|
|
37
|
+
|
|
38
|
+
## Cartridges (Page Designer metadata)
|
|
39
|
+
|
|
40
|
+
| Command | Purpose |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `generate-cartridge` | Generate component metadata from decorators into `cartridges/app_storefrontnext_base` |
|
|
43
|
+
| `validate-cartridge` | Validate the generated JSON |
|
|
44
|
+
| `deploy-cartridge` | Upload cartridges to a B2C instance. Instance settings come from flags, env, or `dw.json`. Flags: `-s, --server`, `-v, --code-version`, `-r, --reload` (re-activate), `--delete` (remove old files first), `-c` include / `-x` exclude cartridges |
|
|
45
|
+
| `setup-base-cartridge` | Register the SLAS scopes the base cartridge needs: `--slas-client-id <id>` (needs short code and tenant ID from flags/env/dw.json) |
|
|
46
|
+
|
|
47
|
+
Deploying cartridges needs WebDAV credentials; without `--code-version` it also needs OAuth credentials to discover the active code version.
|
|
48
|
+
|
|
49
|
+
## Configuration and extensions
|
|
50
|
+
|
|
51
|
+
| Command | Purpose |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `config inspect` | Show which `config.server.ts` values are overridden by `.env` or MRT (`--project`, `--environment` to include MRT values) |
|
|
54
|
+
| `config aggregate-extensions`, `locales aggregate-extensions` | Merge extension config / translations (run by `dev`, `build`, `typecheck`) |
|
|
55
|
+
| `extensions list` | List installed extensions |
|
|
56
|
+
| `extensions install -e <SFDC_EXT_...>` | Install an extension |
|
|
57
|
+
| `extensions remove -e <A,B>` | Remove extensions (`--yes` to also remove dependents) |
|
|
58
|
+
| `extensions create -n "<Name>" -d "<desc>"` | Scaffold a new extension (`-p` target project dir) |
|
|
59
|
+
| `create-instructions` | Generate install/uninstall instruction files for an extension you author |
|
|
60
|
+
|
|
61
|
+
## SCAPI clients
|
|
62
|
+
|
|
63
|
+
`sfnext scapi available | add | list | remove` manage typed SCAPI clients, including custom APIs. See `storefront-next:sfnext-scapi`.
|