Umbraco.Commerce.Search 18.0.0-beta.1

Prefix Reserved
This is a prerelease version of Umbraco.Commerce.Search.
dotnet add package Umbraco.Commerce.Search --version 18.0.0-beta.1
                    
NuGet\Install-Package Umbraco.Commerce.Search -Version 18.0.0-beta.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Umbraco.Commerce.Search" Version="18.0.0-beta.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Umbraco.Commerce.Search" Version="18.0.0-beta.1" />
                    
Directory.Packages.props
<PackageReference Include="Umbraco.Commerce.Search" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Umbraco.Commerce.Search --version 18.0.0-beta.1
                    
#r "nuget: Umbraco.Commerce.Search, 18.0.0-beta.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Umbraco.Commerce.Search@18.0.0-beta.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Umbraco.Commerce.Search&version=18.0.0-beta.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Umbraco.Commerce.Search&version=18.0.0-beta.1&prerelease
                    
Install as a Cake Tool

Umbraco.Commerce.Search

A drop-in replacement that makes Umbraco Commerce's product and store search run on the Umbraco.Cms.Search abstractions instead of directly against Examine.

Adding the package swaps Commerce's Examine-backed IProductAdapter and store finder for Cms.Search-backed implementations — product lookup, catalogue search, category extraction and store resolution behave the same, but are served through IIndexer / ISearcher (with Examine as one provider behind them). It is the first step in migrating Commerce off its direct Examine coupling.

Compatible with Umbraco CMS 18 and Umbraco Commerce 18. For CMS / Commerce 17, use the support/17.x branch.

Installation

Register the search core, the Examine provider, Umbraco Commerce, and then this package:

builder.CreateUmbracoBuilder()
    .AddBackOffice()
    .AddWebsite()
    .AddDeliveryApi()
    .AddSearchCore()                 // Umbraco.Cms.Search.Core
    .AddExamineSearchProvider()      // Umbraco.Cms.Search.Provider.Examine
    .AddComposers()
    .AddUmbracoCommerce()
    .AddUmbracoCommerceSearch()      // must come after AddUmbracoCommerce so it can override its services
    .Build();

How it works

AddUmbracoCommerceSearch() does four things:

  1. Enriches content documents — registers a CommerceContentIndexer (IContentIndexer) that adds Commerce-specific fields to product and store content nodes as they're indexed into the built-in content indexes (both draft and published). This replaces Commerce's legacy TransformingIndexValues / UmbracoCommerceVariantsEditorExamineValueOptimizer hook. The fields (prefixed so they never collide with the built-in property-value indexer) are:

    Field Type Source
    umbracoCommerceStore keyword store-picker value on store-root nodes
    umbracoCommerceIsProduct keyword "true" on nodes with a sku or variants property
    umbracoCommerceSku keyword the product's own SKU
    umbracoCommerceVariantSkus keyword[] SKUs parsed from the Variants Editor value
    umbracoCommerceCategories keyword[] (facetable) category references
    umbracoCommerceProductSource keyword product-source reference
    umbracoCommerceSearchText text SKU + product name, for free-text matching
  2. Declares those non-textual fields in FieldOptions so the Examine provider indexes them as filterable / facetable. Without this, keyword filters silently return nothing.

  3. Replaces the product adapterAddUnique<IProductAdapter, CmsSearchProductAdapter>(). CmsSearchProductAdapter subclasses Commerce's UmbracoProductAdapter, inheriting all non-search behaviour (product snapshots, variant attributes) unchanged and overriding only the three methods that used Examine:

    • TryGetProductReferenceAsync — SKU → product/variant reference (draft index).
    • SearchProductSummariesAsync — paged catalogue search (published index).
    • GetProductCategoriesAsync — distinct categories via a facet (published index).
  4. Replaces the store finder — swaps UmbracoLuceneStoreFinder for CmsSearchStoreFinder in the store finder collection (the two cache-based finders are left in place). It walks a node's ancestors via the content cache to find the nearest store, with a product-source fallback.

Index choice

Capability Index
Catalogue search, category extraction Umb_PublishedContent
SKU lookup, store resolution Umb_Content (draft / all content)

This mirrors the legacy behaviour: catalogue search returned published products only, while SKU lookup and store resolution worked against all content (the Examine InternalIndex).

Reindexing after install (important)

Umbraco.Cms.Search persists collected fields in a database table (umbracoIndexDocument) and treats it as the source of truth — the Examine indexes are just a projection of it. A rebuild (the backoffice button or PUT /umbraco/search/api/v1/rebuild?indexAlias=<alias>) only resets Examine and re-projects that stored table; it does not re-run the content indexers for content that already has a stored document. So adding this package to a site whose content was already indexed by Cms.Search before the package was installed will not surface the umbracoCommerce* fields — a rebuild alone is not enough, and product search will silently return nothing.

To pick up the new fields on an existing site, force a fresh collection so the indexers run again:

  • Republish the affected content (publishing deletes the stored document, so the next index pass re-collects through all indexers), or
  • Clear umbracoIndexDocument (e.g. DELETE FROM umbracoIndexDocument) and then rebuild both content indexes — the backoffice button, or PUT /umbraco/search/api/v1/rebuild?indexAlias=Umb_PublishedContent and PUT /umbraco/search/api/v1/rebuild?indexAlias=Umb_Content. Note indexAlias is a query parameter, not a request-body field.

On a fresh site where the package is present before content is first indexed, this does not apply — the Commerce fields are collected from the start.

Limitations

  • Product-source scoping — catalogue search and category extraction scope to a store by the store-root ancestor (Umb_PathIds). Products linked into a store from elsewhere via a productSource relation are not yet included in those results (Cms.Search search hits expose only document ids, not field values, so the source reference can't be read back from a result without rehydration). Store resolution still honours productSource because it reads the node directly. Tracked as a follow-up.
  • Product summaries are built from the public IPublishedContent.Value<T>() API rather than Commerce's internal PublishedContentHelper (which isn't accessible from this package), so recursive property resolution differs slightly from the in-product adapter.
  • Unpublished nodes that aren't in the published cache fall through to Commerce's content-service store finder, as before.
  • Unit tests mock ISearcher / IContentBase, so they verify field projection and query composition, not real provider behaviour. End-to-end search is only proven against a running Examine index — use the demo (setup-demo.ps1).

Project layout

src/Umbraco.Commerce.Search/
├── Constants.cs                              // Names of the injected content fields
├── Extensions/UmbracoBuilderExtensions.cs    // AddUmbracoCommerceSearch()
├── Adapters/CmsSearchProductAdapter.cs       // IProductAdapter override (search methods)
├── Finders/CmsSearchStoreFinder.cs           // IUmbracoNodeStoreFinder (replaces the Lucene finder)
└── Services/
    ├── CommerceContentIndexer.cs             // IContentIndexer — enriches content docs
    ├── ICommerceContentSearcher.cs           // Query surface over the content indexes
    └── CommerceContentSearcher.cs            // ISearcher-backed implementation

See docs/superpowers/specs/2026-06-30-commerce-search-examine-replacement-design.md for the full design.

Running the demo

The demo is not committed. To scaffold one locally:

./setup-demo.ps1

This clones the official Umbraco Commerce demo store, installs Umbraco.Cms.Search.Core + Umbraco.Cms.Search.Provider.Examine and a project reference to the local Umbraco.Commerce.Search, patches Program.cs to call .AddSearchCore() / .AddExamineSearchProvider() / .AddUmbracoCommerceSearch(), and generates a git-ignored Umbraco.Commerce.Search.local.slnx. Run ./setup-demo.ps1 -? for parameters.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
18.0.0-beta.1 56 7/16/2026
18.0.0--beta.1.preview.2... 54 7/16/2026
17.0.0-beta.1 55 7/16/2026
17.0.0--beta.1.preview.13... 55 7/16/2026