@salesforce/afv-skills 1.41.0 → 1.43.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.
Files changed (288) hide show
  1. package/package.json +2 -6
  2. package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +3 -0
  3. package/skills/automation-sandbox-post-copy-configure/SKILL.md +4 -0
  4. package/skills/design-systems-slds-validate/SKILL.md +2 -2
  5. package/skills/dx-app-analytics-query/SKILL.md +1 -3
  6. package/skills/dx-devops-conflict-resolve/SKILL.md +205 -0
  7. package/skills/dx-devops-conflict-resolve/examples/conflict-workflows.md +165 -0
  8. package/skills/dx-devops-conflict-resolve/references/deploy-failure-resolution.md +75 -0
  9. package/skills/dx-devops-conflict-resolve/references/git-conflict-resolution.md +124 -0
  10. package/skills/dx-devops-conflict-resolve/scripts/detect-conflicts.sh +91 -0
  11. package/skills/dx-devops-conflict-resolve/scripts/diagnose-deploy-failure.sh +156 -0
  12. package/skills/dx-devops-request-status/SKILL.md +160 -0
  13. package/skills/dx-devops-request-status/examples/polling-workflows.md +101 -0
  14. package/skills/dx-devops-request-status/references/cli-commands.md +176 -0
  15. package/skills/dx-devops-request-status/scripts/poll-status.sh +134 -0
  16. package/skills/dx-devops-test-failures-analyze/SKILL.md +6 -6
  17. package/skills/dx-devops-test-pipeline-configure/SKILL.md +7 -7
  18. package/skills/dx-devops-test-suite-assignments-configure/SKILL.md +6 -6
  19. package/skills/dx-devops-test-suite-run/SKILL.md +6 -6
  20. package/skills/dx-devops-work-item-manage/SKILL.md +2 -0
  21. package/skills/dx-org-manage/references/creating-scratch-org.md +5 -2
  22. package/skills/dx-org-manage/references/creating-snapshot.md +1 -0
  23. package/skills/dx-org-shape-manage/SKILL.md +152 -0
  24. package/skills/dx-org-shape-manage/examples/create_error_output.json +9 -0
  25. package/skills/dx-org-shape-manage/examples/create_success_output.json +9 -0
  26. package/skills/dx-org-shape-manage/examples/delete_output.json +11 -0
  27. package/skills/dx-org-shape-manage/examples/list_inactive_output.json +32 -0
  28. package/skills/dx-org-shape-manage/examples/list_output.json +24 -0
  29. package/skills/dx-org-shape-manage/references/cli_flags.md +135 -0
  30. package/skills/dx-org-switch/SKILL.md +2 -2
  31. package/skills/dx-org-trial-expiration-check/SKILL.md +2 -0
  32. package/skills/dx-pkg-post-install-configure/SKILL.md +3 -0
  33. package/skills/education-cloud-multi-campus-configure/SKILL.md +211 -0
  34. package/skills/education-cloud-multi-campus-configure/examples/hierarchy_visualization.md +174 -0
  35. package/skills/education-cloud-multi-campus-configure/examples/output_examples.md +54 -0
  36. package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input.csv +29 -0
  37. package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input_edgecases.csv +16 -0
  38. package/skills/education-cloud-multi-campus-configure/references/account_recordtype_prerequisite.md +44 -0
  39. package/skills/education-cloud-multi-campus-configure/references/delta_computation.md +33 -0
  40. package/skills/education-cloud-multi-campus-configure/references/error_handling.md +198 -0
  41. package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +54 -0
  42. package/skills/education-cloud-multi-campus-configure/references/gotchas.md +16 -0
  43. package/skills/education-cloud-multi-campus-configure/references/hierarchy_parsing_rules.md +133 -0
  44. package/skills/education-cloud-multi-campus-configure/references/mcp-invocation.md +75 -0
  45. package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/SKILL.md +1 -1
  46. package/skills/experience-cms-brand-apply/SKILL.md +4 -1
  47. package/skills/experience-cms-brand-create/SKILL.md +197 -0
  48. package/skills/experience-cms-brand-create/assets/brand-template.json +329 -0
  49. package/skills/experience-cms-brand-create/references/brand-anatomy.md +120 -0
  50. package/skills/experience-cms-brand-create/references/disk-contract.md +84 -0
  51. package/skills/experience-cms-content-generate/SKILL.md +190 -0
  52. package/skills/experience-cms-content-generate/assets/display-formats.md +84 -0
  53. package/skills/experience-cms-content-generate/assets/payloads/create-content-bulk.json +11 -0
  54. package/skills/experience-cms-content-generate/assets/payloads/create-content-single.json +11 -0
  55. package/skills/experience-cms-content-generate/assets/payloads/publish-content.json +4 -0
  56. package/skills/experience-cms-content-generate/assets/payloads/update-content.json +9 -0
  57. package/skills/experience-cms-content-generate/assets/questions.md +241 -0
  58. package/skills/experience-cms-content-generate/examples/create-content-call.md +81 -0
  59. package/skills/experience-cms-content-generate/references/bulk-batching.md +56 -0
  60. package/skills/experience-cms-content-generate/references/content-type-classification.md +88 -0
  61. package/skills/experience-cms-content-generate/references/content-write-tool.md +95 -0
  62. package/skills/experience-cms-content-generate/references/delegation-protocol.md +37 -0
  63. package/skills/experience-cms-content-generate/references/edit-publish-workflow.md +63 -0
  64. package/skills/experience-cms-content-generate/references/error-recovery.md +72 -0
  65. package/skills/experience-cms-content-generate/references/identifier-resolution.md +26 -0
  66. package/skills/experience-cms-content-generate/references/intent-routing.md +45 -0
  67. package/skills/experience-cms-content-generate/references/principles.md +19 -0
  68. package/skills/experience-cms-content-generate/references/ux-rules.md +68 -0
  69. package/skills/experience-cms-content-generate/references/workspace-resolution.md +33 -0
  70. package/skills/experience-cms-content-type-generate/SKILL.md +449 -0
  71. package/skills/experience-cms-content-type-generate/assets/discovery-prompts.md +79 -0
  72. package/skills/experience-cms-content-type-generate/assets/schema-example.json +70 -0
  73. package/skills/experience-cms-content-type-generate/references/agent-checklist.md +50 -0
  74. package/skills/experience-cms-content-type-generate/references/anti-patterns.md +39 -0
  75. package/skills/experience-cms-content-type-generate/references/deployment-errors.md +27 -0
  76. package/skills/experience-cms-content-type-generate/references/discovery-details.md +106 -0
  77. package/skills/experience-cms-content-type-generate/references/discovery-query-rules.md +85 -0
  78. package/skills/experience-cms-content-type-generate/references/edit-fields-loop.md +48 -0
  79. package/skills/experience-cms-content-type-generate/references/pre-deploy-checklist.md +21 -0
  80. package/skills/experience-cms-content-type-generate/references/retrieve-and-reconcile.md +105 -0
  81. package/skills/experience-cms-content-type-generate/references/schema-rules.md +51 -0
  82. package/skills/experience-cms-content-type-generate/references/schema-summary-format.md +60 -0
  83. package/skills/experience-lds-graphql-generate/SKILL.md +4 -0
  84. package/skills/experience-lwc-accessibility-jest-run/SKILL.md +79 -0
  85. package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +205 -0
  86. package/skills/experience-lwc-design-generate/SKILL.md +5 -4
  87. package/skills/experience-lwc-generate/SKILL.md +10 -9
  88. package/skills/experience-ui-bundle-deploy/references/dev-preview.md +21 -0
  89. package/skills/experience-ui-bundle-deploy/references/social-login.md +1 -0
  90. package/skills/experience-ui-bundle-file-upload-generate/SKILL.md +6 -6
  91. package/skills/experience-ui-bundle-localize/SKILL.md +30 -37
  92. package/skills/experience-ui-bundle-localize/references/gotchas.md +23 -7
  93. package/skills/experience-ui-bundle-localize/references/i18n-setup.md +48 -4
  94. package/skills/experience-ui-bundle-localize/references/label-xml.md +22 -8
  95. package/skills/experience-ui-bundle-localize/references/verifying.md +39 -11
  96. package/skills/experience-ui-bundle-localize/scripts/detect-bundle-type.sh +118 -15
  97. package/skills/experience-ui-bundle-localize/scripts/tests/test-detect-bundle-type.sh +187 -0
  98. package/skills/experience-ui-bundle-mfa-configure/SKILL.md +13 -2
  99. package/skills/experience-ui-bundle-mfa-configure/references/social-login.md +1 -0
  100. package/skills/experience-ui-bundle-project-generate/SKILL.md +2 -2
  101. package/skills/integration-connectivity-generate/SKILL.md +11 -10
  102. package/skills/integration-eventing-cdc-configure/SKILL.md +6 -6
  103. package/skills/integration-eventing-subscription-configure/SKILL.md +6 -5
  104. package/skills/mobile-platform-native-capabilities-integrate/SKILL.md +2 -2
  105. package/skills/mobile-platform-offline-validate/scripts/package.json +1 -1
  106. package/skills/platform-agentexchange-partner-offers-configure/SKILL.md +8 -8
  107. package/skills/platform-custom-application-generate/SKILL.md +2 -0
  108. package/skills/platform-custom-field-generate/SKILL.md +8 -6
  109. package/skills/platform-custom-metadata-type-generate/SKILL.md +460 -0
  110. package/skills/platform-custom-metadata-type-generate/references/cmdt-records.md +251 -0
  111. package/skills/platform-custom-metadata-type-generate/scripts/sanitize-developer-name.sh +46 -0
  112. package/skills/platform-custom-setting-generate/SKILL.md +419 -0
  113. package/skills/platform-dataspace-access-configure/SKILL.md +3 -3
  114. package/skills/platform-sharing-owd-configure/SKILL.md +3 -0
  115. package/skills/platform-value-set-generate/SKILL.md +2 -0
  116. package/skills/service-agentforce-channel-configure/SKILL.md +29 -20
  117. package/skills/service-agentforce-channel-configure/assets/BotEmailDefinition.botEmailDefinition-meta.xml +36 -0
  118. package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email +17 -0
  119. package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email-meta.xml +29 -0
  120. package/skills/service-agentforce-channel-configure/assets/mdapi-package.xml +25 -0
  121. package/skills/service-agentforce-channel-configure/assets/settings-mdapi-package.xml +30 -0
  122. package/skills/service-agentforce-channel-configure/references/agent-wiring.md +20 -0
  123. package/skills/service-agentforce-channel-configure/references/botemaildefinition.md +107 -0
  124. package/skills/service-agentforce-channel-configure/references/channel-branch-email.md +203 -50
  125. package/skills/service-agentforce-channel-configure/references/channel-types.md +30 -3
  126. package/skills/service-agentforce-channel-configure/references/queue-resolution.md +17 -8
  127. package/skills/service-agentforce-channel-configure/references/routing-flow.md +14 -3
  128. package/skills/service-agentforce-channel-configure/scripts/validate-botemaildefinition.py +126 -0
  129. package/skills/service-agentforce-channel-configure/scripts/validate-emailtemplate.py +133 -0
  130. package/skills/service-de-channel-activate/SKILL.md +271 -0
  131. package/skills/service-de-channel-activate/references/gotchas.md +31 -0
  132. package/skills/service-de-channel-activate/references/phone-verification.md +96 -0
  133. package/skills/service-de-channel-activate/references/worked-examples.md +14 -0
  134. package/skills/service-de-channel-consent-configure/SKILL.md +230 -0
  135. package/skills/service-de-channel-consent-configure/references/gotchas.md +41 -0
  136. package/skills/service-de-channel-consent-configure/references/language-keywords.md +84 -0
  137. package/skills/service-de-channel-consent-configure/references/worked-examples.md +134 -0
  138. package/skills/service-de-channel-create/SKILL.md +369 -0
  139. package/skills/service-de-channel-create/references/apple.md +59 -0
  140. package/skills/service-de-channel-create/references/connect-insert.md +84 -0
  141. package/skills/service-de-channel-create/references/facebook.md +154 -0
  142. package/skills/service-de-channel-create/references/line.md +66 -0
  143. package/skills/service-de-channel-create/references/sms.md +98 -0
  144. package/skills/service-de-channel-create/references/whatsapp.md +98 -0
  145. package/skills/service-de-channel-create/references/worked-examples.md +70 -0
  146. package/skills/service-de-channel-routing-configure/SKILL.md +345 -0
  147. package/skills/service-de-channel-routing-configure/references/asa-routing.md +90 -0
  148. package/skills/service-de-channel-routing-configure/references/gotchas.md +27 -0
  149. package/skills/service-de-channel-routing-configure/references/queue-creation.md +123 -0
  150. package/skills/service-de-channel-routing-configure/references/target-locate.md +98 -0
  151. package/skills/service-de-channel-routing-configure/references/worked-examples.md +174 -0
  152. package/skills/service-de-headless-channel-configure/SKILL.md +305 -0
  153. package/skills/service-de-headless-channel-configure/references/gotchas.md +27 -0
  154. package/skills/service-de-headless-channel-configure/references/inputs.md +49 -0
  155. package/skills/service-de-headless-channel-configure/references/output-envelopes.md +53 -0
  156. package/skills/service-de-headless-channel-configure/references/partial-success.md +24 -0
  157. package/skills/service-de-headless-channel-configure/references/terms-and-conditions.md +54 -0
  158. package/skills/service-de-headless-channel-configure/references/worked-examples.md +108 -0
  159. package/skills/service-de-waba-integrate/SKILL.md +227 -0
  160. package/skills/service-digital-engagement-channel-configure/scripts/check-api-version.sh +29 -0
  161. package/skills/service-digital-engagement-messaging-site-integrate/SKILL.md +10 -9
  162. package/skills/service-digital-engagement-messaging-site-integrate/references/lwr_patch.md +39 -21
  163. package/skills/service-digital-engagement-messaging-site-integrate/scripts/patch_lwr_bundle.sh +157 -96
  164. package/skills/service-email-to-case-configure/SKILL.md +190 -0
  165. package/skills/service-email-to-case-configure/assets/CaseSettings.settings-meta.xml +45 -0
  166. package/skills/service-email-to-case-configure/examples/CaseSettings-two-addresses.settings-meta.xml +36 -0
  167. package/skills/service-email-to-case-configure/references/apply-mechanics.md +73 -0
  168. package/skills/service-email-to-case-configure/references/routing_address_reference.md +73 -0
  169. package/skills/service-email-to-case-configure/references/troubleshooting.md +25 -0
  170. package/skills/service-email-to-case-configure/scripts/apply-casesettings.py +1315 -0
  171. package/skills/service-email-to-case-configure/scripts/check-agent-email-capability.sh +26 -0
  172. package/skills/service-email-to-case-configure/scripts/tests/__init__.py +0 -0
  173. package/skills/service-email-to-case-configure/scripts/tests/_bootstrap.py +45 -0
  174. package/skills/service-email-to-case-configure/scripts/tests/_fakeorg.py +366 -0
  175. package/skills/service-email-to-case-configure/scripts/tests/_run.py +84 -0
  176. package/skills/service-email-to-case-configure/scripts/tests/test_apply_org_scenarios.py +655 -0
  177. package/skills/service-email-to-case-configure/scripts/tests/test_get_session.py +134 -0
  178. package/skills/service-email-to-case-configure/scripts/tests/test_new_capabilities.py +193 -0
  179. package/skills/service-email-to-case-configure/scripts/tests/test_validate_casesettings.py +170 -0
  180. package/skills/service-email-to-case-configure/scripts/validate-casesettings.py +229 -0
  181. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +33 -15
  182. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -47
  183. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +17 -12
  184. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/references/cli-invocation.md +5 -3
  185. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-enable-plan.mjs +11 -3
  186. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +8 -6
  187. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/references/cli-invocation.md +3 -3
  188. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/scripts/classify-readiness.mjs +11 -3
  189. package/skills/service-itsm-agentic-setup-configure/SKILL.md +5 -5
  190. package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +5 -5
  191. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +2 -2
  192. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +11 -7
  193. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +20 -7
  194. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +10 -6
  195. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/action-availability.md +7 -7
  196. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +11 -7
  197. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/build-create-body.mjs +24 -17
  198. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-action-availability.mjs +98 -58
  199. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +20 -7
  200. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/strip-release-management.mjs +176 -0
  201. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +19 -19
  202. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/cli-invocation.md +3 -4
  203. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/helper-contracts.md +6 -6
  204. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/permset-topology.md +3 -10
  205. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-permset-availability.mjs +7 -9
  206. package/skills/service-itsm-incident-mgmt-configure/SKILL.md +2 -0
  207. package/skills/service-itsm-incident-priority-configure/SKILL.md +15 -12
  208. package/skills/service-itsm-incident-priority-configure/examples/matrix-operations.md +27 -1
  209. package/skills/service-itsm-incident-priority-configure/references/sf-cli-invocation.md +37 -6
  210. package/skills/service-native-voice-recording-transcription-configure/SKILL.md +146 -0
  211. package/skills/service-native-voice-recording-transcription-configure/assets/confirmation-output.json +16 -0
  212. package/skills/service-native-voice-recording-transcription-configure/assets/package.xml +22 -0
  213. package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +101 -0
  214. package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +181 -0
  215. package/skills/data360-activate/README.md +0 -38
  216. package/skills/data360-activate/SKILL.md +0 -127
  217. package/skills/data360-connect/README.md +0 -57
  218. package/skills/data360-connect/SKILL.md +0 -163
  219. package/skills/data360-connect/examples/connections/heroku-postgres.json +0 -15
  220. package/skills/data360-connect/examples/connections/ingest-api-connection.json +0 -5
  221. package/skills/data360-connect/examples/connections/ingest-api-schema.json +0 -31
  222. package/skills/data360-connect/examples/connections/redshift.json +0 -16
  223. package/skills/data360-connect/examples/connections/sharepoint-unstructured.json +0 -20
  224. package/skills/data360-connect/examples/connections/snowflake-connection.json +0 -42
  225. package/skills/data360-harmonize/README.md +0 -31
  226. package/skills/data360-harmonize/SKILL.md +0 -126
  227. package/skills/data360-orchestrate/README.md +0 -120
  228. package/skills/data360-orchestrate/SKILL.md +0 -263
  229. package/skills/data360-orchestrate/assets/definitions/activation-target.template.json +0 -5
  230. package/skills/data360-orchestrate/assets/definitions/activation.template.json +0 -7
  231. package/skills/data360-orchestrate/assets/definitions/calculated-insight.template.json +0 -7
  232. package/skills/data360-orchestrate/assets/definitions/data-action-target.template.json +0 -5
  233. package/skills/data360-orchestrate/assets/definitions/data-action.template.json +0 -5
  234. package/skills/data360-orchestrate/assets/definitions/data-graph.template.json +0 -21
  235. package/skills/data360-orchestrate/assets/definitions/data-stream.template.json +0 -55
  236. package/skills/data360-orchestrate/assets/definitions/dmo.template.json +0 -17
  237. package/skills/data360-orchestrate/assets/definitions/identity-resolution.template.json +0 -30
  238. package/skills/data360-orchestrate/assets/definitions/mapping.template.json +0 -14
  239. package/skills/data360-orchestrate/assets/definitions/relationship.template.json +0 -12
  240. package/skills/data360-orchestrate/assets/definitions/search-index.template.json +0 -9
  241. package/skills/data360-orchestrate/assets/definitions/segment.template.json +0 -16
  242. package/skills/data360-orchestrate/references/feature-readiness.md +0 -157
  243. package/skills/data360-orchestrate/references/plugin-setup.md +0 -138
  244. package/skills/data360-orchestrate/scripts/bootstrap-plugin.sh +0 -53
  245. package/skills/data360-orchestrate/scripts/diagnose-org.mjs +0 -511
  246. package/skills/data360-orchestrate/scripts/generate-manifest.mjs +0 -68
  247. package/skills/data360-orchestrate/scripts/verify-plugin.sh +0 -58
  248. package/skills/data360-prepare/README.md +0 -50
  249. package/skills/data360-prepare/SKILL.md +0 -203
  250. package/skills/data360-prepare/examples/ingestion-api/.env.example +0 -8
  251. package/skills/data360-prepare/examples/ingestion-api/README.md +0 -48
  252. package/skills/data360-prepare/examples/ingestion-api/send-data.py +0 -144
  253. package/skills/data360-query/README.md +0 -43
  254. package/skills/data360-query/SKILL.md +0 -128
  255. package/skills/data360-query/examples/search-indexes/hybrid-structured.json +0 -44
  256. package/skills/data360-query/examples/search-indexes/vector-knowledge.json +0 -43
  257. package/skills/data360-segment/README.md +0 -35
  258. package/skills/data360-segment/SKILL.md +0 -123
  259. package/skills/service-helpagent-coordinate/references/channel-help-portal.md +0 -22
  260. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-1-1-non-text-content.md +0 -0
  261. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-i-lists.md +0 -0
  262. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-ii-tables.md +0 -0
  263. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iii-form-labels.md +0 -0
  264. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iv-regions.md +0 -0
  265. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-v-groups.md +0 -0
  266. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-5-identify-input.md +0 -0
  267. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-4-3-contrast.md +0 -0
  268. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-1-1-keyboard.md +0 -0
  269. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-4-link-purpose.md +0 -0
  270. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-6-headings-labels.md +0 -0
  271. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -0
  272. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -0
  273. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-3-label-in-name.md +0 -0
  274. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-7-dragging-movement.md +0 -0
  275. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-1-on-focus.md +0 -0
  276. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-2-on-input.md +0 -0
  277. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-1-error-identification.md +0 -0
  278. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-2-labels-instructions.md +0 -0
  279. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-3-error-suggestion.md +0 -0
  280. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-i-name.md +0 -0
  281. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-ii-role.md +0 -0
  282. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-iii-value.md +0 -0
  283. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-1-1-non-text-content.md +0 -0
  284. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-1-use-of-color.md +0 -0
  285. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-10-resize-reflow.md +0 -0
  286. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-11-non-text-contrast.md +0 -0
  287. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-3-contrast.md +0 -0
  288. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/scripts/contrast-ratio.py +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: experience-ui-bundle-localize
3
- description: "MUST activate to localize / internationalize a uiBundles/*/src/ React project: extract hardcoded user-facing strings into Custom Labels, wire i18next over the Platform SDK GraphQL backend, add a language to a localized bundle, or troubleshoot label rendering across locales. Triggers: user-facing string literals in .tsx/.jsx, a CustomLabels.labels-meta.xml, a src/i18n/ directory or label-manifest.ts, t(…) calls, or requests to 'translate / localize / internationalize / support another language.' Scope: authenticated UI Bundles only (B2E CustomApplication-bound, or in-core accessCheck-bound apps). DO NOT TRIGGER when: the bundle is a site (B2C/B2B) app bound to a DigitalExperienceConfig (site localization not yet supported), building app shell/UI or styling, reading/writing/refreshing records (use experience-ui-bundle-salesforce-data-access), generating a new bundle (use experience-ui-bundle-frontend-generate), deploying (use experience-ui-bundle-deploy), or authoring translations in Translation Workbench."
3
+ description: "MUST activate to localize / internationalize a uiBundles/*/src/ React project: extract hardcoded user-facing strings into Custom Labels, wire i18next over the Platform SDK GraphQL backend, add labels for another language, or troubleshoot label rendering across locales. Triggers: user-facing string literals in .tsx/.jsx, a CustomLabels.labels-meta.xml, a src/i18n/ directory or label-manifest.ts, t(…) calls, or requests to 'translate / localize / internationalize / support another language.' Scope: authenticated B2E UI Bundles and B2C site bundles. Use experience-ui-bundle-site-generate instead for site language configuration or sfdc_cms__languageSettings. DO NOT TRIGGER for B2B site bundles, building app shell/UI or styling, reading/writing/refreshing records (use experience-ui-bundle-salesforce-data-access), generating a new bundle (use experience-ui-bundle-frontend-generate), deploying (use experience-ui-bundle-deploy), or authoring translations in Translation Workbench."
4
4
  metadata:
5
5
  version: "1.0"
6
6
  domains: ["Experience"]
@@ -9,6 +9,7 @@ metadata:
9
9
  - "experience-ui-bundle-deploy"
10
10
  - "experience-ui-bundle-frontend-generate"
11
11
  - "experience-ui-bundle-salesforce-data-access"
12
+ - "experience-ui-bundle-site-generate"
12
13
  cliTools:
13
14
  - tool: ["jq"]
14
15
  semver: ">=1.6"
@@ -20,7 +21,7 @@ metadata:
20
21
 
21
22
  # Localize a React UI Bundle
22
23
 
23
- Walk a developer through localizing a React UI Bundle: detect hardcoded user-facing strings, extract them into Salesforce Custom Labels, wire up i18next over the Platform SDK GraphQL backend, and verify labels render across locales.
24
+ Localize a React UI Bundle: extract user-facing strings into Salesforce Custom Labels, wire i18next over the Platform SDK GraphQL backend, and verify labels across locales.
24
25
 
25
26
  This file is the **workflow + guardrail spine**. Depth lives in linked docs:
26
27
 
@@ -51,6 +52,7 @@ function WelcomeBanner() {
51
52
  |---|---|
52
53
  | Bundle doesn't exist yet | **experience-ui-bundle-frontend-generate** skill |
53
54
  | Deploying the app with its labels | **experience-ui-bundle-deploy** skill |
55
+ | Configuring site languages or `sfdc_cms__languageSettings` | **experience-ui-bundle-site-generate** skill |
54
56
  | Localizing an existing bundle | **Workflow below** |
55
57
 
56
58
  ---
@@ -60,10 +62,11 @@ function WelcomeBanner() {
60
62
  | # | Requirement | Verify | If missing |
61
63
  |---|---|---|---|
62
64
  | 1 | It's a `uiBundles/*/src/` React project | Project structure matches | Not a UI Bundle → route to the correct skill |
63
- | 2 | `@salesforce/platform-sdk` installed (≥11.42.1) | `package.json` in the UI bundle dir | Tell user to install it; cannot proceed |
65
+ | 2 | Platform SDK, UI Bundle, and Vite plugin siblings installed and aligned (≥11.49.3) | `package.json` in the UI bundle dir | Tell user to align and upgrade them; cannot proceed |
64
66
  | 3 | You can identify where the app mounts | Read the entry file (usually `src/index.tsx`) | No clear mount point → ask user to point it out |
65
67
  | 4 | Target org actually supports API v68.0+ (runtime label GraphQL for UI Bundles ships in Release 264) | Run the runtime org-release check below | Org's max API version is below v68.0 (Release 262 or older) → cannot proceed; retarget a Release 264+ org or upgrade the org |
66
- | 5 | The bundle is an authenticated app (B2E, or an in-core internal app), not a public site | Run the authenticated-app detection below | Bundle is a site (B2C/B2B) app → localization is **not yet supported for site bundles**; stop and tell the user B2C support is planned for when B2C localization is ready |
68
+ | 5 | The bundle is authenticated B2E or the request/context explicitly identifies a B2C site, not B2B | Run the bundle-type detection below and use the request/context for site product identity | Explicit B2B → reject; site type not explicit → ask the user and stop until confirmed; B2C also requires precondition 6 |
69
+ | 6 | For B2C only, an admin has enabled `GraphQLApiOrgPrefForGuestUsers` | Ask the admin to confirm the org preference is already enabled | Do not enable it; explain that guest GraphQL returns HTTP 403 without it and stop (dependency: W-23854208) |
67
70
 
68
71
  **Runtime org-release check (precondition 4).** The `platform.labels` GraphQL path that resolves labels at runtime for UI Bundles ships in Salesforce Release 264 (API v68.0 or higher). A `sourceApiVersion` in `sfdx-project.json` records what you declared, not what the org supports, so a newer CLI pointed at an older org can pass a static file check and then fail at runtime. Query the org's actual maximum API version before wiring anything:
69
72
 
@@ -73,21 +76,25 @@ bash <skill-dir>/scripts/check-org-api-version.sh <org-alias-or-username>
73
76
 
74
77
  Exit `0` → the org supports v68.0+, proceed. Exit `1` → the org is too old or unreachable; do not write i18n wiring or labels, report the version mismatch to the user and stop. (`sf api request rest` inside the script keeps authentication at the CLI transport layer, so no access token enters context.)
75
78
 
76
- **Authenticated-app detection (precondition 5).** The bundle's type decides whether localization is supported, and it's decided by deterministic file and string checks. Pass the full path to the bundle dir; the script derives the metadata root from it, so the current directory does not matter:
79
+ **Bundle-type detection (precondition 5).** The bundle's type decides which localization branch applies. Pass the full path to the bundle dir; the script derives the metadata root from it, so the current directory does not matter:
77
80
 
78
81
  ```bash
79
82
  bash <skill-dir>/scripts/detect-bundle-type.sh <path-to-uiBundles/<name>/ dir>
80
83
  ```
81
84
 
82
- Act on the exit code: `0` → authenticated app (in-core internal or B2E), proceed; `1` → site (B2C/B2B), localization is **not yet supported for site bundles**, stop and tell the user (B2C support is planned for when B2C localization is ready); `2` → unbound or cannot auto-detect, **ask the user to confirm** the bundle is an authenticated app (B2E or in-core internal) and stop if they cannot.
85
+ Act on the exit-code contract: `0` → authenticated app (B2E or in-core internal), use the B2E branch; `10` → bound public site app-container candidate, meaning metadata proves site binding and guest access but **not** B2C versus B2B; `11` → bound non-public/unsupported site, stop; `12` → both CustomApplication and one site binding exist, ask which runtime context is the localization target; `13` → multiple matching Experience site bindings, show the reported site names and ask which site/runtime context is the target; `2` → unbound/unknown, report the script output and stop rather than guessing.
83
86
 
84
- If a precondition isn't met, stop: report the specific block to the user and record a plan item to return once it's resolved. Do not edit the bundle, in particular, never add i18n wiring or TODO markers to a site (B2C/B2B) bundle that precondition 5 gated off as unsupported.
87
+ For exit `10`, route by explicit request/context: if it says **B2C**, confirm precondition 6 and use the B2C branch; if it says **B2B**, reject it; if product type is not explicit, ask the user whether the site is B2C or B2B and stop until confirmed. For exits `12` and `13`, require the user to choose the runtime context (and site for exit `13`), then apply that branch's fallback and prerequisites. Never infer B2C from `DigitalExperienceConfig`, `appSpace`, `appContainer`, or `AUTHENTICATED_WITH_PUBLIC_ACCESS_ENABLED`; the authentication value means guest access is enabled.
88
+
89
+ For B2C, only an org admin may enable `GraphQLApiOrgPrefForGuestUsers`; never provision or change it. Without it, guest label requests return HTTP 403. Track availability through W-23854208.
90
+
91
+ If a precondition isn't met, stop: report the specific block to the user and record a plan item to return once it's resolved. Do not add i18n wiring or TODO markers to a B2B or unknown bundle.
85
92
 
86
93
  ---
87
94
 
88
95
  ## Workflow: the five steps
89
96
 
90
- Each step has a **checkable completion criterion** and a **confirm-before-continue** pause.
97
+ Each step has a **completion criterion** and a **confirm-before-continue** pause.
91
98
 
92
99
  ### Step 1: Detect
93
100
 
@@ -183,6 +190,8 @@ Branch on the exit code: `0`, every key is registered (or there are no `t()` cal
183
190
 
184
191
  **Goal:** Ensure the i18next init exists; scaffold it if the app has no i18n yet.
185
192
 
193
+ Configure `SalesforceBackend` by bundle type: preserve the shipped `BASE_VALUE` default for B2E; for B2C only, set `labelFallback: "USER_DEFAULT"`. See [references/i18n-setup.md](references/i18n-setup.md) for both configurations and B2C language context.
194
+
186
195
  **Check:**
187
196
  Run `check-i18n-wired.sh` from the UI bundle dir (it scans `src/` relative to the current directory) and report what it returns. The script owns the whole deterministic inspection: it looks for an init file defining `initI18n()` and a boot-time call to it, and when those exist it also reports whether the label manifest is imported and actually passed into the backend config. Do not re-derive any of this by reading files yourself.
188
197
 
@@ -228,42 +237,21 @@ Act on the message `check-i18n-wired.sh` already printed (above): if it reports
228
237
 
229
238
  **Goal:** Guide the developer to verify labels render in a second language.
230
239
 
231
- **Action:**
232
- 1. **Activate a second language** (if not already active), tell the user: "In your org, go to Setup → Translation Workbench → Translation Settings → add a language (e.g., Spanish)."
233
- 2. **Author a translation**, scaffold an empty translation file for the language:
234
- ```xml
235
- <!-- force-app/main/default/translations/es.translation-meta.xml -->
236
- <Translations xmlns="http://soap.sforce.com/2006/04/metadata">
237
- <customLabels>
238
- <label>Bienvenido</label>
239
- <name>Welcome_Text</name>
240
- </customLabels>
241
- </Translations>
242
- ```
243
- (Full structure: [references/label-xml.md](references/label-xml.md))
244
-
245
- Tell the user to either:
246
- - Edit the XML file by hand (for a small number of labels), or
247
- - Use Translation Workbench (Setup → Translate → Custom Label → pick language → enter translations), then retrieve with `sf project retrieve start --metadata Translations:es`.
248
-
249
- 3. **Build and deploy**, tell the user:
250
- ```bash
251
- sf config set target-org=<alias> # API version bakes in; point at the deploy target first
252
- npm run build
253
- sf project deploy start --source-dir force-app --target-org <alias>
254
- ```
240
+ **Action:** Follow the branch-specific procedure in [references/verifying.md](references/verifying.md).
255
241
 
256
- 4. **Open the app** at the `/lwr/application/ai/<namespace>-<bundleName>` URL on the `lightning.force.com` domain (redirects to the app host).
242
+ For **B2E**, activate a second language, author or retrieve its translation metadata, build against the target org, deploy only the target bundle and label metadata, then change the authenticated user's Language and reload. The exact commands and URLs are in [references/verifying.md](references/verifying.md).
257
243
 
258
- 5. **Change the user's Language** (not Locale), Setup → My Settings → Language & Time Zone → Language → pick the translated language → Save.
244
+ For **B2C**, verify configured site languages, URL routing, `SFDC_ENV.language`, the full-reload language switcher, localized local preview, guest GraphQL access, and cache clearing as detailed in [references/verifying.md](references/verifying.md).
259
245
 
260
- 6. **Reload the app**, labels should flip to the translated language.
246
+ Deploying the bundle, labels, and translations does not publish the Experience site. Treat `sf community publish` as a separate go-live mutation: show the exact site and target org, then wait for explicit user confirmation immediately before running it.
261
247
 
262
248
  **If it doesn't render:**
263
249
  Check the three gotchas in [references/gotchas.md](references/gotchas.md):
264
250
  - Unregistered manifest key (Step 3 missed a label)
265
251
  - API-version mismatch (built against a different org)
266
252
  - Stale localStorage cache (clear `i18next_res_*` keys in DevTools)
253
+ - B2C guest GraphQL 403 (`GraphQLApiOrgPrefForGuestUsers` is not admin-enabled)
254
+ - B2C route, site language, and `SFDC_ENV.language` disagree
267
255
 
268
256
  **Completion criterion:**
269
257
  Labels render in ≥2 locales, or the blocking gotcha is identified.
@@ -278,15 +266,17 @@ Labels render in ≥2 locales, or the blocking gotcha is identified.
278
266
  - **No strings found**: report cleanly and stop; do not invent work.
279
267
  - **App has no i18n setup yet**: Step 4 scaffolds the two files first before Step 3 can register anything.
280
268
  - **Partial setup** (manifest exists but init missing, or vice-versa), reconcile what's present; never clobber existing wiring.
269
+ - **B2B site**: explicitly reject it. B2C support does not imply B2B support.
281
270
 
282
271
  ---
283
272
 
284
273
  ## Guardrails: never regress these
285
274
 
286
- 1. **Never machine-translate into deployable metadata.** Scaffold empty translation files and guide the developer to author translations (by hand or via Translation Workbench). Do not call any MT API and paste the result into `translation-meta.xml`; unreviewed machine translations are a quality liability.
275
+ 1. **Never machine-translate deployable metadata.** Scaffold one well-formed `<Translations>` document with a closed `<customLabels>` block per label and XML-escaped English source text. Preserve placeholders and parse both metadata files before completion. Translators replace scaffold values by hand or through Translation Workbench; never call an MT API for them.
287
276
  2. **Never register a key that has no label.** Manifest entry count must equal label count (Step 3 criterion). An unregistered key renders as its own literal name with no console warning. It's the most common localization bug.
288
277
  3. **Never clobber existing i18n wiring.** If Step 4 finds an existing `initI18n()`, reconcile (add the manifest import if missing) rather than replace the whole file.
289
278
  4. **Every file must be customer-safe.** No `webapps`, core-only paths, or internal infrastructure references anywhere. Write as if for an external customer in an SFDX project.
279
+ 5. **Never publish a B2C site implicitly.** Metadata deployment and site publication are separate. Run `sf community publish` only after showing the site and org and receiving explicit confirmation for that publication.
290
280
 
291
281
  ---
292
282
 
@@ -310,7 +300,7 @@ Labels render in ≥2 locales, or the blocking gotcha is identified.
310
300
  |---|---|---|
311
301
  | `npm install i18next react-i18next i18next-chained-backend i18next-localstorage-backend` | UI bundle dir | Install i18n dependencies (Step 4) |
312
302
  | `npm run build` | UI bundle dir | Build the app (API version bakes in, set target-org first) |
313
- | `sf project deploy start --source-dir force-app` | Project root | Deploy the app + labels + translations |
303
+ | See `references/verifying.md` | Project root | Review and deploy the exact target bundle + changed label metadata to an explicit org |
314
304
  | `sf project retrieve start --metadata Translations:<locale>` | Project root | Pull translations authored in Translation Workbench |
315
305
 
316
306
  ---
@@ -320,5 +310,8 @@ Labels render in ≥2 locales, or the blocking gotcha is identified.
320
310
  - [ ] Every confirmed string has both a `CustomLabels` entry and a `t()` call
321
311
  - [ ] `label-manifest.ts` entry count == label count (no unregistered keys)
322
312
  - [ ] `initI18n()` present and called once at boot
313
+ - [ ] B2C only: guest GraphQL preference confirmed, `USER_DEFAULT` configured, and site language route matches `SFDC_ENV.language`
314
+ - [ ] B2E only: no `labelFallback` override; the `BASE_VALUE` default is preserved
323
315
  - [ ] Labels render in ≥2 locales (or the blocking gotcha is named)
324
316
  - [ ] No hand-written machine translations landed in `*-meta.xml` (only scaffold-and-guide)
317
+ - [ ] Both metadata files parse as XML; the translation scaffold has one `<Translations>` root and one closed block per label
@@ -81,7 +81,11 @@ If you built while pointed at a v65.0 org and deploy to a v63.0 org, the bundle
81
81
  ```bash
82
82
  sf config set target-org=<your-deploy-target-alias>
83
83
  npm run build
84
- sf project deploy start --source-dir force-app --target-org <same-alias>
84
+ sf project deploy start \
85
+ --source-dir force-app/main/default/uiBundles/<your-bundle> \
86
+ --source-dir force-app/main/default/labels/CustomLabels.labels-meta.xml \
87
+ --source-dir force-app/main/default/translations/<locale>.translation-meta.xml \
88
+ --target-org <same-alias>
85
89
  ```
86
90
 
87
91
  **Check an org's API version:**
@@ -190,7 +194,7 @@ English never needs activation.
190
194
 
191
195
  **Symptom:** The text is correct, just not translated (e.g., you see "Welcome" when you expected "Bienvenido").
192
196
 
193
- **Cause (most likely):** The translation file is missing that label, or its `<name>` doesn't match the `<fullName>` in `CustomLabels`. i18next falls back to the English base value (via `fallbackLng: "en"`), which is correct behavior; it just means that one key wasn't translated.
197
+ **Cause (most likely):** The translation file is missing that label, or its `<name>` doesn't match the `<fullName>` in `CustomLabels`. The Platform SDK's GraphQL request returns a fallback according to `labelFallback` (`BASE_VALUE` for B2E, explicit `USER_DEFAULT` for B2C), so correct English text usually means that one key wasn't translated.
194
198
 
195
199
  **Other causes:**
196
200
  - The user's **Language** (not Locale) isn't set to the language you translated.
@@ -200,15 +204,25 @@ English never needs activation.
200
204
 
201
205
  ---
202
206
 
203
- ### Logged-in user sees their own language instead of the org default
207
+ ### B2C guest labels request returns HTTP 403
204
208
 
205
- **Symptom:** In a B2X site (or any authenticated context), a logged-in user whose **Language** is French sees French text for a label you only authored in the org-default language (English), **even when the app requests English**. A guest user switching languages works fine; only the logged-in user with a different Language setting hits it.
209
+ **Symptom:** The B2C site loads, but a signed-out visitor's labels GraphQL request returns HTTP 403. The same request can work for an authenticated user.
206
210
 
207
- **Cause:** the server's label **fallback strategy**. When the app asks for a locale that has no explicit translation for a label, the server decides what to return. Its default strategy, `USER_DEFAULT`, resolves in this order: requested locale → that locale's language-fallback chain → **the logged-in user's own language** → the base/master value. Because the user's language comes *before* the base value, a French user gets French, not the English default.
211
+ **Cause:** `GraphQLApiOrgPrefForGuestUsers` is not enabled. Guest access to the GraphQL label path is an org-admin prerequisite tracked by W-23854208.
208
212
 
209
- **Fix on the documented floor (11.42.1):** `SalesforceBackend` does not yet override the server's default, so the query resolves with `USER_DEFAULT` and a logged-in user with a different Language can still see their own language instead of the base value. To get the org default on this version, author an explicit org-default translation for the label, or debug the raw query with `fallback: BASE_VALUE` (shown below) to confirm the value you expect.
213
+ **Fix:** Ask an org admin to confirm and enable the preference through the supported administration process. This localization workflow must never provision or change it. Stop until the prerequisite is satisfied.
210
214
 
211
- > **Coming in a later SDK release:** a change that makes `SalesforceBackend` request `fallback: BASE_VALUE` is merged (2026-07-29) but not yet published, so it is not in 11.42.1. Once the release that carries it ships, the backend skips straight to the org-default value when a translation is missing, and you no longer need an explicit English translation just to work around this. Until then, treat the behavior above as current.
215
+ ### B2C language switch leaves old-language labels
216
+
217
+ **Symptom:** The URL or switcher displays a new site language, but labels remain in the previous language.
218
+
219
+ **Cause:** B2C language context is established at boot from the language-specific route through `SFDC_ENV.language`. An in-place language change does not rebuild the SDK context, and `i18next_res_*` localStorage entries may continue serving cached labels.
220
+
221
+ **Fix:** Make the switcher navigate to the configured language URL and perform a full page reload. Confirm the route and `SFDC_ENV.language` agree. During development, clear `i18next_res_*` before retesting.
222
+
223
+ ### Choose fallback by bundle type
224
+
225
+ The shipped `SalesforceBackend` supports `labelFallback`. Preserve its `BASE_VALUE` default for B2E by omitting the option. For B2C only, configure `labelFallback: "USER_DEFAULT"` so fallback follows the guest/site language context. Do not apply the B2C override to B2E.
212
226
 
213
227
  **If you're debugging the raw labels query** (e.g., re-running it in DevTools): `fallback` must be declared in the operation signature (`$fallback: LabelFallback`) **and** passed to the `labels(...)` field. A `fallback` key in the variables block alone is silently dropped and the server falls back to `USER_DEFAULT`. It takes the `LabelFallback` enum (`USER_DEFAULT` / `BASE_VALUE` / `NONE`), not a locale string like `"en"`:
214
228
 
@@ -229,6 +243,8 @@ query Labels($ns: String!, $names: [String!]!, $locale: String, $fallback: Label
229
243
 
230
244
  with `"fallback": "BASE_VALUE"` in the variables.
231
245
 
246
+ B2B remains unsupported. Do not infer B2B support from the B2C guidance or apply these steps to a B2B site.
247
+
232
248
  ---
233
249
 
234
250
  ### Large manifest: no per-query limit to manage yourself
@@ -25,7 +25,7 @@ export async function initI18n() {
25
25
  const dataSDK = await createDataSDK();
26
26
  const ctx = await fetchI18nContext(dataSDK);
27
27
 
28
- // Tell the browser the user's language + text direction (RTL support).
28
+ // B2E: the session language is the display language.
29
29
  document.documentElement.dir = ctx.dir;
30
30
  document.documentElement.lang = ctx.lang;
31
31
 
@@ -40,7 +40,7 @@ export async function initI18n() {
40
40
  backends: [LocalStorageBackend, SalesforceBackend],
41
41
  backendOptions: [
42
42
  { expirationTime: 86400000 }, // cache labels in localStorage for a day
43
- { dataSDK, labelManifest }, // fetch the rest over GraphQL
43
+ { dataSDK, labelManifest }, // B2E: shipped BASE_VALUE fallback
44
44
  ],
45
45
  },
46
46
  interpolation: {
@@ -57,6 +57,34 @@ export async function initI18n() {
57
57
  }
58
58
  ```
59
59
 
60
+ The example above is the **B2E** configuration. Do not set `labelFallback` for B2E: the shipped `SalesforceBackend` default is `BASE_VALUE`.
61
+
62
+ For a **B2C** bundle, change only the Salesforce backend options entry:
63
+
64
+ ```typescript
65
+ backendOptions: [
66
+ { expirationTime: 86400000 },
67
+ {
68
+ dataSDK,
69
+ labelManifest,
70
+ labelFallback: "USER_DEFAULT",
71
+ },
72
+ ],
73
+ ```
74
+
75
+ `USER_DEFAULT` is required for B2C so fallback follows the guest/site language context. Do not copy this override into B2E wiring.
76
+
77
+ For B2C, also set the document language and direction from the route-selected display language, not `ctx.dir`. The GraphQL i18n context direction reflects the guest session profile and can stay `ltr` after the site switches to an RTL language. Reuse the resolved language from the site's language-switcher integration:
78
+
79
+ ```typescript
80
+ const resolvedLang =
81
+ (globalThis as { SFDC_ENV?: { language?: string } }).SFDC_ENV?.language || ctx.lang;
82
+ document.documentElement.dir = i18next.dir(resolvedLang);
83
+ document.documentElement.lang = resolvedLang.replace(/_/g, "-");
84
+ ```
85
+
86
+ Before using this configuration, have an org admin confirm that `GraphQLApiOrgPrefForGuestUsers` is already enabled. This workflow must never enable it. Without the preference, unauthenticated GraphQL label requests return HTTP 403; see dependency W-23854208.
87
+
60
88
  **Call it once at boot**, before mounting your app:
61
89
 
62
90
  ```typescript
@@ -90,6 +118,22 @@ export const labelManifest = [
90
118
 
91
119
  The manifest is how i18next knows what to fetch. An **unregistered key fails silently**: it renders as its own literal name (e.g., `"Welcome_Text"` instead of "Welcome") with no console warning. Always keep the manifest in sync with your `t()` calls.
92
120
 
121
+ ## B2C language context
122
+
123
+ A B2C site's configured languages and language-specific URLs are the source of truth. At boot, the site route supplies `SFDC_ENV.language`; the SDK detector uses that value to resolve labels. A language switcher must navigate to the target language URL and perform a full page reload. An in-place i18next language change is insufficient because the SDK context and localStorage-backed labels are established at boot.
124
+
125
+ For local preview, use the site entry of the Vite plugin and pass the site's supported language codes, with the default first:
126
+
127
+ ```typescript
128
+ import siteUiBundlePlugin from "@salesforce/vite-plugin-ui-bundle/site";
129
+
130
+ export default defineConfig({
131
+ plugins: [siteUiBundlePlugin({ languages: ["en_US", "es", "ar"] })],
132
+ });
133
+ ```
134
+
135
+ The site plugin injects `SFDC_ENV.language` per request and serves non-default hyphenated language routes such as `/es` or `/en-US`; the default language has no prefix. Verify the injected language before judging label output. The authenticated org user's Language setting is not a substitute for the guest site's language context.
136
+
93
137
  ---
94
138
 
95
139
  ## Dependencies
@@ -100,7 +144,7 @@ Install these first (Step 4 of the main workflow):
100
144
  npm install i18next react-i18next i18next-chained-backend i18next-localstorage-backend
101
145
  ```
102
146
 
103
- Use `@salesforce/platform-sdk` **≥11.42.1**. The `@salesforce/platform-sdk/i18n` subpath (`SalesforceBackend`, `createSalesforceDetector`, `fetchI18nContext`) has existed since 11.4.1, and 11.7.0 added `reloadI18nContext` for refreshing the cached label context. 11.42.1 is the validated floor because it carries the fix that batches a namespace into 100-name-or-fewer queries. Without it, a manifest of more than 100 labels in one namespace hits the `uiapi.platform.labels` limit and the whole namespace read fails. Keep the SDK's siblings (`@salesforce/vite-plugin-ui-bundle`, `@salesforce/ui-bundle`) on the same version.
147
+ Use aligned `@salesforce/platform-sdk`, `@salesforce/vite-plugin-ui-bundle`, and `@salesforce/ui-bundle` packages at **≥11.49.3**. Platform SDK 11.45.0 introduced the `labelFallback` option and shipped `BASE_VALUE` default, but the B2C local-preview entry `@salesforce/vite-plugin-ui-bundle/site` first appears in the 11.49.x line. Version 11.49.3 is therefore the common floor for this B2C-capable workflow. Earlier history: the i18n subpath existed in 11.4.1, 11.7.0 added `reloadI18nContext`, and 11.42.1 added namespace batching for the 100-name labels-query limit.
104
148
 
105
149
  Known-good companion versions:
106
150
  - `i18next` **^24.2.2**
@@ -125,7 +169,7 @@ If you see an older example that vendors `salesforce-detector.ts` or `salesforce
125
169
 
126
170
  1. Bundle loads, `initI18n()` runs
127
171
  2. `createDataSDK()` initializes the SDK
128
- 3. `fetchI18nContext()` queries the org for the user's language/locale/direction
172
+ 3. `fetchI18nContext()` queries the org for language/locale/direction (B2C uses the site route's `SFDC_ENV.language`)
129
173
  4. `SalesforceBackend` reads the manifest and issues a GraphQL query per namespace:
130
174
  ```graphql
131
175
  query LoadLabels {
@@ -77,6 +77,10 @@ One file per translated language (e.g., `es.translation-meta.xml` for Spanish, `
77
77
  </Translations>
78
78
  ```
79
79
 
80
+ Always write the whole document shown above, not a fragment: exactly one XML declaration, one `<Translations>` root with the Metadata API namespace, and one complete `<customLabels>` block per label. For an untranslated scaffold, copy the XML-escaped English source text into `<label>` and leave actual translation to the localization team. Preserve positional placeholders such as `{0}` and `{1}`.
81
+
82
+ XML-escape text values: `&` becomes `&amp;`, `<` becomes `&lt;`, and `>` becomes `&gt;`. Before considering the file complete, parse both `CustomLabels.labels-meta.xml` and every generated `*.translation-meta.xml` with an XML parser. A fragment with balanced-looking inner tags is still invalid without its root document.
83
+
80
84
  ### Fields
81
85
 
82
86
  | Field | Purpose | Notes |
@@ -105,7 +109,7 @@ You have two options:
105
109
 
106
110
  ### 1. Hand-edit the XML (for small apps)
107
111
 
108
- Create the `<locale>.translation-meta.xml` file, add one `<customLabels>` block per label, and type the translations directly. Good for a handful of labels or prototyping.
112
+ Create the complete `<locale>.translation-meta.xml` document and add one complete `<customLabels>` block per label. For this skill's scaffold, keep the English source text rather than inventing translations; translators can replace it later. Good for a handful of labels or prototyping.
109
113
 
110
114
  ### 2. Use Translation Workbench (for scale)
111
115
 
@@ -233,14 +237,17 @@ To change a user's Language (to test translations), go to:
233
237
  </labels>
234
238
  ```
235
239
 
236
- ### 2. Add the Spanish translation
240
+ ### 2. Add the untranslated Spanish scaffold
237
241
 
238
242
  `force-app/main/default/translations/es.translation-meta.xml`:
239
243
  ```xml
240
- <customLabels>
241
- <label>Bienvenido</label>
242
- <name>Welcome_Text</name>
243
- </customLabels>
244
+ <?xml version="1.0" encoding="UTF-8"?>
245
+ <Translations xmlns="http://soap.sforce.com/2006/04/metadata">
246
+ <customLabels>
247
+ <label>Welcome</label>
248
+ <name>Welcome_Text</name>
249
+ </customLabels>
250
+ </Translations>
244
251
  ```
245
252
 
246
253
  ### 3. Register in the manifest
@@ -264,13 +271,20 @@ function WelcomeBanner() {
264
271
  ### 5. Deploy
265
272
 
266
273
  ```bash
267
- sf project deploy start --source-dir force-app --target-org <alias>
274
+ sf project deploy start \
275
+ --source-dir force-app/main/default/uiBundles/<your-bundle> \
276
+ --source-dir force-app/main/default/labels/CustomLabels.labels-meta.xml \
277
+ --source-dir force-app/main/default/translations/<locale>.translation-meta.xml \
278
+ --target-org <alias>
268
279
  ```
269
280
 
281
+ Review the exact paths and target org with the user before deploying. Repeat the translation path only for locale files changed by this task.
282
+
270
283
  ### 6. Verify
271
284
 
272
285
  - User with Language = English sees "Welcome"
273
- - User with Language = Spanish sees "Bienvenido"
286
+ - Before translator review, a user with Language = Spanish also sees the scaffold value "Welcome"
287
+ - After a translator replaces the scaffold value with `Bienvenido` and the metadata is retrieved/deployed, a user with Language = Spanish sees "Bienvenido"
274
288
 
275
289
  ---
276
290
 
@@ -6,13 +6,15 @@ How to build, deploy, open, and verify that labels render correctly in multiple
6
6
 
7
7
  ## Overview
8
8
 
9
- Verification has five steps:
9
+ Authenticated B2E verification has five steps:
10
10
  1. **Build** the app (API version bakes in, point at the deploy target org first)
11
11
  2. **Deploy** the bundle + labels + translations in one shot
12
12
  3. **Open** the app at the correct URL (on the `lightning.force.com` domain)
13
13
  4. **Flip** the user's Language setting to the translated language
14
14
  5. **Reload** and confirm the labels render in the new language
15
15
 
16
+ B2C verification uses the site-configured languages and language-specific URLs instead of the authenticated user's Language setting. Follow the B2C section after deployment.
17
+
16
18
  ---
17
19
 
18
20
  ## Step 1: Build the app
@@ -56,20 +58,24 @@ English (`en_US`) needs no activation; it's always available.
56
58
 
57
59
  ## Step 3: Deploy the bundle + labels + translations
58
60
 
59
- Deploy the entire `force-app` tree (bundle, labels, translations) in one command:
61
+ Before deploying, inspect the local diff and construct exact source paths for the target bundle, `CustomLabels.labels-meta.xml`, and only the locale files changed by this task. Show the actual metadata diff/components, not only the filenames; if either shared label file contains unrelated changes, stop or get explicit approval for those changes too. Show the resolved target org (`sf org display --target-org <alias>`) and wait for explicit confirmation. Then deploy the approved paths, for example:
60
62
 
61
63
  ```bash
62
- sf project deploy start --source-dir force-app --target-org <your-org-alias>
64
+ sf project deploy start \
65
+ --source-dir force-app/main/default/uiBundles/<your-bundle> \
66
+ --source-dir force-app/main/default/labels/CustomLabels.labels-meta.xml \
67
+ --source-dir force-app/main/default/translations/<locale>.translation-meta.xml \
68
+ --target-org <your-org-alias>
63
69
  ```
64
70
 
65
- **Run from the SFDX project root** (not from inside the bundle directory). `--source-dir force-app` deploys everything under that folder:
71
+ **Run from the SFDX project root** (not from inside the bundle directory). The approved source paths deploy only:
66
72
  - `labels/CustomLabels.labels-meta.xml` (English base labels)
67
73
  - `translations/<locale>.translation-meta.xml` (translated labels)
68
74
  - `uiBundles/<your-bundle>/dist/` (the built app)
69
75
 
70
- You do **not** need a `package.xml` or any manifest entry; the CLI discovers the metadata automatically.
76
+ You do **not** need a `package.xml` or any manifest entry; the CLI discovers the selected metadata automatically.
71
77
 
72
- **Point at `force-app`, not `uiBundles/`, or your labels and translations won't go up.**
78
+ Repeat `--source-dir` for each approved locale file. Do not replace these paths with the broad `force-app`, `labels`, or `translations` directories unless the user explicitly intends to deploy every metadata change in them.
73
79
 
74
80
  ---
75
81
 
@@ -115,6 +121,22 @@ To test translations, you need to change the **Language** setting (not Locale, s
115
121
 
116
122
  **Reload the app.** Labels should now render in the selected language.
117
123
 
124
+ This step is for **B2E only**. For B2C, use the site language route below.
125
+
126
+ ---
127
+
128
+ ## B2C: verify a guest site language
129
+
130
+ 1. In the site administration experience, configure at least two supported languages. Translation Workbench activation and translation metadata remain required, but they do not by themselves add a language to the site.
131
+ 2. Confirm an org admin has already enabled `GraphQLApiOrgPrefForGuestUsers` (W-23854208). Never enable it as part of this workflow. Without it, a guest's GraphQL label request returns HTTP 403.
132
+ 3. If the configured language or deployed metadata requires publishing, treat publication as a separate go-live mutation. Resolve the site's `Network.Name` from the target site (prefer matching its `UrlPathPrefix`), show that community name and target org, and wait for explicit user confirmation immediately before running `sf community publish --name "<network-name>" --target-org <org-alias>`. A metadata deployment is not publication approval. Track the returned background operation to completion before guest verification; if propagation is still in progress, report that instead of treating stale output as a localization failure.
133
+ 4. Open the published site as a signed-out guest through its language-specific URL. Confirm the boot environment exposes the same language in `SFDC_ENV.language`.
134
+ 5. Confirm translated labels render and the labels GraphQL request succeeds for the guest.
135
+ 6. Use the site's language switcher. It must navigate to the target language URL and cause a **full page reload**; changing i18next in place leaves the boot-time SDK context and cached resources stale.
136
+ 7. Confirm the new route and `SFDC_ENV.language` agree, then verify the translated labels again.
137
+
138
+ For a localized local preview, supply an explicit configured language in the preview URL/route. Do not use the authenticated org user's Language as evidence for guest behavior. If a recent translation or route change appears stale, delete `i18next_res_*` localStorage entries and reload each language URL.
139
+
118
140
  ---
119
141
 
120
142
  ## Language vs Locale (common confusion)
@@ -140,7 +162,7 @@ When you test localization, **change the Language**, not the Locale. Changing Lo
140
162
 
141
163
  **Check:** Go to Setup → Translation Workbench → Translate → pick the language and the label. Is the translation there? If not, author it and re-deploy.
142
164
 
143
- **Fallback behavior:** If a key is in the manifest but untranslated for the active language, i18next renders the **English base value** (via `fallbackLng: "en"` in the init). That's correct behavior; it just means that one key wasn't translated yet.
165
+ **Fallback behavior:** If a registered key is untranslated for the active language, the Platform SDK's GraphQL request resolves it according to `labelFallback`: B2E uses `BASE_VALUE`; B2C explicitly uses `USER_DEFAULT`. The i18next `fallbackLng` applies only if no resource is loaded for the detected language; it does not define Salesforce label-resolution semantics.
144
166
 
145
167
  ---
146
168
 
@@ -178,11 +200,11 @@ See [gotchas.md](gotchas.md) for the full explanation.
178
200
 
179
201
  This is expected, not a bug, **as long as you only authored the base (`en_US`) translation.**
180
202
 
181
- Asked with `fallback: BASE_VALUE`, the GraphQL server returns the label's base value for a regional Language it has no explicit translation for: `resolvedLocale` comes back as the base (`en_US`) with `wasFallback: true`. The server does **not** map `en_GB → en_US` region-aware; it just honors the base-value fallback. On the documented SDK floor (11.42.1) the backend does not yet request `BASE_VALUE`, so it resolves with the server default (`USER_DEFAULT`): a guest or org-default user still lands on the base value, but see the related note below for the logged-in case. The base-value request ships in a later SDK release (see [gotchas.md](gotchas.md)).
203
+ For B2E, the shipped `SalesforceBackend` default is `BASE_VALUE`. The GraphQL server returns the label's base value for a regional Language with no explicit translation: `resolvedLocale` comes back as the base (`en_US`) with `wasFallback: true`. The server does **not** map `en_GB → en_US` region-aware; it honors the base-value fallback.
182
204
 
183
205
  **Fix (only if you want region-specific text):** Author a translation for that exact regional Language (`en_GB.translation-meta.xml`). Otherwise the base value is the intended, correct result.
184
206
 
185
- **Related:** if instead a *logged-in* user sees **their own** language (not the org default) for an untranslated label, that's the fallback-strategy case, see [gotchas.md](gotchas.md) ("Logged-in user sees their own language instead of the org default"). On 11.42.1 that is the expected behavior, since the backend still uses `USER_DEFAULT`; author an explicit org-default translation to avoid it. The `BASE_VALUE` fallback that prevents it arrives in a later SDK release.
207
+ For B2C, the skill explicitly configures `labelFallback: "USER_DEFAULT"`; test fallback through the guest site's configured language URL rather than by changing an authenticated user's Language.
186
208
 
187
209
  ---
188
210
 
@@ -192,11 +214,16 @@ Use this to confirm everything works:
192
214
 
193
215
  - [ ] Built against the correct org (API version matches deploy target)
194
216
  - [ ] Every translated language is activated in the org
195
- - [ ] Deployed `force-app` (bundle + labels + translations in one shot)
217
+ - [ ] Deployed only the target bundle + labels + translations directories
196
218
  - [ ] Opened at `lightning.force.com/lwr/application/ai/<namespace>-<bundleName>` (redirected to `.my.salesforce.app` is fine)
197
219
  - [ ] Changed user's **Language** (not Locale) to the translated language
198
220
  - [ ] Reloaded, labels render in the new language
199
221
  - [ ] If labels are stale, cleared `i18next_res_*` from localStorage
222
+ - [ ] B2C: site languages are configured/published and the language URL matches `SFDC_ENV.language`
223
+ - [ ] B2C: any site publication received separate explicit confirmation for the named site and org
224
+ - [ ] B2C: signed-out guest labels GraphQL succeeds (no HTTP 403)
225
+ - [ ] B2C: language switcher performs a full reload and localized local preview was checked
226
+ - [ ] B2B was excluded; this workflow does not support B2B sites
200
227
 
201
228
  ---
202
229
 
@@ -206,7 +233,8 @@ Use this to confirm everything works:
206
233
  |---|---|---|
207
234
  | `sf config set target-org=<alias>` | Anywhere | Set default org (API version bakes in on next build) |
208
235
  | `npm run build` | UI bundle dir | Build the app |
209
- | `sf project deploy start --source-dir force-app --target-org <alias>` | Project root | Deploy bundle + labels + translations |
236
+ | `sf project deploy start --source-dir force-app/main/default/uiBundles/<bundle> --source-dir force-app/main/default/labels/CustomLabels.labels-meta.xml --source-dir force-app/main/default/translations/<locale>.translation-meta.xml --target-org <alias>` | Project root | Deploy the approved target bundle + exact label metadata paths |
237
+ | `sf community publish --name "<network-name>" --target-org <alias>` | Project root | Publish the B2C site, only after resolving `Network.Name` and separate explicit confirmation |
210
238
  | `sf project retrieve start --metadata Translations:<locale>` | Project root | Pull translations authored in Translation Workbench |
211
239
 
212
240
  ---