GXE.Umbraco.AzureAISearch
1.10.1
dotnet add package GXE.Umbraco.AzureAISearch --version 1.10.1
NuGet\Install-Package GXE.Umbraco.AzureAISearch -Version 1.10.1
<PackageReference Include="GXE.Umbraco.AzureAISearch" Version="1.10.1" />
<PackageVersion Include="GXE.Umbraco.AzureAISearch" Version="1.10.1" />
<PackageReference Include="GXE.Umbraco.AzureAISearch" />
paket add GXE.Umbraco.AzureAISearch --version 1.10.1
#r "nuget: GXE.Umbraco.AzureAISearch, 1.10.1"
#:package GXE.Umbraco.AzureAISearch@1.10.1
#addin nuget:?package=GXE.Umbraco.AzureAISearch&version=1.10.1
#tool nuget:?package=GXE.Umbraco.AzureAISearch&version=1.10.1
Umbraco.AzureAISearch
Azure AI Search provider for Umbraco Search — designed to work seamlessly with Microsoft Foundry while also supporting direct ranked search via the ISearcher interface.
Requires Umbraco 17+ and an Azure AI Search instance.
Why this package?
Microsoft Foundry expects an Azure AI Search index with specific fields — content, url, and title — to ground AI responses. This package indexes Umbraco content directly into that schema, so you can connect your CMS to Foundry without any manual field mapping or data transformation.
At the same time, it maintains relevance tiers and a scoring profile for high-quality direct search results when querying outside of Foundry.
Foundry uses: content, url, title
Direct search uses: contentR1 (4×), contentR2 (3×), contentR3 (2×), content (1×)
Quick Start
1. Install
dotnet add package Umbraco.Cms.Search.Core
dotnet add package GXE.Umbraco.AzureAISearch
2. Configure
Add to appsettings.json:
{
"AzureAISearch": {
"Endpoint": "https://your-service.search.windows.net",
"Key": "your-admin-api-key",
"BaseUrl": "https://www.your-umbraco-site.com",
"ExcludedContentTypes": [],
"Environment": null
}
}
| Setting | Description |
|---|---|
Endpoint |
Your Azure AI Search service URL |
Key |
Admin API key |
BaseUrl |
(Optional, recommended) Your public Umbraco site URL used to build absolute content links. Do not set this to the Azure Search Endpoint. |
ExcludedContentTypes |
Array of content type aliases to skip during indexing |
Environment |
Optional prefix for index names (e.g. "dev" → dev-publishedcontent) |
3. Register
Create a composer:
using Umbraco.AzureAISearch.Extensions;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Search.Core.DependencyInjection;
public sealed class SearchComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.AddSearchCore();
builder.AddUmbracoAzureAISearch(builder.Config)
.RebuildAzureAISearchOnStartup(); // optional: full re-index on every startup
}
}
That's it. On startup, the index is created automatically. Content is indexed incrementally on save & publish.
Initial Index Population
By default, only new content published after the package is installed gets indexed. To populate the index with all existing content, chain .RebuildAzureAISearchOnStartup():
builder.AddUmbracoAzureAISearch(builder.Config)
.RebuildAzureAISearchOnStartup();
This triggers a full rebuild via IContentIndexingService on every application start. Once your index is populated, you can remove this call to avoid unnecessary rebuilds — incremental indexing on save/publish will keep the index up to date.
Index Schema
The generated Azure AI Search index contains:
| Field | Type | Purpose |
|---|---|---|
id |
String (Key) | Unique document identifier ({guid}_{culture}_{segment}) |
key |
String | Umbraco content GUID |
objectType |
String | Umbraco object type |
culture |
String | Culture code or "inv" |
segment |
String | Segment or "def" |
title |
String | Content node name |
content |
String | All text combined, HTML-stripped — Foundry searches this |
contentR1 |
Collection | High-relevance text (titles, headings) |
contentR2 |
Collection | Medium-relevance text |
contentR3 |
Collection | Lower-relevance text |
url |
String | Full absolute URL |
accessKeys |
Collection | Content protection keys |
Searching
Inject IAzureAISearchSearcher for direct search with full scoring:
using Umbraco.AzureAISearch.Services.Searcher;
public class SiteSearchService(IAzureAISearchSearcher searcher)
{
public async Task<SearchResult> SearchAsync(string query, string? culture = null)
=> await searcher.SearchAsync(
indexAlias: Umbraco.Cms.Search.Core.Constants.IndexAliases.PublishedContent,
query: query,
culture: culture,
skip: 0,
take: 20);
}
The scoring profile automatically boosts contentR1 (4×) over contentR2 (3×) over contentR3 (2×) over content (1×).
Microsoft Foundry Integration
Once content is indexed, connect the Azure AI Search index in Foundry:
- Go to your Foundry project → Data sources
- Add an Azure AI Search connection pointing to your search service
- Select the index (e.g.
publishedcontentordev-publishedcontent) - Foundry will use the
contentfield for search andurl/titlefor grounding responses
No additional mapping or field configuration is needed in Foundry.
Server Role Awareness
On multi-server deployments, only the primary node manages the index. Subscriber nodes skip all write operations automatically.
Releasing a New Version
- Ensure all changes are committed and pushed to
main - Tag the release with the version number:
git tag v1.2.0 git push --tags - The GitHub Actions workflow automatically builds, tests, and publishes to NuGet.org via Trusted Publishing (no API key required)
The version in the tag (e.g. v1.2.0) is used as the package version — no need to update .csproj manually.
License
MIT
| 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
- Azure.Search.Documents (>= 11.7.0)
- Umbraco.Cms.Search.Core (>= 1.0.0)
- Umbraco.Cms.Web.Common (>= 17.0.0 && < 18.0.0)
- Umbraco.Cms.Web.Website (>= 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.