@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.
- package/package.json +2 -6
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +3 -0
- package/skills/automation-sandbox-post-copy-configure/SKILL.md +4 -0
- package/skills/design-systems-slds-validate/SKILL.md +2 -2
- package/skills/dx-app-analytics-query/SKILL.md +1 -3
- package/skills/dx-devops-conflict-resolve/SKILL.md +205 -0
- package/skills/dx-devops-conflict-resolve/examples/conflict-workflows.md +165 -0
- package/skills/dx-devops-conflict-resolve/references/deploy-failure-resolution.md +75 -0
- package/skills/dx-devops-conflict-resolve/references/git-conflict-resolution.md +124 -0
- package/skills/dx-devops-conflict-resolve/scripts/detect-conflicts.sh +91 -0
- package/skills/dx-devops-conflict-resolve/scripts/diagnose-deploy-failure.sh +156 -0
- package/skills/dx-devops-request-status/SKILL.md +160 -0
- package/skills/dx-devops-request-status/examples/polling-workflows.md +101 -0
- package/skills/dx-devops-request-status/references/cli-commands.md +176 -0
- package/skills/dx-devops-request-status/scripts/poll-status.sh +134 -0
- package/skills/dx-devops-test-failures-analyze/SKILL.md +6 -6
- package/skills/dx-devops-test-pipeline-configure/SKILL.md +7 -7
- package/skills/dx-devops-test-suite-assignments-configure/SKILL.md +6 -6
- package/skills/dx-devops-test-suite-run/SKILL.md +6 -6
- package/skills/dx-devops-work-item-manage/SKILL.md +2 -0
- package/skills/dx-org-manage/references/creating-scratch-org.md +5 -2
- package/skills/dx-org-manage/references/creating-snapshot.md +1 -0
- package/skills/dx-org-shape-manage/SKILL.md +152 -0
- package/skills/dx-org-shape-manage/examples/create_error_output.json +9 -0
- package/skills/dx-org-shape-manage/examples/create_success_output.json +9 -0
- package/skills/dx-org-shape-manage/examples/delete_output.json +11 -0
- package/skills/dx-org-shape-manage/examples/list_inactive_output.json +32 -0
- package/skills/dx-org-shape-manage/examples/list_output.json +24 -0
- package/skills/dx-org-shape-manage/references/cli_flags.md +135 -0
- package/skills/dx-org-switch/SKILL.md +2 -2
- package/skills/dx-org-trial-expiration-check/SKILL.md +2 -0
- package/skills/dx-pkg-post-install-configure/SKILL.md +3 -0
- package/skills/education-cloud-multi-campus-configure/SKILL.md +211 -0
- package/skills/education-cloud-multi-campus-configure/examples/hierarchy_visualization.md +174 -0
- package/skills/education-cloud-multi-campus-configure/examples/output_examples.md +54 -0
- package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input.csv +29 -0
- package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input_edgecases.csv +16 -0
- package/skills/education-cloud-multi-campus-configure/references/account_recordtype_prerequisite.md +44 -0
- package/skills/education-cloud-multi-campus-configure/references/delta_computation.md +33 -0
- package/skills/education-cloud-multi-campus-configure/references/error_handling.md +198 -0
- package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +54 -0
- package/skills/education-cloud-multi-campus-configure/references/gotchas.md +16 -0
- package/skills/education-cloud-multi-campus-configure/references/hierarchy_parsing_rules.md +133 -0
- package/skills/education-cloud-multi-campus-configure/references/mcp-invocation.md +75 -0
- package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/SKILL.md +1 -1
- package/skills/experience-cms-brand-apply/SKILL.md +4 -1
- package/skills/experience-cms-brand-create/SKILL.md +197 -0
- package/skills/experience-cms-brand-create/assets/brand-template.json +329 -0
- package/skills/experience-cms-brand-create/references/brand-anatomy.md +120 -0
- package/skills/experience-cms-brand-create/references/disk-contract.md +84 -0
- package/skills/experience-cms-content-generate/SKILL.md +190 -0
- package/skills/experience-cms-content-generate/assets/display-formats.md +84 -0
- package/skills/experience-cms-content-generate/assets/payloads/create-content-bulk.json +11 -0
- package/skills/experience-cms-content-generate/assets/payloads/create-content-single.json +11 -0
- package/skills/experience-cms-content-generate/assets/payloads/publish-content.json +4 -0
- package/skills/experience-cms-content-generate/assets/payloads/update-content.json +9 -0
- package/skills/experience-cms-content-generate/assets/questions.md +241 -0
- package/skills/experience-cms-content-generate/examples/create-content-call.md +81 -0
- package/skills/experience-cms-content-generate/references/bulk-batching.md +56 -0
- package/skills/experience-cms-content-generate/references/content-type-classification.md +88 -0
- package/skills/experience-cms-content-generate/references/content-write-tool.md +95 -0
- package/skills/experience-cms-content-generate/references/delegation-protocol.md +37 -0
- package/skills/experience-cms-content-generate/references/edit-publish-workflow.md +63 -0
- package/skills/experience-cms-content-generate/references/error-recovery.md +72 -0
- package/skills/experience-cms-content-generate/references/identifier-resolution.md +26 -0
- package/skills/experience-cms-content-generate/references/intent-routing.md +45 -0
- package/skills/experience-cms-content-generate/references/principles.md +19 -0
- package/skills/experience-cms-content-generate/references/ux-rules.md +68 -0
- package/skills/experience-cms-content-generate/references/workspace-resolution.md +33 -0
- package/skills/experience-cms-content-type-generate/SKILL.md +449 -0
- package/skills/experience-cms-content-type-generate/assets/discovery-prompts.md +79 -0
- package/skills/experience-cms-content-type-generate/assets/schema-example.json +70 -0
- package/skills/experience-cms-content-type-generate/references/agent-checklist.md +50 -0
- package/skills/experience-cms-content-type-generate/references/anti-patterns.md +39 -0
- package/skills/experience-cms-content-type-generate/references/deployment-errors.md +27 -0
- package/skills/experience-cms-content-type-generate/references/discovery-details.md +106 -0
- package/skills/experience-cms-content-type-generate/references/discovery-query-rules.md +85 -0
- package/skills/experience-cms-content-type-generate/references/edit-fields-loop.md +48 -0
- package/skills/experience-cms-content-type-generate/references/pre-deploy-checklist.md +21 -0
- package/skills/experience-cms-content-type-generate/references/retrieve-and-reconcile.md +105 -0
- package/skills/experience-cms-content-type-generate/references/schema-rules.md +51 -0
- package/skills/experience-cms-content-type-generate/references/schema-summary-format.md +60 -0
- package/skills/experience-lds-graphql-generate/SKILL.md +4 -0
- package/skills/experience-lwc-accessibility-jest-run/SKILL.md +79 -0
- package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +205 -0
- package/skills/experience-lwc-design-generate/SKILL.md +5 -4
- package/skills/experience-lwc-generate/SKILL.md +10 -9
- package/skills/experience-ui-bundle-deploy/references/dev-preview.md +21 -0
- package/skills/experience-ui-bundle-deploy/references/social-login.md +1 -0
- package/skills/experience-ui-bundle-file-upload-generate/SKILL.md +6 -6
- package/skills/experience-ui-bundle-localize/SKILL.md +30 -37
- package/skills/experience-ui-bundle-localize/references/gotchas.md +23 -7
- package/skills/experience-ui-bundle-localize/references/i18n-setup.md +48 -4
- package/skills/experience-ui-bundle-localize/references/label-xml.md +22 -8
- package/skills/experience-ui-bundle-localize/references/verifying.md +39 -11
- package/skills/experience-ui-bundle-localize/scripts/detect-bundle-type.sh +118 -15
- package/skills/experience-ui-bundle-localize/scripts/tests/test-detect-bundle-type.sh +187 -0
- package/skills/experience-ui-bundle-mfa-configure/SKILL.md +13 -2
- package/skills/experience-ui-bundle-mfa-configure/references/social-login.md +1 -0
- package/skills/experience-ui-bundle-project-generate/SKILL.md +2 -2
- package/skills/integration-connectivity-generate/SKILL.md +11 -10
- package/skills/integration-eventing-cdc-configure/SKILL.md +6 -6
- package/skills/integration-eventing-subscription-configure/SKILL.md +6 -5
- package/skills/mobile-platform-native-capabilities-integrate/SKILL.md +2 -2
- package/skills/mobile-platform-offline-validate/scripts/package.json +1 -1
- package/skills/platform-agentexchange-partner-offers-configure/SKILL.md +8 -8
- package/skills/platform-custom-application-generate/SKILL.md +2 -0
- package/skills/platform-custom-field-generate/SKILL.md +8 -6
- package/skills/platform-custom-metadata-type-generate/SKILL.md +460 -0
- package/skills/platform-custom-metadata-type-generate/references/cmdt-records.md +251 -0
- package/skills/platform-custom-metadata-type-generate/scripts/sanitize-developer-name.sh +46 -0
- package/skills/platform-custom-setting-generate/SKILL.md +419 -0
- package/skills/platform-dataspace-access-configure/SKILL.md +3 -3
- package/skills/platform-sharing-owd-configure/SKILL.md +3 -0
- package/skills/platform-value-set-generate/SKILL.md +2 -0
- package/skills/service-agentforce-channel-configure/SKILL.md +29 -20
- package/skills/service-agentforce-channel-configure/assets/BotEmailDefinition.botEmailDefinition-meta.xml +36 -0
- package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email +17 -0
- package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email-meta.xml +29 -0
- package/skills/service-agentforce-channel-configure/assets/mdapi-package.xml +25 -0
- package/skills/service-agentforce-channel-configure/assets/settings-mdapi-package.xml +30 -0
- package/skills/service-agentforce-channel-configure/references/agent-wiring.md +20 -0
- package/skills/service-agentforce-channel-configure/references/botemaildefinition.md +107 -0
- package/skills/service-agentforce-channel-configure/references/channel-branch-email.md +203 -50
- package/skills/service-agentforce-channel-configure/references/channel-types.md +30 -3
- package/skills/service-agentforce-channel-configure/references/queue-resolution.md +17 -8
- package/skills/service-agentforce-channel-configure/references/routing-flow.md +14 -3
- package/skills/service-agentforce-channel-configure/scripts/validate-botemaildefinition.py +126 -0
- package/skills/service-agentforce-channel-configure/scripts/validate-emailtemplate.py +133 -0
- package/skills/service-de-channel-activate/SKILL.md +271 -0
- package/skills/service-de-channel-activate/references/gotchas.md +31 -0
- package/skills/service-de-channel-activate/references/phone-verification.md +96 -0
- package/skills/service-de-channel-activate/references/worked-examples.md +14 -0
- package/skills/service-de-channel-consent-configure/SKILL.md +230 -0
- package/skills/service-de-channel-consent-configure/references/gotchas.md +41 -0
- package/skills/service-de-channel-consent-configure/references/language-keywords.md +84 -0
- package/skills/service-de-channel-consent-configure/references/worked-examples.md +134 -0
- package/skills/service-de-channel-create/SKILL.md +369 -0
- package/skills/service-de-channel-create/references/apple.md +59 -0
- package/skills/service-de-channel-create/references/connect-insert.md +84 -0
- package/skills/service-de-channel-create/references/facebook.md +154 -0
- package/skills/service-de-channel-create/references/line.md +66 -0
- package/skills/service-de-channel-create/references/sms.md +98 -0
- package/skills/service-de-channel-create/references/whatsapp.md +98 -0
- package/skills/service-de-channel-create/references/worked-examples.md +70 -0
- package/skills/service-de-channel-routing-configure/SKILL.md +345 -0
- package/skills/service-de-channel-routing-configure/references/asa-routing.md +90 -0
- package/skills/service-de-channel-routing-configure/references/gotchas.md +27 -0
- package/skills/service-de-channel-routing-configure/references/queue-creation.md +123 -0
- package/skills/service-de-channel-routing-configure/references/target-locate.md +98 -0
- package/skills/service-de-channel-routing-configure/references/worked-examples.md +174 -0
- package/skills/service-de-headless-channel-configure/SKILL.md +305 -0
- package/skills/service-de-headless-channel-configure/references/gotchas.md +27 -0
- package/skills/service-de-headless-channel-configure/references/inputs.md +49 -0
- package/skills/service-de-headless-channel-configure/references/output-envelopes.md +53 -0
- package/skills/service-de-headless-channel-configure/references/partial-success.md +24 -0
- package/skills/service-de-headless-channel-configure/references/terms-and-conditions.md +54 -0
- package/skills/service-de-headless-channel-configure/references/worked-examples.md +108 -0
- package/skills/service-de-waba-integrate/SKILL.md +227 -0
- package/skills/service-digital-engagement-channel-configure/scripts/check-api-version.sh +29 -0
- package/skills/service-digital-engagement-messaging-site-integrate/SKILL.md +10 -9
- package/skills/service-digital-engagement-messaging-site-integrate/references/lwr_patch.md +39 -21
- package/skills/service-digital-engagement-messaging-site-integrate/scripts/patch_lwr_bundle.sh +157 -96
- package/skills/service-email-to-case-configure/SKILL.md +190 -0
- package/skills/service-email-to-case-configure/assets/CaseSettings.settings-meta.xml +45 -0
- package/skills/service-email-to-case-configure/examples/CaseSettings-two-addresses.settings-meta.xml +36 -0
- package/skills/service-email-to-case-configure/references/apply-mechanics.md +73 -0
- package/skills/service-email-to-case-configure/references/routing_address_reference.md +73 -0
- package/skills/service-email-to-case-configure/references/troubleshooting.md +25 -0
- package/skills/service-email-to-case-configure/scripts/apply-casesettings.py +1315 -0
- package/skills/service-email-to-case-configure/scripts/check-agent-email-capability.sh +26 -0
- package/skills/service-email-to-case-configure/scripts/tests/__init__.py +0 -0
- package/skills/service-email-to-case-configure/scripts/tests/_bootstrap.py +45 -0
- package/skills/service-email-to-case-configure/scripts/tests/_fakeorg.py +366 -0
- package/skills/service-email-to-case-configure/scripts/tests/_run.py +84 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_apply_org_scenarios.py +655 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_get_session.py +134 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_new_capabilities.py +193 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_validate_casesettings.py +170 -0
- package/skills/service-email-to-case-configure/scripts/validate-casesettings.py +229 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +33 -15
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -47
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +17 -12
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/references/cli-invocation.md +5 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-enable-plan.mjs +11 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +8 -6
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/references/cli-invocation.md +3 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/scripts/classify-readiness.mjs +11 -3
- package/skills/service-itsm-agentic-setup-configure/SKILL.md +5 -5
- package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +5 -5
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +2 -2
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +11 -7
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +20 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +10 -6
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/action-availability.md +7 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +11 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/build-create-body.mjs +24 -17
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-action-availability.mjs +98 -58
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +20 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/strip-release-management.mjs +176 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +19 -19
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/cli-invocation.md +3 -4
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/helper-contracts.md +6 -6
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/permset-topology.md +3 -10
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-permset-availability.mjs +7 -9
- package/skills/service-itsm-incident-mgmt-configure/SKILL.md +2 -0
- package/skills/service-itsm-incident-priority-configure/SKILL.md +15 -12
- package/skills/service-itsm-incident-priority-configure/examples/matrix-operations.md +27 -1
- package/skills/service-itsm-incident-priority-configure/references/sf-cli-invocation.md +37 -6
- package/skills/service-native-voice-recording-transcription-configure/SKILL.md +146 -0
- package/skills/service-native-voice-recording-transcription-configure/assets/confirmation-output.json +16 -0
- package/skills/service-native-voice-recording-transcription-configure/assets/package.xml +22 -0
- package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +101 -0
- package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +181 -0
- package/skills/data360-activate/README.md +0 -38
- package/skills/data360-activate/SKILL.md +0 -127
- package/skills/data360-connect/README.md +0 -57
- package/skills/data360-connect/SKILL.md +0 -163
- package/skills/data360-connect/examples/connections/heroku-postgres.json +0 -15
- package/skills/data360-connect/examples/connections/ingest-api-connection.json +0 -5
- package/skills/data360-connect/examples/connections/ingest-api-schema.json +0 -31
- package/skills/data360-connect/examples/connections/redshift.json +0 -16
- package/skills/data360-connect/examples/connections/sharepoint-unstructured.json +0 -20
- package/skills/data360-connect/examples/connections/snowflake-connection.json +0 -42
- package/skills/data360-harmonize/README.md +0 -31
- package/skills/data360-harmonize/SKILL.md +0 -126
- package/skills/data360-orchestrate/README.md +0 -120
- package/skills/data360-orchestrate/SKILL.md +0 -263
- package/skills/data360-orchestrate/assets/definitions/activation-target.template.json +0 -5
- package/skills/data360-orchestrate/assets/definitions/activation.template.json +0 -7
- package/skills/data360-orchestrate/assets/definitions/calculated-insight.template.json +0 -7
- package/skills/data360-orchestrate/assets/definitions/data-action-target.template.json +0 -5
- package/skills/data360-orchestrate/assets/definitions/data-action.template.json +0 -5
- package/skills/data360-orchestrate/assets/definitions/data-graph.template.json +0 -21
- package/skills/data360-orchestrate/assets/definitions/data-stream.template.json +0 -55
- package/skills/data360-orchestrate/assets/definitions/dmo.template.json +0 -17
- package/skills/data360-orchestrate/assets/definitions/identity-resolution.template.json +0 -30
- package/skills/data360-orchestrate/assets/definitions/mapping.template.json +0 -14
- package/skills/data360-orchestrate/assets/definitions/relationship.template.json +0 -12
- package/skills/data360-orchestrate/assets/definitions/search-index.template.json +0 -9
- package/skills/data360-orchestrate/assets/definitions/segment.template.json +0 -16
- package/skills/data360-orchestrate/references/feature-readiness.md +0 -157
- package/skills/data360-orchestrate/references/plugin-setup.md +0 -138
- package/skills/data360-orchestrate/scripts/bootstrap-plugin.sh +0 -53
- package/skills/data360-orchestrate/scripts/diagnose-org.mjs +0 -511
- package/skills/data360-orchestrate/scripts/generate-manifest.mjs +0 -68
- package/skills/data360-orchestrate/scripts/verify-plugin.sh +0 -58
- package/skills/data360-prepare/README.md +0 -50
- package/skills/data360-prepare/SKILL.md +0 -203
- package/skills/data360-prepare/examples/ingestion-api/.env.example +0 -8
- package/skills/data360-prepare/examples/ingestion-api/README.md +0 -48
- package/skills/data360-prepare/examples/ingestion-api/send-data.py +0 -144
- package/skills/data360-query/README.md +0 -43
- package/skills/data360-query/SKILL.md +0 -128
- package/skills/data360-query/examples/search-indexes/hybrid-structured.json +0 -44
- package/skills/data360-query/examples/search-indexes/vector-knowledge.json +0 -43
- package/skills/data360-segment/README.md +0 -35
- package/skills/data360-segment/SKILL.md +0 -123
- package/skills/service-helpagent-coordinate/references/channel-help-portal.md +0 -22
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-1-1-non-text-content.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-i-lists.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-ii-tables.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iii-form-labels.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iv-regions.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-v-groups.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-5-identify-input.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-4-3-contrast.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-1-1-keyboard.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-4-link-purpose.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-6-headings-labels.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-3-label-in-name.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-7-dragging-movement.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-1-on-focus.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-2-on-input.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-1-error-identification.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-2-labels-instructions.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-3-error-suggestion.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-i-name.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-ii-role.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-iii-value.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-1-1-non-text-content.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-1-use-of-color.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-10-resize-reflow.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-11-non-text-contrast.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-3-contrast.md +0 -0
- /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
|
|
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
|
-
|
|
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 |
|
|
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
|
|
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
|
-
**
|
|
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
|
|
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
|
-
|
|
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 **
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
|
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
|
|
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`.
|
|
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
|
-
###
|
|
207
|
+
### B2C guest labels request returns HTTP 403
|
|
204
208
|
|
|
205
|
-
**Symptom:**
|
|
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:**
|
|
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
|
|
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
|
-
|
|
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
|
-
//
|
|
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 }, //
|
|
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
|
|
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
|
|
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 `&`, `<` becomes `<`, and `>` becomes `>`. 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`
|
|
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
|
|
240
|
+
### 2. Add the untranslated Spanish scaffold
|
|
237
241
|
|
|
238
242
|
`force-app/main/default/translations/es.translation-meta.xml`:
|
|
239
243
|
```xml
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
<
|
|
243
|
-
</
|
|
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
|
|
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
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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).
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 +
|
|
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
|
---
|