Category: Optimizely

Optimizely Opti ID Integration: Why the API Key Was Missing from the DXP Management Portal

While working on an Optimizely CMS 12 Opti ID integration recently, we ran into an issue that initially appeared to be related to SSO authentication but turned out to be an environment-specific configuration requirement.

The Problem

We needed to configure API key authentication for an Optimizely integration. However, when accessing the DXP Management Portal (PaaS Portal), the expected API key details were not visible.

At the same time, the team was investigating issues accessing the Admin Center and Support Portal through Opti ID SSO, which made it seem like the problems might be related.

What We Learned

After engaging Optimizely Support, the key piece of information was that:

The API for local configuration only works for the Integration environment. To view and use the API key configuration within the DXP Management Portal, Opti ID must first be enabled for the Integration CMS environment.[docs.devel…mizely.com]

This was not immediately obvious and explained why the API key details were not appearing even though the environment was otherwise accessible.

Resolution

Once Opti ID was enabled for the Integration environment:

  • The DXP Management Portal began displaying the API key details.
  • We were able to retrieve the required credentials.
  • The API key was configured in the application.
  • Functional testing could proceed successfully.

As confirmed during testing:

We have enabled Opti ID for the integration environment and the PaaS portal now shows the API key details. We configured the API key details in our code and started testing the functionality.

Key Takeaways

When working with Optimizely Opti ID integrations:

  1. Verify that Opti ID is enabled for the Integration CMS environment before attempting to retrieve API key details.
  2. If API keys are missing from the DXP Management Portal, check environment configuration first.
  3. Avoid assuming SSO authentication issues and API key visibility issues have the same root cause.
  4. Engage Optimizely Support early when certificate or authentication behavior appears inconsistent.
  5. Complete API key validation in Integration before promoting any configuration to higher environments.

Final Thoughts

A simple environment prerequisite prevented the API credentials from being displayed, and identifying that dependency quickly moved the team from investigation back into testing.

Happy Optimizing!

0

Optimizely CMS 12 and .NET 10 Upgrade: Resolving a TinyMCE Dependency Injection Exception

Framework upgrades often expose hidden compatibility issues that have remained dormant for years. While upgrading one of our Optimizely CMS solutions to .NET 10, we encountered a runtime exception that initially appeared to be a dependency injection problem but ultimately turned out to be an outdated TinyMCE package.

This post documents the issue, the investigation journey, and the surprisingly simple fix.

The Problem

After upgrading our solution to:

  • .NET 10
  • Optimizely CMS 12.34.4

the application failed during startup with the following exception:

AggregateException: One or more errors occurred.
 
Unable to resolve service for type
‘EPiServer.ServiceLocation.ServiceAccessor<EPiServer.Cms.TinyMce.Core.TinyMceConfiguration>’
while attempting to activate
‘DXP.Core.Model.TimelineBlockXhtmlStringEditorDescriptor’.

 

The exception pointed to our custom TinyMCE editor descriptor:

[EditorDescriptorRegistration(
TargetType = typeof(XhtmlString),
EditorDescriptorBehavior = EditorDescriptorBehavior.OverrideDefault,
UIHint = UIHint)]
public class TimelineBlockXhtmlStringEditorDescriptor
: XhtmlStringEditorDescriptor
{
public const string UIHint =
"TimelineBlockXhtmlStringEditorDescriptor";
 
public TimelineBlockXhtmlStringEditorDescriptor(
ServiceAccessor<TinyMceConfiguration> tinyMceConfiguration)
: base(tinyMceConfiguration)
{
}
public override void ModifyMetadata(
ExtendedMetadata metadata,
IEnumerable<Attribute> attributes)
{
// custom implementation
}
}

At first glance, it looked like a service registration or dependency injection issue.

Environment Details

The key package versions at the time were:

  • Optimizely CMS 12.34.4
  • EPiServer.CMS.TinyMce 4.8.3
  • .NET 10

The application had been working correctly before the framework upgrade, which made the issue particularly challenging to diagnose.

Initial Investigation

Our TinyMCE registration was straightforward:

services
.AddCmsAspNetIdentity<ApplicationUser>()
.AddCms()
.AddTinyMce();

and custom configuration was registered using:

services.Configure<TinyMceConfiguration>(config =>
{
// custom TinyMCE settings
});

Everything appeared to be configured correctly.

Testing on Alloy

To isolate the problem, we reproduced similar TinyMCE configuration in a clean Alloy solution running on .NET 10.

The result:

  • CMS started successfully

  • TinyMCE loaded correctly

  • No dependency injection errors

This immediately suggested the problem was not a generic Optimizely or .NET 10 issue.

Reviewing Custom Editor Descriptors

Since the exception referenced:

TimelineBlockXhtmlStringEditorDescriptor

we spent considerable time reviewing:

  • Editor descriptor registrations
  • Dependency injection registrations
  • Startup ordering
  • TinyMCE configuration extensions

Everything looked valid.

Checking Service Registration Order

We also reviewed whether .NET 10 had introduced behavioural differences in service registration and startup initialization.

Multiple registration orders were tested:

services.AddCms();
services.AddTinyMce();
services.Configure<TinyMceConfiguration>();

and

services.Configure<TinyMceConfiguration>();
services.AddCms();
services.AddTinyMce();

No change.

The Root Cause

After eliminating configuration and dependency injection possibilities, attention shifted to package compatibility.

EPiServer.CMS.TinyMce 4.8.3

Although the package had worked successfully before the upgrade, it was clearly not behaving correctly in the .NET 10 environment.

The Fix

We upgraded TinyMCE from:

EPiServer.CMS.TinyMce 5.0.3

After upgrading:

  • Application started successfully
  • TinyMCE initialized correctly
  • Dependency injection exception disappeared
  • Custom editor descriptors continued to work
  • CMS editor experience was fully restored

Happy Optimizely!

0

Optimizely : Missing Language Manager Gadget Fix in CMS 12 After Upgrading to .NET 10

Recently, while upgrading an Optimizely CMS solution to .NET 10, we came across an issue where the Language Manager gadget completely disappeared from CMS Edit Mode.

The application was functioning normally, content editing worked as expected, and there were no build or startup errors. However, editors noticed that the Language Manager gadget was no longer available.

What made the issue difficult to troubleshoot was the complete absence of meaningful error messages.

In this blog, I will walk through the issue, the troubleshooting journey, and the simple configuration change that ultimately resolved it.

Environment

The affected solution was running the following versions:

  • .NET 10
  • Optimizely CMS 12.34.4
  • EPiServer.CMS.UI 12.34.4
  • EPiServer.Labs.LanguageManager 5.5.3

Immediately after the upgrade, the Language Manager gadget disappeared from the CMS editing interface.

Symptoms

Editors reported the following:

  • Language Manager gadget missing from Edit Mode
  • Gadget not available in the “Add Gadgets” list
  • Reinstalling the package did not help
  • Browser cache clearing had no effect
  • Application started successfully without errors

The issue was consistent across environments and users.

Initial Checks

As part of the troubleshooting process, we verified the obvious areas first.

Verify Package Installation

The Language Manager package was installed correctly.

<PackageVersion Include="EPiServer.Labs.LanguageManager" Version="5.5.3" />

No package restore issues were identified.

Verify Language Configuration

We confirmed that all required languages were enabled within Optimizely Admin Mode.

Since multilingual content was configured correctly, the problem was clearly elsewhere.

What Was Causing the Issue?

After working with Optimizely Support, the investigation pointed towards a .NET build configuration setting that was affecting assembly discovery.

The application itself was running correctly, but dependency information required by certain Optimizely add-ons was being trimmed during the build process.

Because of this, Language Manager was not being initialized correctly, resulting in the gadget disappearing from the CMS UI.

The tricky part was that there were:

  • No compilation errors
  • No startup failures
  • No obvious exceptions

The feature simply disappeared.

The Fix

The issue was resolved by adding the following property to the project file:

<PropertyGroup>
<TrimDepsJsonLibrariesWithoutAssets>false</TrimDepsJsonLibrariesWithoutAssets>
</PropertyGroup>
 

After adding the setting:

  1. Rebuild the solution
  2. Redeploy the application
  3. Restart the site

The Language Manager gadget immediately became visible again.

Happy Optimizing! 
0

Unlock AI-Ready Experiences with Optimizely

Over the past few months, almost every customer conversation has shifted from SEO to AI readiness.

The questions are no longer just:

“How do we rank higher on Google?”

They’re becoming:

“How do we make sure ChatGPT, Copilot, Gemini, or Claude can find and understand our content?”

If you’re running an Optimizely website, the good news is that you don’t need a complete redesign. A few small improvements can make your content much easier for AI systems to discover and consume.

In this post, I’ll walk through a few simple changes we’ve been discussing with customers, including:

  • Upgrading the Stott Security RobotHandler
  • Adding an llms.txt file
  • Structuring content for AI
  • Improving metadata
  • Preparing your Optimizely implementation for the next generation of search

Why AI Readiness Matters

Search engines return links.

LLMs return answers.

That means AI systems need to understand your content, not just crawl it.

If your website has:

  • messy content
  • outdated metadata
  • poor internal linking
  • no structured information

then AI assistants have a harder time understanding what your organization actually offers.

Fortunately, most of these improvements are things we should already be doing.

Step 1 – Upgrade Stott Security RobotHandler

We are currently using Stott.Security.Optimizely.RobotsHandler 3.x – CMS PaaS 12 

There isn’t necessarily anything wrong with version 3, but if you’re actively maintaining your solution, it’s worth upgrading to the latest release to benefit from ongoing fixes, compatibility improvements, and newer Optimizely support.

Updating is straightforward.

Remove the old package:

dotnet remove package Stott.Security.Optimizely.RobotsHandler

Install the latest version:

dotnet add package Stott.Security.Optimizely.RobotsHandler

After upgrading, verify that:

  • robots.txt is still generated correctly
  • your sitemap is referenced
  • custom rules still work
  • different environments behave as expected

It only takes a few minutes but keeps an important part of your site’s crawl configuration up to date.

Step 2 – Add an llms.txt File

You have probably heard about llms.txt recently.

Think of it as the AI equivalent of a sitemap.

While it isn’t an official web standard today, more organizations are publishing one to help AI systems discover their most important content.

A simple example looks like this:

# Contoso

Website:
https://contoso.com

Documentation:
https://contoso.com/docs

Products:
https://contoso.com/products

Support:
https://contoso.com/support
 

For smaller websites, a static file is perfectly fine.

For enterprise Optimizely implementations with thousands of pages, I’d recommend generating it dynamically so it always reflects your published content.

That’s something I’ll cover in a future post.

Step 3 – Structure Your Content

This is probably the biggest opportunity.

Many websites still publish pages that contain multiple unrelated topics, huge blocks of text, and headings like:

Learn More

AI models love structure.

Instead, organize pages with:

  • meaningful headings
  • summaries
  • FAQs
  • bullet lists
  • tables where appropriate

Good content structure helps humans and AI alike.

Step 4 – Don’t Ignore Metadata

Metadata is still important.

Make sure every page includes:

  • Page title
  • Meta description
  • Canonical URL
  • Open Graph tags
  • Schema.org structured data

Structured data gives AI additional context about your pages, products, articles, events, and organization.

Step 5 – Review Your Sitemap

Your XML sitemap should always be current.

Remove:

  • unpublished pages
  • redirects
  • expired content

Include:

  • important landing pages
  • articles
  • product pages
  • documentation

This benefits traditional search engines and AI crawlers alike.

Step 6 – Improve Internal Linking

One thing that’s often overlooked is internal linking.

If every page exists in isolation, AI has to work harder to understand the relationships between your content.

Instead, connect related pages naturally.

For example:

  • Blog → Product
  • Product → Documentation
  • Documentation → FAQ
  • FAQ → Support

These relationships help both users and AI navigate your website more effectively.

Step 7 – Expose Content Through APIs

If you’re building AI-powered experiences, don’t stop with web pages.

Optimizely already provides excellent options for exposing structured content, including:

  • Content Delivery API
  • Content Graph
  • Search & Navigation indexes

These services make it much easier to build Retrieval-Augmented Generation (RAG) applications and AI assistants that provide grounded responses based on your content.

Most of these are relatively small changes, but together they make your content significantly easier for AI systems to understand and surface.

As AI continues to change how people discover information, preparing your Optimizely website today will put you in a much stronger position tomorrow.

Happy Optimizing!

0

Optimizely: Upgrade Opti-ID and .NET 10 in CMS 12

Many Optimizely customers are planning their roadmap around a future migration to Optimizely CMS 13. As a result, upgrades such as Opti ID adoption and .NET modernization are often postponed until the CMS 13 project begins.

However, waiting for CMS 13 is not necessary.

Organizations running Optimizely CMS 12 can upgrade to Opti ID and move to .NET 10 today, gaining immediate security, performance, and operational benefits while reducing the complexity of a future CMS 13 migration.

Why Modernize on CMS 12?

Instead of combining multiple transformations into a single CMS 13 project, organizations can:

  • Improve security immediately
  • Standardize authentication
  • Modernize the application platform
  • Reduce future migration complexity
  • Enable newer Optimizely SaaS capabilities

A phased modernization approach is typically lower risk than a large-scale platform upgrade.

Part 1: Implementing Opti ID in CMS 12

What is Opti ID?

Opti ID is Optimizely’s centralized authentication platform that provides:

  • Single Sign-On (SSO)
  • Multi-Factor Authentication (MFA)
  • Centralized user administration
  • Unified access across Optimizely products
  • Improved security and compliance

Required NuGet Packages

Depending on your CMS 12 version, install or upgrade the following packages.

Core CMS Packages

Install-Package EPiServer.CMS
Install-Package EPiServer.CMS.AspNetCore
Install-Package EPiServer.CMS.UI

Identity Packages

Install-Package EPiServer.CMS.UI.AspNetIdentity
Install-Package Microsoft.AspNetCore.Authentication.OpenIdConnect
Install-Package Microsoft.Identity.Web

Always align package versions with the Optimizely-supported package matrix for your CMS version.

Step 1: Enable Opti ID in Optimizely

Within the Optimizely Admin Portal:

  1. Navigate to Administration
  2. Enable Opti ID
  3. Configure organization users
  4. Assign product access
  5. Configure MFA policies

Step 2: Configure Authentication

Update Program.cs.

Add Authentication Services

builder.Services
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.Authority = configuration["Authentication:Authority"];
options.ClientId = configuration["Authentication:ClientId"];
options.ClientSecret = configuration["Authentication:ClientSecret"];

options.ResponseType = "code";

options.SaveTokens = true;
});
 

Step 3: Configure appsettings.json

{
"Authentication": {
"Authority": "https://login.optimizely.com",
"ClientId": "xxxxx",
"ClientSecret": "xxxxx"
}
}

Step 4: Configure Authorization

Map Opti ID users to CMS roles.

Example:

services.AddAuthorization(options =>
{
options.AddPolicy("CmsEditors",
policy => policy.RequireRole("WebEditors"));
});
Validate:
  • WebEditors
  • Administrators
  • ContentApprovers
  • MarketingUsers

Part 2: Upgrading CMS 12 to .NET 10

Why Upgrade?

Benefits include:

  • Improved performance
  • Better security
  • Long-term support alignment
  • Reduced technical debt
  • Better cloud-native capabilities

Step 1: Upgrade Development Environment

Install:

  • .NET 10 SDK
  • Visual Studio 2026 (or latest supported version)

Step 2: Update Project Files

Update:

<TargetFramework>net10.0</TargetFramework>

Step 3: Upgrade NuGet Packages

CMS Packages

<PackageReference Include="EPiServer.CMS.Core" Version="12.24.0" />
<PackageReference Include="EPiServer.CMS.UI" Version="12.34.4" />

Microsoft Packages  

<PackageReference Include="Microsoft.Extensions.*" />
<PackageReference Include="Microsoft.AspNetCore.*" />
<PackageReference Include="Microsoft.Identity.Web" />

Hope this helps.

Happy Optimizing!
0

Optimizely CMS 13 Upgrade Overview

Wondering how to upgrade from Optimizely CMS 12 to 13? Not sure where to start – you are not alone. 

Here is a quick overview of the key architectural changes that need to be addressed.

Key Architecture Changes

  1. No Search and Navigation
  2. Opti-ID for Identity
  3. Graph for Search and Discovery
  4.  Embedded DAM
  5. OCP for Integrations
  6. OPAL for AI

Optimizely CMS 13

 

🟩Graph — Search & Discovery

  • Provides unified content search across structured and unstructured data.

  • Enables semantic relationships between content items.

  • Powers personalized discovery experiences through relevance scoring and taxonomy mapping.

  • Integrates with Optimizely’s indexing layer for fast retrieval and filtering.

🟦Opti‑ID — Identity & Access

  • Centralized identity provider for user authentication and authorization.

  • Supports SSO, OAuth 2.0, and enterprise federation (e.g., Azure AD, Okta).

  • Manages user roles, permissions, and attribute mapping across CMS modules.

  • Ensures secure access control for editors, marketers, and external systems.

🟪OPAL — AI Services

  • Provides AI‑driven content recommendations and predictive analytics.

  • Automates tagging, summarization, and personalization workflows.

  • Integrates with external AI APIs for language and vision tasks.

  • Enhances editorial efficiency through intelligent suggestions and insights.

🟩Embedded DAM — Asset Management

  • Manages digital assets (images, videos, documents) directly within CMS.

  • Supports versioning, metadata tagging, and rights management.

  • Enables seamless asset reuse across pages and campaigns.

  • Connects to external storage or CDN for optimized delivery.

⬛OCP — Integrations & Connectors

  • Provides an integration framework for third‑party systems (CRM, ERP, marketing tools).

  • Uses REST APIs and webhooks for data synchronization.

  • Supports modular connectors for commerce, analytics, and automation.

  • Ensures scalable interoperability across enterprise ecosystems.

Hope this helps.

Happy Optimizing!

 

0

Optimizely Opal: Unlocking AI-Powered Marketing with Opal Chat & Agents

I’ve just released a new YouTube video highlighting Optimizely Opal and how it’s transforming modern marketing with AI-powered chat and intelligent agents.

In this video, you’ll get a quick overview of:

  • Opal Chat and how it simplifies everyday marketing tasks
  • AI agents that help generate content, insights, and reports
  • How Opal enables faster, smarter marketing workflows

Check out the video here –

Happy Optimizing!

 

0

Optimizely: Our Journey in the Opal Innovation Challenge

When we signed up for Optimizely’s Opal Innovation Challenge, we knew it wasn’t just about building a solution—it was about solving a real marketing pain point. As marketing professionals and technologists, we’ve seen countless campaigns fail despite being well-written. Why? Because they didn’t resonate with the audience. This challenge gave us the perfect opportunity to tackle that problem head-on.

https://www.optimizely.com/operation-opal/#challenge

The Spark Behind the Idea

Marketing teams often struggle with persona alignment. A campaign might sound great internally, but fall flat with the target audience. For example:

  • Campaign 1: “Save more with Smart meters” – casual tone, generic message.
  • Campaign 2: “Embracing Green Living” – empathetic, informative, and resonates better.

This gap between content creation and audience expectation inspired our solution.

Our Team & Approach

We formed Infosys Transformers, a two-member team:

Our goal was simple yet ambitious: Make every piece of content count.

Challenges We Faced

  • Time Constraints: Building a multi-agent workflow in a hackathon timeframe was intense.
  • Balancing Creativity & Tech: Ensuring the solution was both innovative and practical.
  • Persona Complexity: Defining measurable persona attributes for scoring was tricky.

Timelines

Key Lessons Learned

  1. Persona Alignment is Non-Negotiable: Content without persona context is just noise.
  2. AI Can Bridge the Gap: Multi-agent systems can automate what manual reviews can’t.
  3. Collaboration is Everything: Combining tech and marketing expertise was our biggest strength.
  4. Start Simple, Scale Later: A modular approach helped us deliver a working prototype fast.

The Hackathon Experience

The Opal Innovation Challenge wasn’t just a competition—it was a learning marathon. We explored Opal’s agent ecosystem, experimented with orchestration, and realized how AI can transform marketing workflows.

Check out our video presented at the Hackathon – 

 

Closing Thoughts

Innovation happens when you combine empathy with technology. For us, this challenge was proof that marketing and AI are not separate worlds—they’re partners in creating meaningful experiences.

Top teams can win prizes like $5,000 in MDF, gift cards, and thought leadership opportunities.

Hope this helps.

Happy Optimizing!

0

Optimizely : Show Personalized Content Blocks

I have been exploring Personalization on Optimizely CMS 12 – Simple to set up, and can be utilized throughout the website.

I came across this use case where we want to show the Priority Call button on a page only during business hours.

The page currently has no call-to-action button.

Let’s get started to personalize the page to add a Priority Call button.

Step 1: Create Audience

  • Create an audience with the rules you would like to define.

Optimizely-CMS-Personalization-Content-Block.png

  • I created an Audience called Priority Call specifically for customers who can call the priority phone number during business hours.

Optimizely-CMS-Personalization-Content-Block-1.png

  • Add Criteria based on the project needs – multiple criteria can target specific customers.

  • Added Time of Day criteria – Monday to Friday from 8 am to 5 pm.

Optimizely-CMS-Personalization-Content-Block-3.png

 

Step 2: Create a Personalized Block

  • Now that we have created the target Audience. Let’s make a personalized block for a page.
  • I chose the ‘Find a Reseller’ page and, in Blocks, I am going to create a New Block for this page – you can also create one for the All Sites.

  •  Selected Button as the New Block and gave it a name – Priority Call Button.

  • Filled out the Button Text and Link.

  • Please make sure to Publish the Block – If not, it will not be visible on the page. 
  • I have made this mistake and wondered why the block isn’t appearing 🙂

 

3. Add the Personalized Block to a Page

  • Let’s drag and drop the Priority Call Button block into the Large Content Area or any Content Area.

  • Let’s personalize the button.

  • Everyone is by default – let’s change it to our new audience Priority Call.

  • Let’s publish the page and view it during business hours (our Audience criteria)
  • Yay! We could see the Priority Call Button!

If you prefer watching a video, my quick recording –

Hope this helps.

Happy Optimizing!

0