Disclaimer: This website requires Please enable JavaScript in your browser settings for the best experience.

HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

CMS extension packages and components

Describes the integration between Optimizely Search & Navigation and Optimizely Content Management System (CMS).

The extension includes specific components for using the Optimizely Search & Navigation .NET client API with the Optimizely Content Management System (CMS).

Set up for development

The CMS extension assumes each environment has its own Search & Navigation index. It also assumes that content is added and removed through the CMS API. This means that:

  • Each developer should have their development index unless you use a shared database.
  • Each server environment (test, staging, and so on) should have its index unless it uses a shared database.
  • If content is removed or added in ways other than the CMS API (for instance, using a database restore or rollback), you should run the scheduled job for re-indexing.

If you do not follow the previous guidelines, the search and querying functionality may appear to work but produce unexpected results. For example, the GetContentResult method returns less content than its TotalMatching property reports, which could happen if two developers use the same index, and one publishes a page that does not exist in the other developer's database.

Packages

The following packages are used for Search & Navigation-specific integrations:

  • Episerver.Find.Cms – Integration of Find REST API with Optimizely Content Management System (CMS).
  • EPiServer.Find – The .NET client API for the Find REST API (installed with EPiServer.Find.Cms).
  • EPiServer.Find.Framework – General integration components for the Find REST API (installed with EPiServer.Find.Cms).
  • EPiServer.Find.Cms.AttachmentFilter – File type parser for CMS attachments.
  • EPiServer.Commerce.FindSearchProvider – Integration components for Optimizely Commerce Connect (v13).
  • EPiServer.Find.Commerce – Integration components for Optimizely Commerce Connect (v13).
  • EPiServer.Find.Personalization – Integration components for Personalized Search & Navigation.

Reference the assemblies needed in your project, and add the standard configuration for the .NET API to web.config.

📘

Note

If you installed Optimizely Search & Navigation with a sample site through the Visual Studio extensions, the integration with CMS is automatically set up.

Extension components

The Optimizely Search & Navigation extension builds on a .NET-based client API, adding functionality for automatically indexing objects and methods for filtering, retrieving, and caching results. The following list shows some of the functionality you get with the extension:

  • IndexingModule – Hooks up events to handle content indexing (IContent objects).
  • SearchClient.Instance – To manage the SearchClient.Instance object, conventions are applied to exclude certain properties of the IContent object and other CMS classes while also incorporating additional fields. This process is executed by the IndexingModule during startup through the CmsClientConventions class. When using the general .NET API, you typically create an IClient instance with the Client.CreateFromConfig method. In alignment with the standard development approach, the Optimizely integration offers a singleton instance via the SearchClient class and its Instance property. Although the instance returned is a standard IClient, it undergoes some modifications at startup. Therefore, when working with CMS and Search & Navigation, it is important to use SearchClient.Instance.

    ❗️

    Warning

    Differences between the authentication mechanism of EPiServer.ServiceAPI and EPiServer.Find may lead to the incorrect functioning of user authentication. To avoid these problems, you should install EPiServer.ServiceAPI in a separate application.

  • ContentIndexer – This class handles the indexing, re-indexing, and removing content from the index. You can customize content to be indexed by modifying its conventions.
  • GetContentResult – Call this extension method to execute search requests and get actual IContent objects back.
  • Episerver Find (Search & Navigation) Content Indexing Job – A scheduled job that handles content re-indexing.
  • Several additional filter methods, such as ContentReference, make it more convenient to filter on CMS types.

Content Security Policy update for Service Health dashboard

To ensure the Service Health view in the Optimizely Search & Navigation UI functions correctly, clients must update their Content Security Policy (CSP) settings. If you have implemented a CSP, then it is likely in your Startup.cs it might look something like this:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
  if (env.IsDevelopment()) {
    app.UseDeveloperExceptionPage();
    app.UseMiddleware < AdministratorRegistrationPageMiddleware > ();
  }

  // Add Content Security Policy (CSP)
  app.Use(async (context, next) => {
    context.Response.Headers.Add(
      "Content-Security-Policy",
      "default-src 'self'; " +
      "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.optimizely.com; " +
      "img-src 'self' data: https://*.optimizely.com; " +
      "style-src 'self' 'unsafe-inline' https://localhost:44333; " +
      "font-src 'self' https://*.cloudfront.net https://localhost:44333; " +
      "connect-src 'self' ws://localhost:* http://localhost:*;" +
      "object-src 'none';"
    );
    await next.Invoke();
  });

  app.UseStaticFiles();
  app.UseRouting();
  app.UseAuthentication();
  app.UseAuthorization();
  app.UseEndpoints(endpoints => {
    endpoints.MapContent();
    endpoints.MapControllerRoute("Register", "/Register", new {
      controller = "Register", action = "Index"
    });
    endpoints.MapControllerRoute(
      name: "default",
      pattern: "{controller=Home}/{action=Index}/{id?}");
    endpoints.MapRazorPages();
  });
}

To fix it and let the Service Health Dashboard function correctly, add the following directive to the CSP header configuration:

"frame-src 'self' dashboard.find.episerver.net;" +

The updated CSP configuration should look like this:

app.Use(async (context, next) => {
  context.Response.Headers.Add(
    "Content-Security-Policy",
    "default-src 'self'; " +
    "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.optimizely.com; " +
    "img-src 'self' data: https://*.optimizely.com; " +
    "style-src 'self' 'unsafe-inline' https://localhost:44333; " +
    "font-src 'self' https://*.cloudfront.net https://localhost:44333; " +
    "connect-src 'self' ws://localhost:* http://localhost:*;" +
    "frame-src 'self' dashboard.find.episerver.net;" + // Added directive
    "object-src 'none';"
  );
  await next.Invoke();
});

Updating your CSP settings as shown lets the necessary connections for the Service Health view operate properly.