Skip to main content

Outline

At a glance
  • Mandatory shift: Optimizely Graph replaces the deprecated Search & Navigation (Find) infrastructure in CMS 13.
  • Architectural pivot: Transition from server-side C# Fluent APIs to a flexible, GraphQL-based delivery model.
  • Cleanup duty: Decommissioning requires a full purge of legacy EPiServer.Find packages and configurations.
  • Implementation modes: Choose between Content, Typed, or Untyped search based on type-safety and data requirements.

Modernization from Optimizely CMS 12 to CMS 13 necessitates a fundamental change in search architecture. Optimizely Search & Navigation is deprecated in CMS 13, establishing Optimizely Graph as the mandatory service for content indexing, querying, and discovery. This transition requires a strategic shift from server-side, C#-heavy Fluent APIs to a flexible, GraphQL-based delivery model.

1. Architectural Shift: From S&N to Optimizely Graph

Wait-and-see approaches to search migration are not viable, as CMS 13 no longer supports the legacy EPiServer.Find infrastructure. The move to Optimizely Graph is an architectural decision that impacts how data is indexed and retrieved across the entire platform.

  • Service-Bound Indexing: Unlike Search & Navigation, which functioned as a standalone search provider, Optimizely Graph serves as the centralized data backbone for Optimizely One. Content sync is managed automatically through the orchestration layer, ensuring that data is available not just for search results, but for headless delivery and cross-product composition.
  • Query-Driven Flexibility: GraphQL replaces the traditional REST-based search endpoints. This allows technical teams to define precise data shapes in a single request, significantly reducing over-fetching and the need for complex server-side view models.

2. Technical Decommissioning of Search & Navigation

Planning the retirement of legacy search components is the first step in the replacement cycle. This involves removing dependencies that are incompatible with the .NET 10 environment of CMS 13.

Cleanup Requirements

  1. Package Removal: Remove all EPiServer.Find.* NuGet packages from the solution.
  2. Configuration Purge: Eliminate Find specific sections from appsettings.json, including service URLs and default index names.
  3. Code Identification: Audit the codebase for any usage of the ITypeSearch<T> interface or the SearchClient.Instance singleton. These references will result in compiler errors in CMS 13.

3. Integrating Optimizely Graph Client

The implementation layer for search in CMS 13 utilizes the Optimizely.Graph.Client package. System registration occurs within the application's startup sequence to enable content synchronization and API client availability.

Middleware Registration

public void ConfigureServices(IServiceCollection services) { // Required to synchronize CMS data with the Graph service services.AddContentDeliveryApi(); // Core service for content graph indexing services.AddContentGraph(); // SDK Client for executing typed and untyped queries services.AddContentGraphClient(); }

4. Comparing Query Paradigms: Fluent API vs. GraphQL

The most significant development effort in search replacement is the refactoring of query logic. Developers must transition from the C# Fluent API used in Search & Navigation to GraphQL strings or the Optimizely Graph .NET Client's query builder.

Legacy Search & Navigation (Refactor Target)
var results = SearchClient.Instance.Search<StandardPage>() .For("Optimizely") .Filter(x => x.MainBody.Match("Migration")) .OrderBy(x => x.PageName) .GetContentResult();
Optimizely Graph (Replacement Pattern)
query { Content { items { ... on StandardPage { Name Url MainBody { value } } } } }

5. Search Implementation Strategies

Optimizely Graph provides three distinct modes for implementing search functionality, depending on the requirements for type safety and data source.

  • Content Search Mode: This is the recommended replacement for standard CMS search pages. It utilizes IContentLoader internally, ensuring that returned objects are instances of IContent. This mode automatically respects CMS permissions and content URLs.
  • Typed Search Mode: Best suited for high-performance global search or multi-channel delivery where custom data contracts are defined. It offers compile-time type safety for filters.
  • Untyped Search Mode: Provides maximum flexibility by returning raw JsonElement results. Useful for building generic search components where content types are not known at compile time.

6. Identifying Functional Disparities

During the planning phase, technical teams must account for features available in Search & Navigation that are not yet natively supported in the Optimizely Graph pre-release.

  • Native Tracking: Tracking of user clicks and search terms is not currently integrated into the Graph API.
  • Query Suggestions: Features such as "Did you mean?" or spellcheck are currently absent and may require custom implementation.
  • Best Bets: Editorial control over promoted search results is moving to the Graph Management UI and may not have a direct API equivalent initially.

Conclusion

The transition from Search & Navigation to Optimizely Graph is an enablement step for modern, performant delivery. By replacing legacy Fluent API patterns with GraphQL, implementations gain extreme flexibility across web and mobile channels. Successful replacement planning focuses on early decommissioning of legacy packages, selecting the appropriate implementation mode, and establishing a clear refactoring path for complex filtering logic.