|
Important
|
|
Introduced a dedicated new component specifically designed to handle the toggle states of Placeholder Characteristics, registered as PLACEHOLDER_ENUM.
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.
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
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.
|
Tip
|
|
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.
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
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
|
Tip
|
This release is compatible with Release Trains starting in the 2.1.x line. |
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.
|
Important
|
Compatibility Warning: If your frontend application is updated to use this version of the SDK but your backend |
|
Tip
|
This release is otherwise compatible with Release Trains starting in the 1.8.x line. |
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.
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.
|
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. |
|
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. |
|
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. |
|
Tip
|
This release is compatible with Release Trains starting in the 2.1.x line. |
|
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. |
|
Note
|
Docker URL: |
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
|
Caution
|
This is the final planned release for the 1.6.x line of starters. |
|
Note
|
Docker URL: |
|
Tip
|
Security and maintenance release. Includes all changes for 1.6.10. |
|
Note
|
Docker URL: |
|
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.
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
|
Caution
|
This is the final planned release in the 1.0.x line of the Telco starter |
|
Note
|
Docker URL: |
|
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.
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
|
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
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)
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.
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
|
|
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
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
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.
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.
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())
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.
As of Broadleaf Release Train 2.3.0-GA, support for Spring Boot 3.3 & 3.5 for all common libraries has been added.
|
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.
submitSuccessResponseViews.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")));
As of Broadleaf Release Train 2.3.0-GA, support for Spring Boot 3.3 & 3.5 for all common libraries has been added.
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.