IL.UmbracoSearch.Analytics
17.8.4.11
dotnet add package IL.UmbracoSearch.Analytics --version 17.8.4.11
NuGet\Install-Package IL.UmbracoSearch.Analytics -Version 17.8.4.11
<PackageReference Include="IL.UmbracoSearch.Analytics" Version="17.8.4.11" />
<PackageVersion Include="IL.UmbracoSearch.Analytics" Version="17.8.4.11" />
<PackageReference Include="IL.UmbracoSearch.Analytics" />
paket add IL.UmbracoSearch.Analytics --version 17.8.4.11
#r "nuget: IL.UmbracoSearch.Analytics, 17.8.4.11"
#:package IL.UmbracoSearch.Analytics@17.8.4.11
#addin nuget:?package=IL.UmbracoSearch.Analytics&version=17.8.4.11
#tool nuget:?package=IL.UmbracoSearch.Analytics&version=17.8.4.11
IL.UmbracoSearch.Analytics
Optional Search Insights for IL.UmbracoSearch. This package targets Umbraco 17 / .NET 10 only.
Starting with IL.UmbracoSearch 17.8.0.1, this is part of the supported runtime baseline: Umbraco 13-16 and .NET 8-9 are not supported.
Enable Analytics
Enable SearchOptions.Analytics with exactly one engine:
builder.Services.AddUmbracoSearch(SearchOptions.Lucene | SearchOptions.Analytics);
// or
builder.Services.AddUmbracoSearch(SearchOptions.Azure | SearchOptions.Analytics);
Analytics decorates ISearchService; it does not change query/result semantics.
Analytics is requested per search by supplying SearchParameters.Analytics (or
SearchRequest.Analytics for the built-in endpoint). When requested, capture is
non-blocking and stores only GUID UmbracoNodeKey values for impressions/clicks.
Captured searches return SearchResults.Analytics, containing a tracking reference
and session token. Store the session token in the caller and pass it as
AnalyticsRequest.AnalyticsSessionToken on a later search to group executions as
one Search session. AnalyticsResponse.TrackingReference remains distinct for
every execution and must be used for click tracking. Set the optional
AnalyticsRequest.SiteKey to partition events by website; the backoffice exposes
that value through the website filter. The response object is null
when analytics was not requested or is disabled globally. Suggestion responses
return a SuggestionResult<SuggestionResultItem<T>> envelope containing
Analytics, TotalItemCount, and the returned suggestion items.
Session insights
The Search section includes an anonymous Sessions view. It reports activity
only within the selected reporting window: searches per session, refined-session
rate, paginated journeys, and frequent query-to-query refinements. It never
returns or displays AnalyticsSessionToken values.
Journey rows are paginated and only include recent query/click activity. Refinement
analysis is limited to the most recent 10,000 matching raw events and indicates
when a wide reporting window is sampled. These insights depend on raw retained
events and are not available beyond RawEventRetention.
Per-call capture opt-out is available through SearchParameters.Analytics.
Set CaptureAnalytics = false inside the object on searches that must not be
captured (for example, server-generated/internal searches).
Consumer setup checklist
- Enable Analytics with exactly one engine.
- Configure analytics storage.
- Map click tracking endpoint (
UseSearchAnalyticsClicks). - Map backoffice management endpoints (
MapSearchAnalyticsManagement). - Apply a backoffice authorization policy for Search Insights access.
- Install and use the npm click helper package in your front end.
Configuration
The package binds options from SearchSettings:Analytics.
For backward compatibility, UmbracoSearch:Analytics is also accepted when
SearchSettings:Analytics is not present.
{
"ConnectionStrings": {
"UmbracoSearchAnalytics": "Server=...;Database=SearchAnalytics;..."
},
"SearchSettings": {
"Analytics": {
"Enabled": true,
"EnableBackgroundProcessing": true,
"CaptureQueryText": true,
"QueueCapacity": 2000,
"FlushInterval": "00:00:01",
"TrackingReferenceLifetime": "01:00:00",
"RawEventRetention": "90.00:00:00",
"SynonymFieldNames": ["searchTitle"]
}
}
}
Supported SearchSettings:Analytics options:
Enabled— set tofalseon preview/test servers to disable all capture on that nodeEnableBackgroundProcessing— set tofalseon delivery servers in a multi-server setup so only the designated master backend runs periodic tasks (retention purge); capture and ingestion are unaffectedCaptureQueryTextQueueCapacityFlushIntervalTrackingReferenceLifetimeRawEventRetentionConnectionString(explicit override)UseInMemoryStorage(tests/local experiments only)SynonymFieldNames
CaptureAnalytics is not an appsetting; it is a per-request flag on
AnalyticsRequest, nested in SearchParameters.Analytics (or the default HTTP
SearchRequest.Analytics) for selective capture. The analytics request object is
nullable and omitted by default.
Storage defaults:
- SQL Server is default.
- Connection resolution order:
SearchSettings:Analytics:ConnectionStringConnectionStrings:UmbracoSearchAnalyticsConnectionStrings:umbracoDbDSN
- If none are set, startup fails unless
UseInMemoryStorage=true.
Database migrations
Generate analytics migrations with EF tooling (dotnet ef); do not hand-author
migration files. Analytics uses its own migrations history table and does not
modify Umbraco tables.
Click endpoint and npm helper
Map the consumer-owned click endpoint:
app.UseSearchAnalyticsClicks();
Default path: /api/search/analytics/click
Install helper package:
npm i @ihorleleka/umbraco-search-analytics
Use the helper:
import { trackSearchResultClick } from '@ihorleleka/umbraco-search-analytics';
await trackSearchResultClick(
{ endpoint: '/api/search/analytics/click', consent: () => hasAnalyticsConsent() },
{
trackingReference: search.analytics.trackingReference,
nodeKey: item.nodeKey,
position: index + 1,
idempotencyKey: crypto.randomUUID()
});
Click payload:
trackingReference: from the search responsenodeKey: Umbraco content GUID (not numeric node ID)position: 1-based position shown to the useridempotencyKey: unique per click attempt
Endpoint outcomes:
202 Acceptedfor accepted click204 No Contentfor duplicate click400 Bad Requestfor invalid/expired/non-displayed click
The host owns endpoint authentication, transport security, rate limiting, and consent policy.
Backoffice management endpoints
Map Search Insights management endpoints:
app.MapSearchAnalyticsManagement(authorizationPolicy: "SearchInsights");
Default base path: /umbraco/api/search-analytics
If no policy is supplied, endpoints still require an authenticated Umbraco
backoffice user via BackOfficeAuthenticationType.
Example policy wiring:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("SearchInsights", policy =>
policy.AddAuthenticationSchemes(Constants.Security.BackOfficeAuthenticationType)
.RequireAuthenticatedUser());
});
SSR and hydration guidance
TrackingReference is generated per executed search call. If the same logical
search is executed in SSR and then re-executed during hydration, analytics will
record two executions.
To avoid duplicate analytics with the current implementation, reuse SSR search
results during hydration instead of issuing a second identical search call, or
set Analytics = new AnalyticsRequest { CaptureAnalytics = false } on non-user-visible/server-generated searches.
You can also suppress analytics for specific replay/internal searches by setting
SearchParameters.Analytics.CaptureAnalytics = false for those calls.
Multi-server deployments
In a load-balanced or multi-server setup, use Enabled and EnableBackgroundProcessing
to control per-node behaviour:
| Node type | Enabled |
EnableBackgroundProcessing |
What runs |
|---|---|---|---|
| Master / backoffice server | true (default) |
true (default) |
Migrations, retention, capture |
| Delivery server | true (default) |
false |
Capture only |
| Preview / test server | false |
(irrelevant) | Nothing |
EnableBackgroundProcessing = false skips all server-side processing on that node:
database migrations and retention purge. Only the master
(backoffice) server should run with it set to true.
Example delivery server appsettings:
{
"SearchSettings": {
"Analytics": {
"EnableBackgroundProcessing": false
}
}
}
Example preview/test server appsettings:
{
"SearchSettings": {
"Analytics": {
"Enabled": false
}
}
}
Safety when the feature is not activated
If IL.UmbracoSearch.Analytics is referenced but SearchOptions.Analytics is
never added during service registration, the package is inert:
- The database migration hosted service exits without running.
- No background workers start (capture queue, retention).
UseSearchAnalyticsClicks()andMapSearchAnalyticsManagement()map no routes and resolve nothing from the DI container.
Azure synonyms
Synonym management is Azure-only. Every publication removes Azure synonym maps
whose names start with Analytics:SynonymMapPrefix (default us-), creates the
single shared ${SynonymMapPrefix}library-managed-all map from the current
enabled mappings, and refreshes managed active/indexing index definitions. It
does not upload or reindex content documents. Set distinct prefixes such as
staging-us- and production-us- when environments share an Azure Search
service.
Local Storybook preview for Search section FE
Use the local Storybook workspace to evolve Search-section UI and fake-data states without publishing a new package release.
Workspace path:
src/UmbracoSearch.Analytics.Backoffice.Client/
Backoffice modules are authored in that workspace's src/ directory. Generate the
NuGet package assets before packing or testing a UI change:
cd src/UmbracoSearch.Analytics.Backoffice.Client
npm run build
The build writes to src/UmbracoSearch.Analytics/wwwroot/App_Plugins/IL.UmbracoSearch.Analytics/.
Run locally:
cd src/UmbracoSearch.Analytics.Backoffice.Client
npm install
npm run storybook
Build preview artifacts:
npm run build-storybook
The preview uses a Storybook-only fake-data provider. Runtime backoffice behavior remains unchanged: production continues to use authenticated Umbraco fetch flow and existing management endpoints.
| 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
- IL.AttributeBasedDI (>= 2.9.3.1)
- IL.UmbracoSearch (>= 17.8.4.11)
- Microsoft.EntityFrameworkCore.SqlServer (>= 10.0.0 && < 11.0.0)
- Umbraco.Cms.Web.Common (>= 17.0.0 && < 18.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 |
|---|---|---|
| 17.8.4.11 | 41 | 9/17/2026 |
| 17.8.4.10 | 41 | 9/17/2026 |
| 17.8.4.9 | 38 | 9/17/2026 |
| 17.8.4.8 | 36 | 9/17/2026 |
| 17.8.4.7 | 44 | 9/17/2026 |
| 17.8.4.6 | 44 | 9/16/2026 |
| 17.8.4.5 | 42 | 9/16/2026 |
| 17.8.4.4 | 58 | 9/16/2026 |
| 17.8.4.3 | 65 | 9/16/2026 |
| 17.8.4.2 | 83 | 9/14/2026 |
| 17.8.4.1 | 80 | 9/13/2026 |
| 17.8.3.3 | 88 | 9/12/2026 |
| 17.8.3.2 | 107 | 9/5/2026 |
| 17.8.3.1 | 115 | 8/30/2026 |
| 17.8.2.5 | 110 | 8/25/2026 |
| 17.8.2.4 | 107 | 8/22/2026 |
| 17.8.2.3 | 113 | 8/21/2026 |
| 17.8.2.2 | 96 | 8/20/2026 |
| 17.8.2.1 | 102 | 8/20/2026 |
| 17.8.1.18 | 91 | 8/20/2026 |