{
  "features": {
    "angular-agentforce-conversation-client": {
      "name": "Angular Agentforce Conversation Client",
      "package": "@salesforce/ui-bundle-template-feature-angular-agentforce-conversation-client",
      "shortDescription": "Embed an Agentforce (employee) agent in an Angular UI Bundle via a drop-in <app-agentforce-conversation-client /> component",
      "longDescription": "A drop-in <app-agentforce-conversation-client /> Angular standalone component that embeds an Agentforce employee agent using the @salesforce/agentforce-conversation-client SDK over Lightning Out 2.0. Supply an agentId and the component renders a floating or inline conversation surface; an AgentforceEmbedService owns the one-time Lightning Out embed per window. In production the origin resolves from globalThis.SFDC_ENV.orgUrl; for local development the frontdoor URL is fetched from the dev server. Supports floating and inline rendering modes, header/avatar/icon visibility toggles, file-based agents, style-token theming, and ready/error callbacks. Intended for B2E (internal, employee-facing) apps. The wrapper pins showAvatar: false and channel: 'Vibes'.",
      "keywords": [
        "angular",
        "agentforce",
        "agent",
        "conversation",
        "chat",
        "lightning out",
        "acc",
        "b2e"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@salesforce/agentforce-conversation-client": "^12.0.0",
        "@angular/core": "^21.2.0"
      },
      "copy": [
        {
          "from": "force-app/main/default/uiBundles/feature-angular-agentforce-conversation-client/src/app/features/agentforce",
          "to": "<uiBundleDir>/src/app/features/agentforce",
          "description": "Agentforce conversation client: AgentforceConversationClientComponent and the AgentforceEmbedService that owns the one-time Lightning Out embed"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-agentforce-conversation-client/src/app/types/conversation.ts",
          "to": "<uiBundleDir>/src/app/types/conversation.ts",
          "description": "Public prop/option types for the conversation client component"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-agentforce-conversation-client/src/app/types/globals.d.ts",
          "to": "<uiBundleDir>/src/app/types/globals.d.ts",
          "description": "Ambient augmentation adding the optional SFDC_ENV.orgUrl field the embed service reads"
        }
      ],
      "features": [
        "Drop-in <app-agentforce-conversation-client /> component — supply an agentId to embed an employee agent",
        "Floating (default) and inline rendering modes with configurable width/height",
        "Header, avatar, and header-icon visibility toggles",
        "File-based agents via isFileBased",
        "Style-token theming through the styleTokens input",
        "Ready and error callbacks (onReady, onError)",
        "One-time Lightning Out embed per window managed by AgentforceEmbedService",
        "Origin auto-resolves from SFDC_ENV.orgUrl in production; frontdoor URL fetched in local dev"
      ],
      "components": [
        "AgentforceConversationClientComponent - Standalone component (selector app-agentforce-conversation-client) that embeds an Agentforce agent",
        "AgentforceEmbedService - Owns the one-time Lightning Out 2.0 embed and resolves the Salesforce origin"
      ]
    },
    "angular-authentication": {
      "name": "Angular Authentication",
      "package": "@salesforce/ui-bundle-template-feature-angular-authentication",
      "shortDescription": "Complete user authentication for Angular UI Bundles — login, registration, password management, session timeout, and route guards",
      "longDescription": "Complete user authentication system for Angular UI Bundles with login, registration, and password reset flows. Includes a functional route guard (authGuard) for protecting authenticated-only routes, an injectable AuthService that resolves the current user via UI API GraphQL (uiapi.currentUser), a session-timeout service, an AuthAppLayout route layout, and authentication pages (Login, Register, Profile, Forgot Password, Reset Password, Change Password) built with Angular standalone components, signals, and Reactive Forms. Ships the backend Apex classes (UIBundleLogin, UIBundleRegistration, UIBundleForgotPassword, UIBundleChangePassword, UIBundleAuthUtils) that handle authentication server-side. Routes are integrated by merging the feature's app.routes.ts into the app's route file — the top-level layout node swaps to AuthAppLayout, and the auth routes are appended alongside the app's existing routes.",
      "keywords": [
        "angular",
        "login",
        "register",
        "password reset",
        "protected routes",
        "auth",
        "session",
        "user management"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@angular/core": "^21.2.0",
        "@angular/router": "^21.2.0",
        "@angular/forms": "^21.2.0"
      },
      "copy": [
        {
          "from": "force-app/main/default/classes",
          "to": "<sfdxRoot>/classes",
          "description": "Apex authentication handler classes"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-authentication/src/app/features/authentication",
          "to": "<uiBundleDir>/src/app/features/authentication",
          "description": "Authentication library: authGuard, AuthService, session-timeout service, auth layout/forms, and shared UI helpers"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-authentication/src/app/api/user-profile.service.ts",
          "to": "<uiBundleDir>/src/app/api/user-profile.service.ts",
          "description": "GraphQL user-profile query/mutation service backing the profile page"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-authentication/src/app/pages/login",
          "to": "<uiBundleDir>/src/app/pages/login",
          "description": "Login page component"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-authentication/src/app/pages/register",
          "to": "<uiBundleDir>/src/app/pages/register",
          "description": "Registration page component"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-authentication/src/app/pages/forgot-password",
          "to": "<uiBundleDir>/src/app/pages/forgot-password",
          "description": "Forgot-password page component"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-authentication/src/app/pages/reset-password",
          "to": "<uiBundleDir>/src/app/pages/reset-password",
          "description": "Reset-password page component"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-authentication/src/app/pages/change-password",
          "to": "<uiBundleDir>/src/app/pages/change-password",
          "description": "Change-password page component"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-authentication/src/app/pages/profile",
          "to": "<uiBundleDir>/src/app/pages/profile",
          "description": "User profile page component"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-authentication/src/app/app.routes.ts",
          "to": "<uiBundleDir>/src/app/features/authentication/__example__authentication-routes.ts",
          "description": "Example route file showing the authentication routes and the AuthAppLayout swap — merge these into your app's route file",
          "integrationTarget": "src/app/app.routes.ts"
        }
      ],
      "features": [
        "Checks authentication status via UI API GraphQL (uiapi.currentUser)",
        "Protects routes with a functional authGuard that redirects to login",
        "Supports return URL (retUrl) query parameter for post-login navigation",
        "Session timeout with a configurable duration",
        "Password strength validation via hand-written reactive-form validators",
        "Forgot password and reset password flows",
        "User profile display and edit backed by GraphQL",
        "Change password functionality"
      ],
      "components": [
        "authGuard - Functional route guard for authenticated-only routes (canActivate: [authGuard])",
        "AuthService - Injectable service that resolves the current user and manages auth state",
        "AuthAppLayoutComponent - Route layout that hosts the authenticated shell",
        "AuthMenuComponent - Login/logout menu control",
        "SessionTimeoutService - Tracks inactivity and signs the user out on timeout",
        "LoginPageComponent - Login page",
        "RegisterPageComponent - Registration page",
        "ProfilePageComponent - User profile page",
        "ForgotPasswordPageComponent - Password recovery flow",
        "ResetPasswordPageComponent - Password reset page",
        "ChangePasswordPageComponent - Password change page"
      ]
    },
    "angular-language-switcher": {
      "name": "Angular Language Switcher",
      "package": "@salesforce/ui-bundle-template-feature-angular-language-switcher",
      "shortDescription": "B2X language switcher for Angular that rewrites the URL language segment and reloads the page",
      "longDescription": "A drop-in <app-language-switcher /> control for public B2X (Experience) Angular apps. It renders a labeled <select> of the site's supported languages; selecting one rewrites the current URL so the chosen language becomes the first path segment after basePath, then reloads the page at that new URL. A full reload lets the platform serve the correctly localized content — the feature owns only URL rewriting, not translation loading or i18n state. The current language is read from globalThis.SFDC_ENV.language, falling back to a default when absent or unrecognized. The list of available languages is hardcoded (in languages.ts) and manually kept in sync with the site's digitalExperiences/site/<siteName>/sfdc_cms__languageSettings/content.json, since there is no runtime API to read language settings on a published site. For LOCAL DEVELOPMENT, the feature integrates with the site entry of @salesforce/angular-plugin-ui-bundle: switch your middleware/html.mjs to import @salesforce/angular-plugin-ui-bundle and pass the supported LANGUAGES, and the dev server will inject SFDC_ENV.language and a language-prefixed basePath per request (mirroring production) so switching works locally without a server restart. This feature is intended for B2X apps only; B2E (internal) apps derive language from the logged-in user's profile and have no language URL segment.",
      "keywords": [
        "angular",
        "language",
        "language switcher",
        "locale",
        "localization",
        "i18n",
        "b2x",
        "url"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@angular/core": "^21.2.0",
        "@angular/router": "^21.2.0"
      },
      "copy": [
        {
          "from": "force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher",
          "to": "<uiBundleDir>/src/app/features/language-switcher",
          "description": "Language switcher library: LanguageSwitcherComponent, hardcoded language list, and the pure buildLanguageUrl URL-rewriting utility"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-language-switcher/src/types/globals.d.ts",
          "to": "<uiBundleDir>/src/types/language-switcher-globals.d.ts",
          "description": "Ambient augmentation adding the optional SFDC_ENV.language field the switcher reads"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/__examples__/language-switcher-example.ts",
          "to": "<uiBundleDir>/src/app/features/language-switcher/__examples__/language-switcher-example.ts",
          "description": "Example showing how to mount <app-language-switcher /> in an app header/layout",
          "integrationTarget": "src/app/components/layout/app-layout/app-layout.ts"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/__examples__/html-middleware-site-example.ts",
          "to": "<uiBundleDir>/src/app/features/language-switcher/__examples__/html-middleware-site-example.ts",
          "description": "Example showing how to switch middleware/html.mjs to the @salesforce/angular-plugin-ui-bundle entry so language switching works in local dev (inject SFDC_ENV.language + language-prefixed basePath)",
          "integrationTarget": "middleware/html.mjs"
        }
      ],
      "features": [
        "Rewrites the URL so the chosen language is the first path segment after basePath, then reloads",
        "Replaces an existing known language segment instead of stacking a new one",
        "Serves the default language un-prefixed: switching to it removes the language segment",
        "Preserves the rest of the path, the query string, and the hash when rewriting",
        "Reads the current language from SFDC_ENV.language with a safe default fallback",
        "Hardcoded language list kept in sync with the site's sfdc_cms__languageSettings content.json",
        "No-ops when the selected language already matches the current one",
        "Local dev: integrates with @salesforce/angular-plugin-ui-bundle to inject SFDC_ENV.language + a language-prefixed basePath per request, so switching works locally without a server restart"
      ],
      "components": [
        "LanguageSwitcherComponent - Standalone Angular component with labeled <select> that switches language via URL rewrite + reload",
        "buildLanguageUrl - Pure helper that inserts/replaces/removes the leading language path segment",
        "getCurrentLanguage - Resolves the active language from SFDC_ENV with default fallback",
        "LANGUAGES - Typed list of supported languages ({ code, label })",
        "DEFAULT_LANGUAGE - Default language code used when SFDC_ENV.language is missing/unknown"
      ]
    },
    "angular-object-search": {
      "name": "Angular Object Search",
      "package": "@salesforce/ui-bundle-template-feature-angular-object-search",
      "shortDescription": "Object search across Salesforce records for Angular UI Bundles — a searchable Account list with filters, sort, pagination, and a record detail page over GraphQL",
      "longDescription": "A concrete object-search experience for Angular UI Bundles: a searchable Account list with a debounced query box, a structured filter panel (text, select, multi-select, numeric range, date range), sortable columns, pagination, a breadcrumb, and an Account detail page — all backed by batched GraphQL operations. Built with Angular standalone components and signals; search state is owned by an ObjectSearchStateService and data is fetched through an AccountSearchService using GraphQL documents in app/api/account (searchAccounts, getAccountDetail, distinct industries/types). Routes are integrated by merging the feature's app.routes.ts into the app's route file, which wires the account-search index route and the accounts/:recordId detail route. Accounts are the shipped example object; the filter/sort/pagination library and services are structured so the same pattern can be pointed at other SObjects.",
      "keywords": [
        "angular",
        "search",
        "object search",
        "account",
        "filter",
        "sort",
        "pagination",
        "graphql",
        "records"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@angular/core": "^21.2.0",
        "@angular/router": "^21.2.0"
      },
      "copy": [
        {
          "from": "force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search",
          "to": "<uiBundleDir>/src/app/features/object-search",
          "description": "Object-search library: state service, search bar, filter panel (text/select/multi-select/numeric/date-range), sort control, pagination, breadcrumb, and utils"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/account",
          "to": "<uiBundleDir>/src/app/api/account",
          "description": "Account GraphQL operations (searchAccounts, getAccountDetail, distinct industries/types) and the AccountSearchService"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/graphql-operations-types.ts",
          "to": "<uiBundleDir>/src/app/api/graphql-operations-types.ts",
          "description": "Shared GraphQL operation types used by the account services"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/account-search",
          "to": "<uiBundleDir>/src/app/pages/account-search",
          "description": "Account search page"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/account-detail",
          "to": "<uiBundleDir>/src/app/pages/account-detail",
          "description": "Account detail page"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-angular-object-search/src/app/app.routes.ts",
          "to": "<uiBundleDir>/src/app/features/object-search/__example__object-search-routes.ts",
          "description": "Example route file wiring the account search index route and the accounts/:recordId detail route — merge these into your app's route file",
          "integrationTarget": "src/app/app.routes.ts"
        }
      ],
      "features": [
        "Debounced query box searching Salesforce records over GraphQL",
        "Structured filter panel: text, select, multi-select, numeric range, and date range filters",
        "Active-filter chips with individual removal",
        "Sortable columns with a configurable default sort",
        "Pagination with page navigation and configurable page size",
        "Breadcrumb navigation between the search list and a record detail page",
        "Distinct picklist values (industries, types) fetched from the org",
        "URL-aware search state for bookmarkable/shareable searches"
      ],
      "components": [
        "ObjectSearchStateService - Owns query, filter, sort, and pagination state",
        "AccountSearchService - Runs the account GraphQL search and detail queries",
        "AccountSearchPageComponent - The search list page (search bar + filters + results + pagination)",
        "AccountDetailPageComponent - The record detail page",
        "SearchBarComponent - Debounced global query input",
        "SearchFilterComponent - Filter panel host rendering the configured filter controls",
        "TextFilterComponent / SelectFilterComponent / MultiSelectFilterComponent - Picklist and text filters",
        "NumericRangeFilterComponent / DateRangeFilterComponent - Range filters",
        "ActiveFiltersComponent - Chip display of active filters with removal",
        "SortControlComponent - Sort field and direction control",
        "PaginationComponent - Page navigation and page-size control",
        "BreadcrumbComponent - Breadcrumb between list and detail"
      ]
    },
    "cms-toolkit": {
      "name": "CMS Toolkit",
      "package": "@salesforce/ui-bundle-template-feature-cms-toolkit",
      "shortDescription": "Framework-agnostic APIs for reading Salesforce CMS delivery content (by public URL or contentKey, single or bulk) and decoding RichText.",
      "longDescription": "Pure TypeScript library — no React/Angular/Vue — for reading Salesforce CMS delivery content. Provides unauthenticated public-URL reads (public CDN), authenticated by-contentKey reads (single and bulk) via the Connect API, CMS image-field URL resolution, RichText HTML-entity decoding, catalog-driven channel resolution, and source→target contentKey remapping (so one build runs against any org without re-baking keys). Consumers call the exported functions directly from their own framework pages; framework-specific renderers live in the consuming app, not here. The public surface is additive-only: new capability arrives as new optional options, new named exports, or new error subclasses — never as a changed signature.",
      "keywords": [
        "cms",
        "content",
        "delivery",
        "richtext",
        "connect api",
        "contentKey",
        "channel",
        "image",
        "framework-agnostic"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@salesforce/platform-sdk": "^12.0.0",
        "@salesforce/ui-bundle": "^12.0.0"
      },
      "copy": [
        {
          "from": "src/force-app/main/default/uiBundles/feature-cms-toolkit/src/features/cmsToolkit",
          "to": "<uiBundleDir>/src/features/cmsToolkit",
          "description": "CMS delivery API (public + authenticated Connect transports), catalog loader, image URL and RichText decode utilities, and shared types"
        },
        {
          "from": "src/force-app/main/default/uiBundles/feature-cms-toolkit/src/index.ts",
          "to": "<uiBundleDir>/src/__example__index.ts",
          "description": "Barrel of public exports — re-export the functions and types you need from your own app entry point",
          "integrationTarget": "src/index.ts"
        }
      ],
      "features": [
        "getCmsContentByUrl — read a public CMS delivery URL (unauthenticated CDN)",
        "getCmsContentByKey — read one item by contentKey via the authenticated Connect API (throws on miss)",
        "getCmsContentByKeys — bulk read many contentKeys in one call (best-effort; per-key error/result)",
        "resolveCmsImageUrl — resolve a CMS image field to a loadable URL (external or root-relative, origin-prefixed); synchronous and localizes root-relative media via the language chain",
        "resolveMediaUrl — resolve a raw media URL string to a loadable URL (localise root-relative CMS media then origin-prefix; foreign CDN urls untouched); the string-input sibling of resolveCmsImageUrl",
        "resolveCmsLanguage — async: resolve the active delivery language (explicit → SFDC_ENV.language → platform-sdk i18n) and warm the cache",
        "getResolvedCmsLanguage — sync: read the active language (explicit → SFDC_ENV.language → warmed i18n); backs the synchronous resolveCmsImageUrl",
        "localiseMediaUrl — sync: read the active language (via getResolvedCmsLanguage) and append it to a directly-passed media URL (render-time sibling of resolveCmsImageUrl)",
        "localiseCmsUrl — async: resolve the active language (performing the i18n fetch if needed) and append it to a directly-passed content/media URL",
        "appendLanguageParam — sync/pure: set or override the language query param on a URL (removes duplicates; otherwise byte-for-byte)",
        "resolveEffectiveContentKey — remap a baked-in source contentKey to the deployed org's target key via the catalog",
        "getCmsDefaultChannelId — read the catalog's default channelId (fail-open; undefined when absent)",
        "decodeRichHtmlEntities — decode entity-encoded RichText to literal characters before sanitize + injection",
        "getCmsInstanceOrigin — read the instance origin used to prefix root-relative media URLs",
        "Catalog loader — fail-open, fetch-once channelId and contentKey-map resolution from content-metadata.json",
        "Typed error subclasses (CmsDeliveryError, CmsDeliveryNotFoundError, ConnectApiError, CmsNotFoundError) stable for instanceof checks"
      ],
      "components": [
        "getCmsContentByUrl / getCmsContentByKey / getCmsContentByKeys - CMS delivery read functions",
        "resolveCmsImageUrl - CMS image field → loadable URL resolver (synchronous)",
        "resolveMediaUrl - raw media URL string → loadable URL resolver (synchronous)",
        "resolveCmsLanguage / getResolvedCmsLanguage - active delivery language resolvers (async warm / sync read)",
        "localiseMediaUrl / localiseCmsUrl / appendLanguageParam - URL language-param localizers (sync / async / sync-pure)",
        "resolveEffectiveContentKey - catalog source→target contentKey remapper",
        "getCmsDefaultChannelId - catalog default channelId accessor (fail-open)",
        "decodeRichHtmlEntities - RichText HTML-entity decoder (single pass, no DOM)",
        "getCmsInstanceOrigin - instance origin accessor for media prefixing",
        "CmsReadOptions (incl. language) / CmsImageOptions / ResolveLocaleOptions / CmsBulkResult / CmsContentBody / CmsImageField / CmsContentCatalog - shared types",
        "CmsDeliveryError / CmsDeliveryNotFoundError / ConnectApiError / CmsNotFoundError - typed errors"
      ]
    },
    "authentication": {
      "name": "Authentication",
      "package": "@salesforce/ui-bundle-template-feature-react-authentication",
      "shortDescription": "Complete user authentication system with login, registration, and password management",
      "longDescription": "Complete user authentication system with login, registration, and password reset flows. Includes protected route guards, session management, and authentication context providers. Handles user state across the application with secure token storage and automatic session refresh. Features include: AuthContext for managing auth state, PrivateRoute component for protecting authenticated-only pages, authentication pages (Login, Register, Profile, Forgot Password, Reset Password, Change Password), and backend Apex classes for authentication handling.",
      "keywords": [
        "login",
        "register",
        "password reset",
        "protected routes",
        "auth",
        "session",
        "user management"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@salesforce/platform-sdk": "^4.0.0",
        "@salesforce/ui-bundle": "^4.0.0",
        "@tanstack/react-form": "^1.28.3",
        "zod": "^4.3.6"
      },
      "copy": [
        {
          "from": "force-app/main/default/classes",
          "to": "<sfdxRoot>/classes",
          "description": "Apex authentication handler classes"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-authentication/src/features/authentication",
          "to": "<uiBundleDir>/src/features/authentication",
          "description": "Authentication components, context, and pages"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-authentication/src/routes.tsx",
          "to": "<uiBundleDir>/src/features/authentication/__example__authentication-routes.tsx",
          "description": "Example showing how to add authentication routes",
          "integrationTarget": "src/routes.tsx"
        }
      ],
      "features": [
        "Checks authentication status via UI API GraphQL (uiapi.currentUser)",
        "Protects routes with automatic redirect to login",
        "Supports return URL (retUrl) query parameter for post-login navigation",
        "Session timeout with configurable duration",
        "Password strength validation",
        "Forgot password and reset password flows",
        "User profile display",
        "Change password functionality"
      ],
      "components": [
        "AuthContext - React context for managing authentication state",
        "AuthMenu - Composable authentication menu with login/logout dropdown",
        "PrivateRoute - Route protection for authenticated-only pages",
        "AuthenticationRoute - Route layout that redirects authenticated users",
        "Login - Login page component",
        "Register - Registration page component",
        "Profile - User profile page",
        "ForgotPassword - Password recovery flow",
        "ResetPassword - Password reset page",
        "ChangePassword - Password change page"
      ]
    },
    "language-switcher": {
      "name": "Language Switcher",
      "package": "@salesforce/ui-bundle-template-feature-react-language-switcher",
      "shortDescription": "B2X language switcher that rewrites the URL language segment and reloads the page",
      "longDescription": "A drop-in <LanguageSwitcher /> control for public B2X (Experience) apps. It renders a labeled <select> of the site's supported languages; selecting one rewrites the current URL so the chosen language becomes the first path segment after basePath, then reloads the page at that new URL. A full reload lets the platform serve the correctly localized content — the feature owns only URL rewriting, not translation loading or i18n state. The current language is read from globalThis.SFDC_ENV.language, falling back to a default when absent or unrecognized. The list of available languages is hardcoded (in languages.ts) and manually kept in sync with the site's digitalExperiences/site/<siteName>/sfdc_cms__languageSettings/content.json, since there is no runtime API to read language settings on a published site. For LOCAL DEVELOPMENT, the feature integrates with the site entry of @salesforce/vite-plugin-ui-bundle: switch your vite.config.ts to import @salesforce/vite-plugin-ui-bundle/site and pass the supported LANGUAGES, and the dev server will inject SFDC_ENV.language and a language-prefixed basePath per request (mirroring production) so switching works locally without a server restart. This feature is intended for B2X apps only; B2E (internal) apps derive language from the logged-in user's profile and have no language URL segment.",
      "keywords": [
        "language",
        "language switcher",
        "locale",
        "localization",
        "i18n",
        "b2x",
        "url"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "react": "^19.2.1",
        "react-router": "^7.15.1"
      },
      "copy": [
        {
          "from": "force-app/main/default/uiBundles/feature-react-language-switcher/src/features/language-switcher",
          "to": "<uiBundleDir>/src/features/language-switcher",
          "description": "Language switcher library: <LanguageSwitcher /> component, hardcoded language list, and the pure buildLanguageUrl URL-rewriting utility"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-language-switcher/src/types/globals.d.ts",
          "to": "<uiBundleDir>/src/types/language-switcher-globals.d.ts",
          "description": "Ambient augmentation adding the optional SFDC_ENV.language field the switcher reads"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-language-switcher/src/features/language-switcher/__examples__/language-switcher-example.tsx",
          "to": "<uiBundleDir>/src/features/language-switcher/__examples__/language-switcher-example.tsx",
          "description": "Example showing how to mount <LanguageSwitcher /> in an app header/layout",
          "integrationTarget": "src/appLayout.tsx"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-language-switcher/src/features/language-switcher/__examples__/vite-config-site-example.ts",
          "to": "<uiBundleDir>/src/features/language-switcher/__examples__/vite-config-site-example.ts",
          "description": "Example showing how to switch vite.config.ts to the @salesforce/vite-plugin-ui-bundle/site entry so language switching works in local dev (inject SFDC_ENV.language + language-prefixed basePath)",
          "integrationTarget": "vite.config.ts"
        }
      ],
      "features": [
        "Rewrites the URL so the chosen language is the first path segment after basePath, then reloads",
        "Replaces an existing known language segment instead of stacking a new one",
        "Serves the default language un-prefixed: switching to it removes the language segment",
        "Preserves the rest of the path, the query string, and the hash when rewriting",
        "Reads the current language from SFDC_ENV.language with a safe default fallback",
        "Hardcoded language list kept in sync with the site's sfdc_cms__languageSettings content.json",
        "No-ops when the selected language already matches the current one",
        "Local dev: integrates with @salesforce/vite-plugin-ui-bundle/site to inject SFDC_ENV.language + a language-prefixed basePath per request, so switching works locally without a server restart"
      ],
      "components": [
        "LanguageSwitcher - Drop-in labeled <select> that switches language via URL rewrite + reload",
        "buildLanguageUrl - Pure helper that inserts/replaces/removes the leading language path segment",
        "getCurrentLanguage - Resolves the active language from SFDC_ENV with default fallback",
        "LANGUAGES - Typed list of supported languages ({ code, label })",
        "DEFAULT_LANGUAGE - Default language code used when SFDC_ENV.language is missing/unknown"
      ]
    },
    "mfa": {
      "name": "MFA",
      "package": "@salesforce/ui-bundle-template-feature-react-mfa",
      "shortDescription": "Enable Multi-Factor Authentication for Experience Cloud React sites",
      "longDescription": "Deploys permission sets to enable MFA enforcement for community users. Includes MFA_Required_For_Community (ForceTwoFactor) and API_Enabled_For_Community (ApiEnabled). The platform MFA challenge UI handles the actual verification flow automatically — no custom React component is needed. Supports TOTP, Salesforce Authenticator, WebAuthn, SMS, and Email OTP verification methods.",
      "keywords": [
        "mfa",
        "multi-factor",
        "authentication",
        "security",
        "2fa",
        "totp",
        "permission set",
        "ForceTwoFactor"
      ],
      "featureDependencies": [],
      "packageDependencies": {},
      "packageDevDependencies": {},
      "copy": [
        {
          "from": "src/force-app/main/default/permissionsets",
          "to": "<sfdxSource>/permissionsets",
          "description": "MFA and API Enabled permission sets for community users"
        }
      ],
      "features": [
        "Permission set: MFA_Required_For_Community (enforces MFA at login via ForceTwoFactor)",
        "Permission set: API_Enabled_For_Community (enables REST API access for React sites)",
        "Works with platform OOTB MFA challenge UI (no custom React page needed)",
        "Supports TOTP, SMS, Email, Salesforce Authenticator, and WebAuthn verification methods"
      ],
      "components": []
    },
    "search": {
      "name": "Search (Beta)",
      "package": "@salesforce/ui-bundle-template-feature-react-search",
      "shortDescription": "[Beta] Configuration-driven multi-source (multi-object) search with one query box, per-source filters/sort, and global or per-source pagination over GraphQL",
      "longDescription": "[Beta — API may change in a future release] Configuration-driven unified search across multiple Salesforce objects from a single query box. The application declares a SearchConfig with one entry per searchable SObject source; the library handles query construction, per-source filter/sort/pagination state, URL sync, and a single batched multi-aliased GraphQL request that fans out across every source. Supports two pagination models: per-source cursor pagination (each source advances its own Relay cursor) and merged/global pagination (the cumulative result set is windowed into fixed pages of pageSize). Provides a drop-in <Search> component plus lower-level primitives (useSearch hook, SearchBar, SearchResults, ScopeSelector, sort and pagination controls) and a configuration-driven filter panel (text, select, multi-select, numeric range, date range, boolean). Results can render one section per source or as a single combined grid via mergedResults, and a scope selector narrows the search to a single object or 'all'.",
      "keywords": [
        "search",
        "multi-object",
        "unified search",
        "global search",
        "filter",
        "sort",
        "pagination",
        "GraphQL",
        "scope",
        "multi-source",
        "beta"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@salesforce/platform-sdk": "^11.2.0",
        "lucide-react": "^0.562.0",
        "react-router": "^7.10.1"
      },
      "copy": [
        {
          "from": "force-app/main/default/uiBundles/feature-react-search/src/features/search",
          "to": "<uiBundleDir>/src/features/search",
          "description": "Multi-source search library: useSearch hook, drop-in <Search> component, scope selector, filter panel, sort and pagination controls, query builder, GraphQL search service, and the example config.json"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-search/src/pages/Home.tsx",
          "to": "<uiBundleDir>/src/features/search/__examples__/search-page-example.tsx",
          "description": "Example page rendering the drop-in <Search config={config} /> — shows how to mount the search experience on a route",
          "integrationTarget": "src/routes.tsx"
        }
      ],
      "features": [
        "Configuration-driven multi-object search from a single query box",
        "One batched multi-aliased GraphQL request fans out across all in-scope sources",
        "Two pagination models: per-source cursor pagination and merged/global fixed-size pagination",
        "Merge ordering for the combined result list: sequential, interleaved, or proportional",
        "Scope selector to narrow the search to a single object or search across all",
        "Per-source structured filters: text, select, multi-select, numeric range, date range, boolean",
        "Per-source sort controls with configurable sort fields and default sort",
        "URL-synced query, scope, filters, sort, and pagination for bookmarkable/shareable searches",
        "Drop-in <Search> component (one section per source) plus low-level primitives for custom layouts",
        "mergedResults for rendering a single combined cross-source grid",
        "Extensible adapter boundary — SObject sources today, room for CMS/REST adapters"
      ],
      "components": [
        "Search - Drop-in multi-source search experience (search bar, scope, sections, pagination)",
        "useSearch - Hook orchestrating query, scope, per-source filter/sort/pagination, URL sync, and fetch",
        "SearchBar - Global query input driving every source",
        "ScopeSelector - Dropdown to narrow search scope to one source or 'all'",
        "SearchResults - Renders in-scope source results",
        "SourceSection - One result section for a single source",
        "SortControl - Per-source sort field and direction dropdown",
        "PaginationControls - Pagination with page navigation and configurable page size",
        "DefaultFilterPanel - Sidebar panel rendering filter controls from config",
        "DefaultResultRow - Default renderer for a single result node",
        "ActiveFilters - Chip display of active filters with removal",
        "FilterContext - FilterProvider and hooks (useFilterField, useFilterPanel) for custom filter UIs",
        "TextFilter - Debounced text input filter",
        "SelectFilter - Single-select picklist filter",
        "MultiSelectFilter - Multi-select picklist filter",
        "NumericRangeFilter - Min/max numeric range filter",
        "DateRangeFilter - Date range filter with start/end pickers",
        "BooleanFilter - Boolean toggle filter",
        "useDistinctValues - Hook for fetching distinct picklist values",
        "useAsyncData - Hook for async data fetching with loading/error states",
        "queryBuilder - Builds the multi-aliased GraphQL document and variables",
        "searchService - Runs the batched GraphQL search and parses per-source results",
        "filterUtils / sortUtils / fieldUtils - URL serialization, GraphQL filter/order building, field extraction"
      ]
    }
  }
}
