Umbraco.Commerce.Search
18.0.0-beta.1
Prefix Reserved
dotnet add package Umbraco.Commerce.Search --version 18.0.0-beta.1
NuGet\Install-Package Umbraco.Commerce.Search -Version 18.0.0-beta.1
<PackageReference Include="Umbraco.Commerce.Search" Version="18.0.0-beta.1" />
<PackageVersion Include="Umbraco.Commerce.Search" Version="18.0.0-beta.1" />
<PackageReference Include="Umbraco.Commerce.Search" />
paket add Umbraco.Commerce.Search --version 18.0.0-beta.1
#r "nuget: Umbraco.Commerce.Search, 18.0.0-beta.1"
#:package Umbraco.Commerce.Search@18.0.0-beta.1
#addin nuget:?package=Umbraco.Commerce.Search&version=18.0.0-beta.1&prerelease
#tool nuget:?package=Umbraco.Commerce.Search&version=18.0.0-beta.1&prerelease
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:
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 legacyTransformingIndexValues/UmbracoCommerceVariantsEditorExamineValueOptimizerhook. The fields (prefixed so they never collide with the built-in property-value indexer) are:Field Type Source umbracoCommerceStorekeyword store-picker value on store-root nodes umbracoCommerceIsProductkeyword "true"on nodes with askuorvariantspropertyumbracoCommerceSkukeyword the product's own SKU umbracoCommerceVariantSkuskeyword[] SKUs parsed from the Variants Editor value umbracoCommerceCategorieskeyword[] (facetable) category references umbracoCommerceProductSourcekeyword product-source reference umbracoCommerceSearchTexttext SKU + product name, for free-text matching Declares those non-textual fields in
FieldOptionsso the Examine provider indexes them as filterable / facetable. Without this, keyword filters silently return nothing.Replaces the product adapter —
AddUnique<IProductAdapter, CmsSearchProductAdapter>().CmsSearchProductAdaptersubclasses Commerce'sUmbracoProductAdapter, 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).
Replaces the store finder — swaps
UmbracoLuceneStoreFinderforCmsSearchStoreFinderin 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, orPUT /umbraco/search/api/v1/rebuild?indexAlias=Umb_PublishedContentandPUT /umbraco/search/api/v1/rebuild?indexAlias=Umb_Content. NoteindexAliasis 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 aproductSourcerelation 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 honoursproductSourcebecause 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 internalPublishedContentHelper(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 | Versions 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. |
-
net10.0
- Umbraco.Cms.Search.Core (>= 18.0.0)
- Umbraco.Cms.Search.Provider.Examine (>= 18.0.0-beta.1)
- Umbraco.Commerce.Cms (>= 18.0.0 && < 19.0.0)
- Umbraco.Commerce.Cms.Startup (>= 18.0.0 && < 19.0.0)
- Umbraco.Commerce.Core (>= 18.0.0 && < 19.0.0)
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 |