Broadleaf Microservices
  • v1.0.0-latest-prod

Upgrade to 2.3.1

Requirements

  • Java 17 is required since 2.0.0-GA.

Notable Changes

Notable Changes from 2.3.0 RT

Introduced new Workflow Service
Introduced new Audit Service
Introduced Subscription Lifecycle & Billing Functionality
  • Impacted Services: CatalogServices, PricingServices, OfferServices, CartOperationServices, OrderOperationServices, SubscriptionOperationServices, BillingServices, WorkflowServices, AuditServices

  • Highlights:

    • Subscription Purchase & Fulfillment: Out-of-box support for handling subscription-based products directly within the cart & checkout.

    • Subscription Management: Manage the full subscription lifecycle with configurable edit, upgrade, downgrade, and cancellation scenarios. Includes advanced support for sandboxing and delayed prepaid actions.

    • Recurring Billing: A highly configurable recurring billing engine that works in conjunction with Broadleaf’s Catalog, Pricing, and Offer Engines to support complex or unique recurring billing needs.

    • CSR Interactions: Allow CSRs to manage subscriptions price changes and add discounts to existing subscriptions.

Introduction of Chase Payment integration module

New and Notable Changes

Support for Kafka KRaft and Strimzi Operator
Support for Fees and Fee Calculation for Cart Pricing
Support Retail Delivery Fees from Avalara Tax
Added Domain Support for Default Frequency for Products with Recurring Pricing
Microservice Gateways Performance Improvements
  • Impacted Services: Microservices Gateways

  • Highlights:

    • Rewrote OAuth2ClientCredentialsGatewayFilterFactory to use a fully non-blocking mechanism for all logic related to obtaining a new access token.

    • Rewrote ApplicationTokenGatewayFilterFactory and ExternalApplicationResolverService to move blocking cache interactions off of the event loop thread and into worker threads.

  • Links: Please refer to Gateways 2.0.5

Confirmed Node 22 and 24 Support for Frontend Projects
New Components and Component Enhancements
Introduced TenantService Component to make interactions with Tenant Microservice extensible
Removed Bootstrap dependency
Added support for customizing access token cache key
  • Impacted Services: Auth SDK (@broadleaf/auth-web)

  • Links: Please refer to Auth JS SDK 1.6.6

Support Specifying Variant Hydration Behavior in Product Details Requests
Introduced Lightweight Inventory Availability Index Based on Lite Variant Details
Introduced New API for Consolidated Returnable Items and Fees Information
Support for Consolidated OMS Refund Transactions
Support for Two-Tier Pricing using Attributes and Characteristics
Added new Price List Types
Introduced Pricing Categories
Introduced Variant Pricing Strategy
Updated TMForumExtensions module for compatibility with the latest Broadleaf 2.3.0 release train

Breaking Changes Requiring Action

Added support for Caffeine and Ehcache as Spring Cache options
  • Impacted Services: All services implementing caching

  • Required action: In 2.3.0+, Caffeine is the new default cache implementation.

    • Code and property changes are required to fully migrate from Ignite to Caffeine.

      • Please review the Switching to Caffeine documentation for more details

      • Both Caffeine and Ehcache leverage Apache Fury for serialization, and this requires explicitly configuring a whitelist of serializable classes. Ensure that package prefixes for your custom classes are included in this whitelist. For more details about this, please see Caching Serialization Configuration.

    • Alternatively, if immediately migrating to Caffeine is not possible, you can continue using the deprecated Ignite approach by explicitly setting com.broadleafcommerce.cache.activeCacheManagerImplementation=com.broadleafcommerce.common.extension.autoconfigure.IgniteCacheAutoConfiguration in your configuration properties.

  • Links: Please refer to Caching for more information.

ProductCharacteristic domain separation

Notable Bug Fixes

Fixed RecordTooLargeException from Changing Status of a Large Fulfillment
Fixed Various Refund Bugs

Notable Changes from 2.3.1 RT

Feature/Notable Change Impacted Services Links

Impersonation Security Scope

Authentication Services

Payment Lock Tokens When Removing Invalid Offer Codes

Cart Operation Services

Placeholder Characteristics and Catalog Bug Fixes

Catalog Services

Frontend Compatibility and Release Notes

Unified Admin Release Notes for 2.1.0

Important
  • Requires Node ≥22, React ≥19, React Router ≥6

Features & Enhancements

Introduced ThemeProvider and update existing CSS
Tip
This provides Runtime Admin Theming Support.

We introduced a robust, CSS-variable-based runtime theming engine for the Admin application. The foundation is highly extensible, memory-leak safe, and 100% backwards compatible for downstream apps that do not wish to utilize theming.

Key Features
  • Dynamic Theming Engine: Introduced a new <ThemeProvider> that programmatically accepts a nested Theme object and dynamically injects scoped CSS variables (e.g., --tw-colors-primary-500) into the document :root.

  • AdminProvider Integration: Integrated the new <ThemeProvider> directly into <AdminProvider>, allowing the theme to be passed cleanly as a top-level prop without disturbing existing context setups.

  • Tailwind Plugin & Config Upgrades:

    • Updated @broadleaf/admin-tailwindcss to utilize safe CSS variable fallbacks across all branding colors, mapping gray to the secondary scale and red to the danger scale.

    • Added a new adminTheme Tailwind plugin to dynamically generate shell-specific styling utilities (tw-shell-nav- and tw-shell-header-).

  • Shell Chrome Migration: Surgically migrated legacy SCSS from structural components like <Navigation> and <Header> to leverage the new theme-aware Tailwind classes instead of hardcoded background colors.

  • SASS Color Function Removal: Removed legacy SASS functions (like lighten() or color-yiq()) from older components in @broadleaf/admin-style, allowing them to safely compile and consume the new dynamic CSS variable fallbacks seamlessly.

How it works

You can now theme the admin by supplying a theme prop to your <AdminProvider>:

import { AdminProvider, Theme } from '@broadleaf/admin-components';

const brandTheme: Theme = {
  colors: {
    primary: { /* 50-950 scale */ },
    secondary: { /* 50-950 scale (defaults to Tailwind 'gray') */ },
    danger: { /* 50-950 scale (defaults to Tailwind 'red') */ },
    link: '#3b82f6',
    linkHover: '#2563eb'
  },
  shell: {
    nav: { bg: '#111827', text: '#d1d5db', active: '#1f2937' },
    header: { bg: '#1f2937' }
  }
};

const App = () => (
  <AdminProvider theme={brandTheme}>
    {/* Admin Routes */}
  </AdminProvider>
);
Cleaned up BaseLayout to be only concerned with layout

We introduced a significant architectural cleanup to the <BaseLayout> component and its associated global elements. The goal of this refactor is to improve component cohesion, enable granular overrides for downstream consumers, and future-proof the codebase for modern React paradigms like Server Components (RSC).

1. Global Context Provider Extraction

The <BaseLayout> component was previously cluttered with global context providers and structural modals. These have been cleanly extracted: * ToastContainerContextProvider: Extracted the toast state logic into its own dedicated context provider. * ConfirmModalContextProvider: Extracted the confirmation modal state. The actual <ConfirmModal /> element is now rendered natively inside this provider (after {children}) rather than hanging off the <BaseLayout>. * Both of these new providers have been injected into the default array of the <GlobalProviders> component, ensuring they are available across all routes without cluttering the layout tree.

2. Component Overrides

To provide maximum flexibility for downstream applications, the following global UI components have been wrapped in enableOverrides, allowing them to be swapped out completely: * ConfirmModal * ToastContainer * TransitionToasts * Toast

3. Flat Exports for <ScrollView> (Tree-shaking & RSC Support)

The <ScrollView> component was previously exposing its sub-components via dot-notation (e.g., ScrollView.Header). This has been refactored to use named flat exports (ScrollViewHeader, ScrollViewContent, ScrollViewFooter). * Why? Flat exports drastically improve tree-shaking by allowing bundlers to eliminate dead code. Furthermore, in React Server Component (RSC) environments (like Next.js App Router), dot-notation forces the entire object tree to be treated as a Client Component. Flat exports allow for granular server/client boundary definitions. * Backwards Compatibility: The dot-notation accessors have been kept intact on the default export but are marked as @deprecated.

4. Header & AuthService Cohesion

Removed AuthService dependency injection from <BaseLayout>. The <Header> component now directly imports and handles its own logout and changePassword logic, resulting in a much dumber, cleaner layout wrapper.

Deprecations

The following properties/accessors have been marked as @deprecated and should be migrated to their new paradigms: * ScrollView.Header → Use named import ScrollViewHeader * ScrollView.Content → Use named import ScrollViewContent * ScrollView.Footer → Use named import ScrollViewFooter * HeaderProps.onLogoutClick → Handled internally by <Header> * HeaderProps.onChangePasswordClick → Handled internally by <Header>

Enabled decoupling the rendering of Admin NavMenuItems from Routes
Important
Requires Admin Navigation Services 3.0.0, which is part of Release Train 3.0.0 but also compatible with Release Train 2.3.1 if upgrading independently.

We introduced the ability for Menu Items defined in the Admin Navigation Service to be rendered independently of any Metadata Routes. They can now be filtered by their own predicates in a similar fashion to Routes, e.g., only return this item in a Tenant context rather than an Application. They can also define the security scopes for whether the user has access to see them similar to Routes, e.g., a user needs READ_PRODUCT to see this item.

  • Introduced VITE_MAIN_NAVIGATION_BEHAVIOR. To trigger the new behavior set it to ROUTE_INDEPENDENT

  • Introduced new hook, useSecureNavMenuItem to check whether the user has access to a NavMenuItem either using the old behavior based on a matching route or the new behavior checking the scopes of the NavMenuItem directly

  • Added debug logging to help diagnose why menu items appear or don’t appear

    • Enable using VITE_

  • Fixed lack of typing and documentation for various pieces of the UserOperationContext and related reducers to address technical debt in this area.

  • Deprecated useGetMatchingRoutesWithAccess and useHasMatchingRoute. Instead, useSecureNavMenuItem should be used as it returns both whether the module or submodule has access as well as the map of URL/path for each submodule to whether it has access specifically.

  • Removed access check in NavSection as the access checks for each section has already been done by the time the component is rendered. Instead filtration of the submenu items is explicitly done before rendering any NavSections.

Modularized Metadata Route Rendering & Shell Extraction

We decoupled the application routing logic from the structural UI shell. Previously, AdminApp was tightly coupled to both the layout and the React Router definition, making it difficult for downstream consumers to inject custom routing or entirely replace the application shell.

1. Extraction of AdminRoutes

The react-router-dom <Routes> definition and the metadata-driven route grouping logic have been extracted from AdminApp into a new, standalone <AdminRoutes> component. * This component is purely responsible for consuming the ComponentRouterContext and dynamically rendering the ComponentRouteResolver for each path. * New Injection Slots: <AdminRoutes> now accepts beforeRoutes and afterRoutes props (typed as ReactNode). This allows downstream consumers to seamlessly inject custom static routes alongside the dynamically generated metadata routes without interfering with the 404 catch-all logic.

2. Shell Injection via AdminApp (Slot Pattern)

The <AdminApp> component has been refactored to fully support the slotted children pattern. * If children are provided to <AdminApp>, it now acts strictly as a lifecycle/routing wrapper and renders the provided children directly. This explicitly supports downstream architectures (such as Capibara) that need to inject and manage their own UI shell layout. * Backwards Compatibility: If no children are provided, <AdminApp> gracefully falls back to the original Out-Of-The-Box (OOB) behavior, rendering <BaseLayout><AdminRoutes /></BaseLayout>.

3. Routing Context Lifecycle Audit

Verified that the ComponentRouterContext population is strictly decoupled from the UI shell rendering. The ComponentRouter gateway successfully blocks rendering via the GatewayProvider until all metadata routes are fetched and the context is fully hydrated. This guarantees that any custom shell or route definition passed into the application will have immediate, synchronous access to the fully resolved routing state.

Optimized fulfillment inventory data loading
  • Optimize fulfillment inventory loading to reduce redundant requests due to component re-renders

  • Fixed an issue where an incorrect quantity value was used during fulfillment

  • Updated useFulfillmentInventory to replace the skuCodes parameter with fulfillments

  • Separated inventoryQuantities from StatusChangeContext into a new InventoryContext

    • Note: A withInventoryContext provider is available to allow existing components taking in an inventoryQuantities prop to continue working as previously

Enhanced Extensibility of the Application Selector Component

Moved internal logic of <ApplicationSelector> into a useApplicationSelector hook, encapsulating the state, fetch orchestration, authorization logic, and event callbacks for selecting the active application context. This allows easier customization of the <ApplicationSelector> in the nav sidebar.

import useApplicationSelector from '@broadleaf/admin-components/dist/view/components/ApplicationSelector/hooks/useApplicationSelector';

export const CustomApplicationSelector = () => {
  const {
    application,
    applications,
    isLoading,
    formattedMessages,
    handleApplicationChange,
    queueFetchApplications,
    resolveApplicationsWithQuery
  } = useApplicationSelector();

  return <>{/* Custom Selector Component */}</>;
}
Added support for overriding out-of-box Application and Metadata splash screens

These components are rendered while resolving the Application and Metadata Routes or when those requests encounter an error. This covers the following:

  • App-Level Error and Loading Splash (AppSplash)

    • Registered as blAppSplash

    • Subcomponents that support overrides

      • blAppSplashOverlay for AppSplashOverlay

      • blAppSplashBackground for AppSplashBackground

      • blAppSplashLoading for AppSplashLoading

      • blAppSplashError for AppSplashError

      • blAppSplashErrorNotFound for AppSplashErrorNotFound

      • blAppSplashErrorUnauthorized for AppSplashErrorUnauthorized

      • blAppSplashErrorServer for AppSplashErrorServer

      • blAppSplashErrorUnknown for AppSplashErrorUnknown

      • blAppSplashErrorTemplate for AppSplashErrorTemplate

  • Route/Metadata-Level Error and Loading Splash (ComponentRouteSplash)

    • Registered as blComponentRouteSplash

      • Subcomponents that support overrides

  • blTransitionComponentRouteSplashOverlay for TransitionComponentRouteSplashOverlay

  • blComponentRouteSplashOverlay for ComponentRouteSplashOverlay

  • blComponentRouteSplashBackground for ComponentRouteSplashBackground

  • blComponentRouteSplashLoading for ComponentRouteSplashLoading

  • blComponentRouteSplashError for ComponentRouteSplashError

  • blComponentRouteSplashErrorNotFound for ComponentRouteSplashErrorNotFound

  • blComponentRouteSplashErrorUnauthorized for ComponentRouteSplashErrorUnauthorized

  • blComponentRouteSplashErrorServer for ComponentRouteSplashErrorServer

  • blComponentRouteSplashErrorUnknown for ComponentRouteSplashErrorUnknown

  • blComponentRouteSplashErrorTemplate for ComponentRouteSplashErrorTemplate

Modularized the Main Navigation Components

We refactored the monolithic <Navigation> component into a set of highly granular, composable layout building blocks backed by a centralized context provider. These changes enable users to build entirely custom navigation shells, e.g., top-level headers, custom mobile sidebars, off-canvas menus, while preserving the exact out-of-the-box (OOB) Admin navigation layout and DOM structure. Users can now leverage the NavigationContextProvider alongside individual <Nav*> layout components to compose entirely custom sidebar or header shell layouts without needing to manually lift state or drill props. The default <Navigation> component continues to function identically without requiring downstream changes.

Key Changes:
  • State Extraction: Extracted all data fetching logic, cache interactions, and UI state (menuOpen, menuCollapsed, isHovered, filter) from the main component into a new NavigationContextProvider.

  • Granular Layout Building Blocks: Created atomic <Nav*> wrappers for each semantic layout section (<NavWrapper>, <NavMain>, <NavHeader>, <NavMenuWrapper>, <NavErrorSection>, <NavFooter>).

  • Layout V2 Alignment: Removed legacy branching logic from the new navigation wrappers, standardizing entirely on Layout V2 semantic HTML tags (<nav>, <section>, <header>, <aside>, <footer>).

  • OOB Preservation: Rebuilt the default <Navigation> component as a strict composition of these new atomic layout wrappers to ensure no regressions in default styling or DOM behavior.

  • Expanded Exports: Exported all atomic navigation blocks, types, contexts, and hooks to the root index layer for downstream consumption. All new wrappers are fully extensible via enableOverrides.

Example Custom Navigation
import {
  NavWrapper,
  NavMain,
  NavErrorSection,
  NavError,
  NavMenu,
  NavFooter,
  NavCollapser,
  NavMobileToggle,
  NavigationContextProvider,
  useNavigationContext
} from '@broadleaf/admin-components/dist/view';

export const CustomNavigation: React.FC = () => {
  const {
    isError,
    isSuccess,
    menuCollapsed,
    menuOpen,
    isHovered,
    filter,
    setFilter,
    setMenuOpen,
    setMenuCollapsed,
    setIsHovered,
    modules,
    fetchNavigation
  } = useNavigationContext();

  return (
    <NavigationContextProvider>
      <NavWrapper>
        <NavMain>
          {isError && (
            <NavErrorSection>
              <NavError fetchNavigation={fetchNavigation} />
            </NavErrorSection>
          )}

          {isSuccess && (
            <NavMenu
              filter={filter}
              modules={modules}
              setFilter={setFilter}
              setMenuOpen={setMenuOpen}
              menuCollapsed={menuCollapsed && !isHovered && !menuOpen}
            />
          )}
        </NavMain>

        <NavFooter>
          <NavCollapser
            menuCollapsed={menuCollapsed}
            setMenuCollapsed={val => {
              setMenuCollapsed(val);
              setMenuOpen(!val);
              setIsHovered(false);
            }}
          />
        </NavFooter>
      </NavWrapper>

      <NavMobileToggle
        menuOpen={menuOpen}
        setMenuOpen={val => {
          setMenuOpen(val);
          setMenuCollapsed(!val);
        }}
      />
    </NavigationContextProvider>
  );
};
Introduced support for an admin user to see and copy generated API key values
Important
Requires Metadata 2.0.9-GA (Release Trains 2.3.1, 2.2.3, 2.1.7) or 3.0.0-GA (Release Train 3.0.0).

Introduces support for a "One-Time Success Response" feature, providing a highly integrated framework for safely displaying sensitive, transient API response payloads (such as generated API keys) natively within the Admin UI. This feature looks for successResponse handler configurations on metadata actions. Upon successful form submission, it dynamically hooks-into the onSubmit promise resolution to present the read-only payload values in a slide-over modal or inline-replacement view before the transient state is discarded. It also includes setting a string field as "copyable" that triggers a "copy" action to render with the field and makes the field read-only.

While the successResponse handler can be configured for any action, a helper is included for Entity Create and Update views: submitSuccessResponse. This passes the configuration function down to the appropriate submit action in the metadata.

Example Usage of submitSuccessResponse
Views.entityViewCreate()
    .submitSuccessResponse(response -> response
        .title("Key Generated Successfully")
        .message("Copy this secure key now. It will not be shown again.")
        .displayMode(SuccessResponse.DisplayMode.REPLACE_CONTENT)
        // Renders the API response's 'secret' property as a click-to-copy string field
        .addField("secret", Fields.string()
            .copyable()
            .label("API Key")));
LocalStorageCache Enhancements
  • Added an error boundary in LocalStorageCache to gracefully handle failures to persist the in memory cache to local storage.

  • Modified the in-memory cache used by LocalStorageCache to act as an LRU map with additional byte-size-based eviction that can be set with LocalStorageCache#maxByteSize.

New Configuration Options

Introduce environment properties to fine-tune the behavior of different LocalStorageCache instances across the application. This enables configuring time-to-live (TTL), maximum byte size limits, and local/session storage enablement dynamically.

The following configuration properties have been introduced (formatted as VITE_ prefixed, uppercase, snake_case dotenv variables) with their respective default values:

  • Authentication Cache:

    • VITE_AUTH_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_AUTH_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_AUTH_CACHE_LOCAL_ENABLE: Default: true

    • VITE_AUTH_CACHE_SESSION_ENABLE: Default: true

  • Authentication State Cache:

    • VITE_AUTH_STATE_CACHE_MAX_BYTE_SIZE: Default: 0, not restricted as it is not persisted to local or session storage

    • VITE_AUTH_STATE_CACHE_TTL: Default: 0, no TTL

  • Authentication Transaction Storage:

    • VITE_AUTH_TRANSACTION_STORAGE_MAX_BYTE_SIZE: Default: 0, not restricted as it is not persisted to local or session storage

    • VITE_AUTH_TRANSACTION_STORAGE_TTL: Default: 0, no TTL

  • Metadata/Component Router Cache:

    • VITE_METADATA_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_METADATA_CACHE_TTL: Default: 1800000, 30 minutes

    • VITE_METADATA_CACHE_LOCAL_ENABLE: Default: true

    • VITE_METADATA_CACHE_SESSION_ENABLE: Default: true

  • Catalog Cache:

    • VITE_CATALOG_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_CATALOG_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_CATALOG_CACHE_LOCAL_ENABLE: Default: true

    • VITE_CATALOG_CACHE_SESSION_ENABLE: Default: true

  • Customer Context Cache:

    • VITE_CUSTOMERCONTEXT_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_CUSTOMERCONTEXT_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_CUSTOMERCONTEXT_CACHE_LOCAL_ENABLE: Default: true

    • VITE_CUSTOMERCONTEXT_CACHE_SESSION_ENABLE: Default: true

  • Sandbox Cache:

    • VITE_SANDBOX_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_SANDBOX_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_SANDBOX_CACHE_LOCAL_ENABLE: Default: true

    • VITE_SANDBOX_CACHE_SESSION_ENABLE: Default: true

  • Search Settings Cache:

    • VITE_SEARCHSETTINGS_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_SEARCHSETTINGS_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_SEARCHSETTINGS_CACHE_LOCAL_ENABLE: Default: true

    • VITE_SEARCHSETTINGS_CACHE_SESSION_ENABLE: Default: true

  • Tenant Cache:

    • VITE_TENANT_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_TENANT_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_TENANT_CACHE_LOCAL_ENABLE: Default: true

    • VITE_TENANT_CACHE_SESSION_ENABLE: Default: true

Miscellaneous
  • Introduced a dedicated new component specifically designed to handle the toggle states of Placeholder Characteristics, registered as PLACEHOLDER_ENUM.

  • Added support to ActionListGridCreateAction to configure the modal max size with the modalSize attribute.

    • Supported values:

      • sm: 32rem (512 pixels)

      • lg: 48rem (768 pixels)

      • xl: 72rem (1152 pixels)

  • Refactored the ToggleSwitch component for improved keyboard accessibility and WAI-ARIA compliance

    • Addressed:

      • Limited Keyboard Shortcuts: Previously, keyboard support was restricted to a simple spacebar toggle which acted as a circular index cycler. This made navigating back and forth through multiple choices laborious and did not meet standard accessibility expectations.

      • Double Screen-Reader Announcements: Because both the underlying input element and the visible label/button were interactive and present in the DOM tree, screen readers frequently exposed redundant or competing focused states.

      • Improper Aria Roles: The selection element lacked programmatic group context and checked-state markers, making color changes the only indicator of active options.

  • Updated EntityView useContextParams to take the React Router match param into account to share the behavior used by EntityLongView to determine which form within the view is active.

  • Added support for using EntityViews as targets of slide-over form actions (as opposed to modal forms) like ActionListGridUpdateViewAction that can target an existing View to render when invoked.

  • Added support for overriding some subcomponents of ListGrids

    • blListGridHeaders for ListGridHeaders

    • blActionListGridQueryFilter for ActionListGridQueryFilter

  • Ensured that empty EntityView form tabs are hidden automatically

Bug Fixes

  • Fixed Admin Forms Initializing with Unsaved Changes

  • Fixed the ApplicationSelector disappearing when filtering by a query with no matching results

  • Fixed Workflow view not showing error page for invalid workflows (e.g., navigating to a URL for a workflow that doesn’t exist).

  • Fixed possibility of QuotaExceededError for CustomerContextCache used by the Customer Context Selector component in the Tenant-level admin.

    • Only cache the IDs and Names of Applications stored as these are the only ones relevant for admin functionality

  • Fixed Customize Form actions not opening modals to add Field or Group Augmentations when clicking on the button icon rather than the button background. Now clicking on either will open the modal.

  • Fixed management of placeholder enum characteristics to handle and send valid API request/response payloads.

    • Created a PlaceholderEnumField component (and corresponding internationalized messages) specifically designed to manage placeholder enum characteristics. This avoids polluting the general-purpose select elements with complex active/inactive toggling logic.

    • Updated the conditional resolver in Field.tsx to automatically route characteristic placeholders to this new field type.

  • Fixed runtime TypeError, metadata?.actions?.find is not a function, that occurs in the EntityLongView component for auditable entities (set in metadata with .auditable("ENTITY_TYPE").

    • Logic now ensures that standard metadata actions collections always maintain a strict Array structure, preventing downstream components and hooks from crashing on native array method calls.

  • Fixed regression in 2.0.2: Added missing CSS styles resulting from removal of Bootstrap dependency.


Unified Admin Release Notes for 2.0.2

Important

Features & Enhancements

  • Introduced a dedicated new component specifically designed to handle the toggle states of Placeholder Characteristics, registered as PLACEHOLDER_ENUM.

LocalStorageCache Enhancements
  • Added an error boundary in LocalStorageCache to gracefully handle failures to persist the in memory cache to local storage.

  • Modified the in-memory cache used by LocalStorageCache to act as an LRU map with additional byte-size-based eviction that can be set with LocalStorageCache#maxByteSize.

New Configuration Options

Introduce environment properties to fine-tune the behavior of different LocalStorageCache instances across the application. This enables configuring time-to-live (TTL), maximum byte size limits, and local/session storage enablement dynamically.

The following configuration properties have been introduced (formatted as VITE_ prefixed, uppercase, snake_case dotenv variables) with their respective default values:

  • Authentication Cache:

    • VITE_AUTH_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_AUTH_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_AUTH_CACHE_LOCAL_ENABLE: Default: true

    • VITE_AUTH_CACHE_SESSION_ENABLE: Default: true

  • Authentication State Cache:

    • VITE_AUTH_STATE_CACHE_MAX_BYTE_SIZE: Default: 0, not restricted as it is not persisted to local or session storage

    • VITE_AUTH_STATE_CACHE_TTL: Default: 0, no TTL

  • Authentication Transaction Storage:

    • VITE_AUTH_TRANSACTION_STORAGE_MAX_BYTE_SIZE: Default: 0, not restricted as it is not persisted to local or session storage

    • VITE_AUTH_TRANSACTION_STORAGE_TTL: Default: 0, no TTL

  • Metadata/Component Router Cache:

    • VITE_METADATA_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_METADATA_CACHE_TTL: Default: 1800000, 30 minutes

    • VITE_METADATA_CACHE_LOCAL_ENABLE: Default: true

    • VITE_METADATA_CACHE_SESSION_ENABLE: Default: true

  • Catalog Cache:

    • VITE_CATALOG_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_CATALOG_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_CATALOG_CACHE_LOCAL_ENABLE: Default: true

    • VITE_CATALOG_CACHE_SESSION_ENABLE: Default: true

  • Customer Context Cache:

    • VITE_CUSTOMERCONTEXT_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_CUSTOMERCONTEXT_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_CUSTOMERCONTEXT_CACHE_LOCAL_ENABLE: Default: true

    • VITE_CUSTOMERCONTEXT_CACHE_SESSION_ENABLE: Default: true

  • Sandbox Cache:

    • VITE_SANDBOX_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_SANDBOX_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_SANDBOX_CACHE_LOCAL_ENABLE: Default: true

    • VITE_SANDBOX_CACHE_SESSION_ENABLE: Default: true

  • Search Settings Cache:

    • VITE_SEARCHSETTINGS_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_SEARCHSETTINGS_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_SEARCHSETTINGS_CACHE_LOCAL_ENABLE: Default: true

    • VITE_SEARCHSETTINGS_CACHE_SESSION_ENABLE: Default: true

  • Tenant Cache:

    • VITE_TENANT_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_TENANT_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_TENANT_CACHE_LOCAL_ENABLE: Default: true

    • VITE_TENANT_CACHE_SESSION_ENABLE: Default: true

Bug Fixes

  • Fixed Admin Forms Initializing with Unsaved Changes

  • Fixed the ApplicationSelector disappearing when filtering by a query with no matching results

  • Fixed Workflow view not showing error page for invalid workflows (e.g., navigating to a URL for a workflow that doesn’t exist).

  • Fixed possibility of QuotaExceededError for CustomerContextCache used by the Customer Context Selector component in the Tenant-level admin.

    • Only cache the IDs and Names of Applications stored as these are the only ones relevant for admin functionality

  • Fixed Customize Form actions not opening modals to add Field or Group Augmentations when clicking on the button icon rather than the button background. Now clicking on either will open the modal.

  • Fixed management of placeholder enum characteristics to handle and send valid API request/response payloads.

    • Created a PlaceholderEnumField component (and corresponding internationalized messages) specifically designed to manage placeholder enum characteristics. This avoids polluting the general-purpose select elements with complex active/inactive toggling logic.

    • Updated the conditional resolver in Field.tsx to automatically route characteristic placeholders to this new field type.

  • Fixed runtime TypeError, metadata?.actions?.find is not a function, that occurs in the EntityLongView component for auditable entities (set in metadata with .auditable("ENTITY_TYPE").

    • Logic now ensures that standard metadata actions collections always maintain a strict Array structure, preventing downstream components and hooks from crashing on native array method calls.

  • Fixed regression in 2.0.2: Added missing CSS styles resulting from removal of Bootstrap dependency.


Unified Admin Release Notes for 1.10.15

Features & Enhancements

Tip
  • Supports Node 22 and 24. We recommend upgrading to Node 24.

    • Upgrading Node is not required to use this update.

LocalStorageCache Enhancements
  • Added an error boundary in LocalStorageCache to gracefully handle failures to persist the in memory cache to local storage.

  • Modified the in-memory cache used by LocalStorageCache to act as an LRU map with additional byte-size-based eviction that can be set with LocalStorageCache#maxByteSize.

New Configuration Options

Introduce environment properties to fine-tune the behavior of different LocalStorageCache instances across the application. This enables configuring time-to-live (TTL), maximum byte size limits, and local/session storage enablement dynamically.

The following configuration properties have been introduced (formatted as VITE_ prefixed, uppercase, snake_case dotenv variables) with their respective default values:

  • Authentication Cache:

    • VITE_AUTH_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_AUTH_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_AUTH_CACHE_LOCAL_ENABLE: Default: true

    • VITE_AUTH_CACHE_SESSION_ENABLE: Default: true

  • Authentication State Cache:

    • VITE_AUTH_STATE_CACHE_MAX_BYTE_SIZE: Default: 0, not restricted as it is not persisted to local or session storage

    • VITE_AUTH_STATE_CACHE_TTL: Default: 0, no TTL

  • Authentication Transaction Storage:

    • VITE_AUTH_TRANSACTION_STORAGE_MAX_BYTE_SIZE: Default: 0, not restricted as it is not persisted to local or session storage

    • VITE_AUTH_TRANSACTION_STORAGE_TTL: Default: 0, no TTL

  • Metadata/Component Router Cache:

    • VITE_METADATA_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_METADATA_CACHE_TTL: Default: 1800000, 30 minutes

    • VITE_METADATA_CACHE_LOCAL_ENABLE: Default: true

    • VITE_METADATA_CACHE_SESSION_ENABLE: Default: true

  • Catalog Cache:

    • VITE_CATALOG_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_CATALOG_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_CATALOG_CACHE_LOCAL_ENABLE: Default: true

    • VITE_CATALOG_CACHE_SESSION_ENABLE: Default: true

  • Customer Context Cache:

    • VITE_CUSTOMERCONTEXT_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_CUSTOMERCONTEXT_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_CUSTOMERCONTEXT_CACHE_LOCAL_ENABLE: Default: true

    • VITE_CUSTOMERCONTEXT_CACHE_SESSION_ENABLE: Default: true

  • Sandbox Cache:

    • VITE_SANDBOX_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_SANDBOX_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_SANDBOX_CACHE_LOCAL_ENABLE: Default: true

    • VITE_SANDBOX_CACHE_SESSION_ENABLE: Default: true

  • Search Settings Cache:

    • VITE_SEARCHSETTINGS_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_SEARCHSETTINGS_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_SEARCHSETTINGS_CACHE_LOCAL_ENABLE: Default: true

    • VITE_SEARCHSETTINGS_CACHE_SESSION_ENABLE: Default: true

  • Tenant Cache:

    • VITE_TENANT_CACHE_MAX_BYTE_SIZE: Default: 1048576, 1MB

    • VITE_TENANT_CACHE_TTL: Default: 600000, 10 minutes

    • VITE_TENANT_CACHE_LOCAL_ENABLE: Default: true

    • VITE_TENANT_CACHE_SESSION_ENABLE: Default: true

Bug Fixes

  • Fixed Admin Forms Initializing with Unsaved Changes

  • Fixed the ApplicationSelector disappearing when filtering by a query with no matching results

  • Fixed Workflow view not showing error page for invalid workflows (e.g., navigating to a URL for a workflow that doesn’t exist).

  • Fixed possibility of QuotaExceededError for CustomerContextCache used by the Customer Context Selector component in the Tenant-level admin.

    • Only cache the IDs and Names of Applications stored as these are the only ones relevant for admin functionality


Auth JS SDK Release Notes for 1.6.8

Important

Compatibility Warning: If your frontend application is updated to use this version of the SDK but your backend AuthenticationServices is on an older version that does not support public clients calling /oauth2/revoke, browser console errors will appear during logout or session clearing. To prevent these console errors, you should explicitly set enableTokenRevocation: false when instantiating the AuthClient.

Tip

This release is otherwise compatible with Release Trains starting in the 1.8.x line.

Enhancements & Notable Features

Frontend Token Revocation

The frontend Auth Web SDK (@broadleaf/auth-web) now supports automatic token revocation during logout or session clearing.

  • Automatic Revocation: Before the token cache is cleared, the SDK will automatically iterate over the cached tokens, detect if a refresh token is present, and make a request to the /oauth2/revoke endpoint in AuthenticationServices to revoke it.

  • Compatibility Gating Property: To maintain backward compatibility with older versions of AuthenticationServices that do not support public clients calling the token revocation endpoint, this feature can be explicitly disabled.

  • Toggle Option: A new boolean option enableTokenRevocation has been added to AuthClientOptions which defaults to true. If your frontend application is updated to use the new SDK but your AuthenticationServices backend is on an older version that does not support public clients calling /oauth2/revoke, you should set enableTokenRevocation: false when instantiating the AuthClient.

Token Cache API Updates

To support the lookup and revocation of refresh tokens in the cache, the TokenCache interface now exposes a getEntries method:

  • Added getEntries?(): TokenCacheEntry[] to the TokenCache interface.

  • Implemented getEntries(): TokenCacheEntry[] in both InMemoryTokenCache and WebStorageTokenCache implementations.

Bug Fixes

  • Fixed race-condition when using iframe for silent-callback authorization where some token responses were handled out of order


Commerce SDK Release Notes for 1.7.5

Tip

This release is compatible with Release Trains starting in the 2.1.x line.

New Features & Notable Changes

Checkout Payment Expectations Support
  • Support has been introduced to query both paymentRequired and savedPaymentMethodRequired indicators, along with gathering details about available payment method options, in a single aggregate backend request (under the /checkout/payment-expectations endpoint). This simplifies checkout step transitions and payment status evaluation in storefront integrations.


Commerce Quote Microfrontend Release Notes for 1.1.5

Tip

This release is compatible with Release Trains starting in the 2.1.x line.

Important

Minimum React version upgraded to React 18. Minimum Node version upgraded to Node 18.

Features & Enhancements

Tip
Security and maintenance release. Includes all changes for 1.1.4.

Commerce Shared React Microfrontend Release Notes for 1.0.5

Tip

This release is compatible with Release Trains starting in the 2.2.x line.

Important

Minimum React version upgraded to React 18. Minimum Node version upgraded to Node 18.

Features & Enhancements

Tip
Security and maintenance release. Includes all changes for 1.0.4.

Commerce Subscription React Microfrontend Release Notes for 1.0.5

Tip

This release is compatible with Release Trains starting in the 2.2.x line.

Important

Minimum React version upgraded to React 18. Minimum Node version upgraded to Node 18.

Features & Enhancements

Tip
Security and maintenance release. Includes all changes for 1.0.4.

Payment JS SDK Release Notes for 1.4.3

Tip

This release is compatible with Release Trains starting in the 2.1.x line.

Bug Fixes

  • Fixed useListSavedPaymentMethods infinitely sending requests if the "paymentTypes" parameter is provided.


Payment JS SDK Release Notes for 1.3.8

Caution
This is the final planned release of the 1.3.x line.
Tip

This release is compatible with Release Trains starting in the 2.0.x line.

Features & Enhancements

Tip
Security and maintenance release. Includes all changes for 1.3.7.
  • Verified Node 22 and 24 support

  • Verified React 19 support

  • Modified all usages of Customer Access Tokens to pass in limited scopes when fetching the access tokens.

Bug Fixes

  • Fixed useListSavedPaymentMethods infinitely sending requests if the "paymentTypes" parameter is provided.


Commerce Next.js Starter Release Notes for 2.1.0

Note

Docker URL: repository.broadleafcommerce.com:5001/broadleaf/commerce-nextjs-starter:2.1.0

Features & Enhancements

Important
Dropped Node 20 support

Bug Fixes

  • Fixed an issue in which the anonymous endpoint was used to read historical carts for an authorized customer, causing an error.

  • Updated the configuration property names for the CSP to fix content loading.

  • Fixed loading issues with Stripe scripts

  • Fixed context issues when using @broadleaf/commerce-quote-react

  • Ignore 404 errors when the customer’s cart hasn’t been created yet

  • Improved the guest cart transfer page loading transition

  • Fixed cart state being lost when rejecting a quote request

  • Fixed resolution of findDOMNode and 409 cart version conflict errors during checkout

  • Fixed default locale not having a default value and being applied inconsistently in the LocaleContext


Commerce Next.js Starter Release Notes for 2.0.4

Note

Docker URL: repository.broadleafcommerce.com:5001/broadleaf/commerce-nextjs-starter:2.0.4

Bug Fixes

  • Fixed an issue in which the anonymous endpoint was used to read historical carts for an authorized customer, causing an error.

  • Updated the configuration property names for the CSP to fix content loading.

  • Fixed loading issues with Stripe scripts

  • Fixed context issues when using @broadleaf/commerce-quote-react

  • Ignore 404 errors when the customer’s cart hasn’t been created yet

  • Improved the guest cart transfer page loading transition

  • Fixed cart state being lost when rejecting a quote request

  • Fixed resolution of findDOMNode and 409 cart version conflict errors during checkout

  • Fixed default locale not having a default value and being applied inconsistently in the LocaleContext


Commerce Next.js Starter Release Notes for 1.6.11

Caution

This is the final planned release for the 1.6.x line of starters.

Note

Docker URL: repository.broadleafcommerce.com:5001/broadleaf/commerce-nextjs-starter:1.6.11

Tip
Security and maintenance release. Includes all changes for 1.6.10.

Telco Next.js Starter Release Notes for 1.1.4

Note

Docker URL: repository.broadleafcommerce.com:5001/broadleaf/telco-nextjs-starter:1.1.4

Features & Enhancements

Tip
Security and maintenance release. Includes all changes for 1.1.3.
  • Upgraded to Next 16 and React 19

  • Dropped support for Node 18

  • Verified support for Node 22 and 24

  • Pass product when fetching additional pricing targets

  • Made a PDP specific to products with recurring pricing

    • Handles a new display template name, BLC_SUBSCRIPTION, meant to handle demo subscription products (Office 365 and VPNs)

    • The DefaultRecurringPricingPdp is the exact same copy of DefaultPdp except that DefaultPdp now does NOT use the AdditionalPricingOptions while DefaultRecurringPricingPdp does

      • This is to prevent /price-targets requests from being called unnecessarily on the DefaultPdp

    • Products using the PAY_AS_YOU_GO_PHONE template will use the DefaultPdp as they do not have recurring pricing.

  • Added Fee total to Cart Summary and list fees underneath

  • Added generic recurring pricing template and logic to reprice a cart before submitting checkout for virtual or non-shipping fulfillment groups

    • Added condition for GENERIC_RECURRING_PRICING display template

    • Reprice cart right before checkout for nonShippingFulfillment

      • Since they need the BillingAddress to calculate taxes and everything

    • Now reprices the cart right before checkout for fulfillments that have DefaultFulfillmentType of VIRTUAL or NONE. This is done so that taxes and other pricing mechanisms can be run after the BillingAddress has been populated.taxes and everything === Payment Offers Support

  • Add a useAddAttributeToCart hook to facilitate requests to cartClient#addAttributeToCart.

  • Add a useRemoveAttributeFromCart hook to facilitate requests to cartClient#removeAttributeFromCart.

  • The Passthrough Payment Form now uses the useAddAttributeToCart hook to update the PAYMENTS_LIST when a new payment is submitted or removed.

    • The AddAttributeRequest contains invalidatePricing: true, so that the cart will be repriced once the attribute has been updated.

    • The PAYMENTS_LIST attribute is used by the backend to apply offers based on the type of payment. For more details visit the Cart Operation Service release notes.

Bug Fixes

  • Fixed issues with telco product initial pricing and products with recurring prices added to cart

    • Use frequency when adding to cart, fix term messaging to allow 1-year terms

    • Update to pass frequency when adding to cart with additional pricing options

    • Add logic to reset Product PriceInfo to basePrice before fetching additional pricing options

      • The product at this point is already priced, but we don’t want the already-determined bestPrice to be used as basePrice when pricing these additional targets

    • Make sure to pass frequency for dependent items

  • Fixed an issue in which the anonymous endpoint was used to read historical carts for an authorized customer, causing an error.

  • Improved the guest cart transfer page loading transition

  • Fixed default locale not having a default value and being applied inconsistently in the LocaleContext


Telco Next.js Starter Release Notes for 1.0.6

Caution
This is the final planned release in the 1.0.x line of the Telco starter
Note

Docker URL: repository.broadleafcommerce.com:5001/broadleaf/telco-nextjs-starter:1.0.6

Features & Enhancements

Tip
Security and maintenance release. Includes all changes for 1.0.5.
  • Upgraded to Next 16 and React 19

  • Dropped support for Node 18

  • Verified support for Node 22 and 24

  • Pass product when fetching additional pricing targets

  • Made a PDP specific to products with recurring pricing

    • Handles a new display template name, BLC_SUBSCRIPTION, meant to handle demo subscription products (Office 365 and VPNs)

    • The DefaultRecurringPricingPdp is the exact same copy of DefaultPdp except that DefaultPdp now does NOT use the AdditionalPricingOptions while DefaultRecurringPricingPdp does

      • This is to prevent /price-targets requests from being called unnecessarily on the DefaultPdp

    • Products using the PAY_AS_YOU_GO_PHONE template will use the DefaultPdp as they do not have recurring pricing.

  • Added Fee total to Cart Summary and list fees underneath

  • Added generic recurring pricing template and logic to reprice a cart before submitting checkout for virtual or non-shipping fulfillment groups

    • Added condition for GENERIC_RECURRING_PRICING display template

    • Reprice cart right before checkout for nonShippingFulfillment

      • Since they need the BillingAddress to calculate taxes and everything

    • Now reprices the cart right before checkout for fulfillments that have DefaultFulfillmentType of VIRTUAL or NONE. This is done so that taxes and other pricing mechanisms can be run after the BillingAddress has been populated.taxes and everything === Payment Offers Support

  • Add a useAddAttributeToCart hook to facilitate requests to cartClient#addAttributeToCart.

  • Add a useRemoveAttributeFromCart hook to facilitate requests to cartClient#removeAttributeFromCart.

  • The Passthrough Payment Form now uses the useAddAttributeToCart hook to update the PAYMENTS_LIST when a new payment is submitted or removed.

    • The AddAttributeRequest contains invalidatePricing: true, so that the cart will be repriced once the attribute has been updated.

    • The PAYMENTS_LIST attribute is used by the backend to apply offers based on the type of payment. For more details visit the Cart Operation Service release notes.

Bug Fixes

  • Fixed issues with telco product initial pricing and products with recurring prices added to cart

    • Use frequency when adding to cart, fix term messaging to allow 1-year terms

    • Update to pass frequency when adding to cart with additional pricing options

    • Add logic to reset Product PriceInfo to basePrice before fetching additional pricing options

      • The product at this point is already priced, but we don’t want the already-determined bestPrice to be used as basePrice when pricing these additional targets

    • Make sure to pass frequency for dependent items

Services

Auth Release Notes for 2.3.1-GA

Tip
The 2.x versions are Spring Boot 3 compatible.

New Features & Notable Changes

Improved Bean Overridability

Added @ConditionalOnMissingBean annotations to several auto-configured beans in AuthI18nAutoConfiguration and AuthServiceTemplateAutoConfiguration to support easier customization and overriding in client implementations:

  • Internationalization & Mapping:

    • authMessageSourcePostProcessor

    • authTranslationPostMapperMember

  • Thymeleaf & OAuth2 Template Engine / Resolvers:

    • oAuth2ClientIdTemplateEngine

    • viewResolverPostProcessor (updated to return the concrete ViewResolverPostProcessor type, which has been made public)

    • oAuth2DefaultTemplateResolver

    • broadleafTemplateResolver

    • broadleafOAuth2DefaultTemplateResolver

Public Client Access of Token Revocation Endpoint

The OAuth2 Token Revocation Endpoint is now accessible to public clients. Please review OAuth2 Token Revocation endpoint documentation for more details.

  • Introduced a new PublicClientTokenRevocationAuthenticationConverter that specifically targets the token revocation endpoint and establishes a PublicClientTokenRevocationAuthenticationToken authentication

  • Updated PublicRefreshPublicClientAuthenticationProvider to handle PublicClientTokenRevocationAuthenticationToken

Impersonation Security Scope

Add the IMPERSONATE security scope and its root permission-scope mapping to the required starter data. This is the Authentication Services half of the admin change that hides the View Quote Details action from users who lack impersonation permissions — without the scope in place, the action is hidden from every user because there is nothing for the permission to map to.

The changesets are guarded by preconditions and will not insert rows that already exist, so a deployment that added the scope by hand needs no further action.

Bug Fixes

  • Fixed incorrect default Caffeine and EHCache heap/offheap size properties — they were previously specified in raw megabyte values (e.g. 500) under keys expecting a unit suffix, so the configured sizes were not actually being applied. The defaults now use unit-suffixed values (e.g. 500MB).

Miscellaneous

  • Failing to verify or parse a login token now throws a custom exception.

    • The custom exception is an UnverifiedTokenException. This allows specific handling based on the context in which the token is being verified.


Bulk Operations Release Notes for 1.0.4-GA

Important Updates

Spring Boot Upgrade
  • As of Broadleaf Release Train 2.3.0-GA, all microservices have been upgraded to support Spring Boot 3.3 & 3.5.

Bug Fixes

Fixed Infinite Paging Loop in Bulk Operations
  • Fixed an issue within the paging implementation of the CategoryModifiedEventListener, SingleProductIndexedEventListener, and InitializeBulkOperationItemsListener.

    • Previously, the Pageable request was stuck at page 0 during bulk operations parsing product memberships and auto-included categories, resulting in an infinite loop when the number of items exceeded the initial batch size. The pageable objects are now correctly advanced (e.g., searchPageable = searchPageable.next()) to appropriately traverse search results and auto-included categories. New comprehensive test suites were also added to validate correct paging behaviors.


Cart Services Release Notes for 2.3.1-GA

Tip
The 2.x versions are Spring Boot 3 compatible.

Requirements

  • JDK 17 is required for Broadleaf release trains 2.0.0-GA, and beyond.

New Features & Notable Changes

Historical Cart Lookup
  • Introduced new version of CartEndpoint#readHistoricalCartForAnonymousCustomer that returns only anonymous carts.

    • GET /api/cart/carts?emailAddress=<value>&orderNumber=<value>&historical=true

    • Deprecated older version that returned mixed carts

    • Include Accept-Version=2 as a header to use the new endpoint if calling in custom code, or set broadleaf.cartoperation.cartprovider.readHistoricalCartForAnonymousCustomerEndpointVersion=2 in Cart Operations Service to use the new endpoint.

  • Introduced new endpoint to read historical carts by Order Number only for both anonymous and registered users.

    • GET /api/cart/carts?orderNumber=<value>

    • Additional ownership filtering should be performed by the caller and is automatically performed in Cart Operations Service in the following versions:

      • 2.1.6 (RT 2.1.7)

      • 2.2.3 (RT 2.2.3)

      • 2.3.1 (RT 2.3.1)

Bug Fixes

Hide View Quote Details Admin Action if Missing Impersonation Permission

Previously, the View Quote Details action on the Quote list grid in the Admin would appear even if the user did not have impersonation permissions despite those being required for the action to succeed. To address this, the IMPERSONATE scope has been added to the View Quote Details action to ensure it is hidden for users that lack it so they avoid encountering the error and having to spend time debugging.

View Quote Details Reference

This requires also including the following changes in the Auth Service schema to add a missing security scope and permission-scope mapping for impersonation:

-- Add scope
INSERT INTO blc_security_scope (id, name, open) VALUES ('IMPERSONATE', 'IMPERSONATE', 'N');
-- Map to the root permission
INSERT INTO blc_permission_scope (id, permission, is_permission_root, scope_id) VALUES ('IMPERSONATE', 'IMPERSONATE', 'Y', 'IMPERSONATE');
Tip

If for any reason, you need to disable this change, set the following

broadleaf:
  cart:
    metadata:
      impersonation-permission-required-to-view-quote-details: false

Cart Operation Release Notes for 2.3.1-GA

Tip
The 2.x versions are Spring Boot 3 compatible.

Important Updates

Spring Boot Upgrade
  • As of Broadleaf Release Train 2.3.0-GA, all microservices have been upgraded to support Spring Boot 3.3 & 3.5.

Requirements

  • JDK 17 is required for Broadleaf release trains 2.0.0-GA, and beyond.

New Features & Notable Changes

Allow Disabling Anonymous Historical Cart Endpoints

Added configuration properties to allow users to disable the anonymous history endpoints in Cart Ops altogether if not in use. Cart Ops was chosen for this as it will short-circuit the requests at the earliest point to improve performance. This is granular in case some endpoints are in use but not all. Additionally, users may have added their own custom endpoints in Cart Ops that use the same endpoints in Cart, making Cart Ops the most straightforward placement for this configuration.

To disable each:

broadleaf:
  cartoperation:
    endpoint:
      cart-history:
        read-anonymous-customer-cart-enabled: false
        read-cart-by-order-number-for-anonymous-customer-enabled: false
        read-cart-by-order-number-for-anonymous-customer-hydrate-payments-enabled: false
Miscellaneous
  • Added CartProvider#retrieveHistoricalCartByOrderNumber for looking up both registered and anonymous historical carts by Order Number only. Additional ownership checks are handled in CartHistoryService to allow a more streamlined experience.

  • Added property to control whether CartProvider#retrieveHistoricalCartForAnonymousCustomer can retrieve only anonymous user carts or both registered and anonymous historical carts by email address and order number.

    • Previously the method returned both despite the name implying only anonymous carts being returned.

    • Recommended: Restrict it to only retrieve anonymous carts by setting the following property: broadleaf.cartoperation.cartprovider.readHistoricalCartForAnonymousCustomerEndpointVersion=2

  • All cart retrieval logic in CartHistoryEndpoint methods has been moved to methods in CartHistoryService to better consolidate business logic.

    • CartHistoryService centralizes handling of user access checks for retrieved all historical carts.

    • This enhances the capabilities of the endpoints so that Account Carts can be retrieved by either the owner or an Account Admin/Approver to streamline the behavior on the order confirmation page.

Payment Lock Tokens When Removing Invalid Offer Codes

Add CartOperationService#removeOfferAndCampaignCodesFromCart(Cart, List, boolean, Map, ContextInfo), which accepts the payment lock tokens held by the calling flow. The checkout offer validation activity now passes its lock tokens through when it strips invalid offer codes, so the reprice that follows can act on payments the flow already holds locks for instead of failing to acquire them.

Bug Fixes

  • Fix an issue where transferring an anonymous cart to a customer returned an error if the cart had already been transferred. The cart is now returned unchanged, so a repeated transfer request is harmless.

  • Fix an issue where the stale cart pricing checkout validation ignored its own configuration. broadleaf.cartoperation.checkout.activity.validation.cart-stale-pricing.should-reject-lower-price and broadleaf.cartoperation.checkout.activity.validation.cart-stale-pricing.use-real-time-cart-pricing could not be bound, so both behaved as if left at their defaults regardless of what was configured.

    • The fluent accessors shouldRejectLowerPrice() and useRealTimeCartPricing() are deprecated for removal. Use isShouldRejectLowerPrice()/setShouldRejectLowerPrice(boolean) and isUseRealTimeCartPricing()/setUseRealTimeCartPricing(boolean) instead.

  • Fix a NullPointerException raised while pricing a cart when a merchandising product resolved to a price with no recurring price.

  • Fixed an issue where an invalid offer would cause validation to fail during checkout

  • Fixed properties not binding in CartStalePricingValidationActivityProperties because the field were not utilizing any configured property values due to a @Fluent annotation preventing correct binding.

  • Fixed an NPE caused by Merchandising Products not having a recurring price field.


Catalog Services Release Notes for 2.3.1-GA

Tip
The 2.x versions are Spring Boot 3 compatible.

Requirements

  • JDK 17 is required for Broadleaf release trains 2.0.0-GA, and beyond.

Bug Fixes

  • Fixed various bugs with placeholder characteristics

    • Fixed a bug where CharacteristicValidator was not allowing empty values for placeholder characteristics

    • Removed the synchronizePlaceholderCharacteristics method and a variety of related specialized behavior for placeholder characteristics from DefaultProductHydrationService.

    • Fix property paths for ProductCharacteristic validations to ensure we are always targeting valid paths instead of relying on auto-grow-nested path behavior from Spring Originally this behavior was intended to work around limitations of the admin frontend application, but had the consequence of corrupting certain fields. The admin frontend has been updated to properly interpret and send placeholder characteristic values, so the incorrect backend workarounds have been removed.

  • Fixed a bug where Characteristic.id was using @JsonView(ResponseView.class), preventing the Characteristic ID from coming through on Product update calls even in a nested context.

    • As part of this, the characteristic update endpoint now sets the id on the submitted body from the path variable, so the path is always authoritative for which characteristic is updated.

  • Fixed a bug where policy validation would reject product update attempts if the API caller only had the UPDATE_PRODUCT permission, but a new product characteristic was being created as part of that request

  • Fixed a bug where inactive and date-expired catalog records were skipped by processes that do not run in a storefront request. The active-flag and active-date filters are now disabled when handling catalog entity deletion events, when running product bulk updates, and when reading variants for variant-based product type validation, so each of those processes sees every record it is meant to act on. Previously an inactive product could survive a deletion event and an inactive variant could be missed by product type validation.

  • Fixed the property paths reported in product validation errors for product characteristics. Errors were previously reported against nested paths such as characteristics['<key>'].characteristic and characteristics['<key>'].value[0], which relied on Spring’s auto-grow-nested-path behavior and could fail to resolve.

    • Reference errors and cardinality errors are now reported against characteristics['<key>'], and cardinality errors on business-type characteristics against characteristics.

    • Clients that map validation messages to form fields using the field value in the error response need to be updated to the new paths.


Content Release Notes for 2.0.10-GA

Important Updates

Spring Boot Upgrade
  • As of Broadleaf Release Train 2.3.0-GA, all microservices have been upgraded to support Spring Boot 3.3 & 3.5.

Bug Fixes

  • Add property spring.cloud.stream.bindings.cloneContentItemOutput.destination: cloneContentItem to correctly bind clone content item notification.

  • Fixed the issue where the active check is not skipped when bulk cloning content items


Common Libraries

Common Libraries

Data Tracking Release Notes

Data Tracking Release Notes for 2.0.8-GA

Notable Changes

  • This release contains security fixes. For detailed information regarding this security item, please refer to the Broadleaf Security Advisory. You will need your login credentials originally provided for accessing the Broadleaf nexus.

Dynamic Notification Suppression Integration
  • Introduced support for initializing tracking/persistence notification states based on their suppressed state within the active SuppressNotificationContext

  • Updated trackable domain mapper member supports (DefaultTrackableDomainMapperMemberSupport and JpaTrackableDomainMapperMemberSupport) to check if the specific notification type is suppressed before mapping trackable entities

  • When executing inside a suppressed context, the stopped field of the corresponding trackable domain NotificationState (userState for ChangeSummaryProducer#TYPE and persistenceState for PersistenceProducer#TYPE) is initialized to true dynamically

  • Updated NotificationStateInitializingDomainMapperMember to dynamically resolve and set the stopped property based on the suppressed context check of SuppressNotificationContext.isSuppressed(state.getName())

Bug Fixes

  • Fix an issue where ContextInfo#filterByActiveFlag was lost when a ContextInfo was copied, and where restoring the flag after an active-flag-filtered operation wrote to filterByActiveDates instead. Queries run after such an operation could filter on the wrong flag.

  • Updated DefaultProjectionFactory to assign an explicit parent package to AutoProjection classes

    • Some versions of Apache Fury (now Fory), used for serialization/deserialization in Caffeine and EHCache caching implementations, are susceptible to an internal race condition when dealing with unnamed-package classes. This can result in corrupted output, and cause failures (such as NullPointerException) during cacheable operations. By ensuring AutoProjection classes have an explicit package, Broadleaf reduces exposure to this edge case.

Metadata Release Notes

2.0.9-GA

Spring Upgrade
  • As of Broadleaf Release Train 2.3.0-GA, support for Spring Boot 3.3 & 3.5 for all common libraries has been added.

Features/Notable Changes
Introduced support for an admin user to see and copy generated API key values
Important
Requires AdminWeb 2.1.0.

Introduces support for a "One-Time Success Response" feature, providing a highly integrated framework for safely displaying sensitive, transient API response payloads (such as generated API keys) natively within the Admin UI. This feature looks for successResponse handler configurations on metadata actions. Upon successful form submission, it dynamically hooks-into the onSubmit promise resolution to present the read-only payload values in a slide-over modal or inline-replacement view before the transient state is discarded. It also includes setting a string field as "copyable" that triggers a "copy" action to render with the field and makes the field read-only.

While the successResponse handler can be configured for any action, a helper is included for Entity Create and Update views: submitSuccessResponse. This passes the configuration function down to the appropriate submit action in the metadata.

Example Usage of submitSuccessResponse
Views.entityViewCreate()
    .submitSuccessResponse(response -> response
        .title("Key Generated Successfully")
        .message("Copy this secure key now. It will not be shown again.")
        .displayMode(SuccessResponse.DisplayMode.REPLACE_CONTENT)
        // Renders the API response's 'secret' property as a click-to-copy string field
        .addField("secret", Fields.string()
            .copyable()
            .label("API Key")));

Messaging Common Release Notes

2.0.5

Spring Boot Upgrade
  • As of Broadleaf Release Train 2.3.0-GA, support for Spring Boot 3.3 & 3.5 for all common libraries has been added.

Notable Changes
  • Introduced RoundRobinRetryScheduler to manage retry handlers more efficiently.

    • Addresses resource exhaustion by using a fixed-size thread pool instead of creating a dedicated thread per handler.

    • In the past, thread counts for retry scheduling could get up to ~2600. This should now be reduced to a constant of 30 (the default).

    • Ensures fairness via a round-robin scheduling algorithm, preventing "noisy" handlers from monopolizing resources.

    • Implements a non-blocking design where the scheduler skips full pools and retries on the next cycle.

  • Added "Burst Mode" support for high-load scenarios.

    • Allows handlers to request immediate execution on a dedicated "Burst Pool" when a full page of records is processed.

    • Helps drain large backlogs quickly without starving other handlers in the main fair pool.

  • Added new configuration properties for tuning the retry scheduler and burst mode behavior.