Robert Svallin
Mar 20, 2026
  976
(2 votes)

CMS 13 Preview 4 — Upgrading from Preview 3

This is the third post in a series where I use the Alloy template as a reference to walk through each CMS 13 preview. The first post covered upgrading from CMS 12 to Preview 2, and the second looked at the key changes in Preview 3. If you're following along, pick up where we left off.

Preview 4 is out. The package bump is easy enough, but there's an API change around how you resolve the start page that'll ripple through your code. Here's what to change and what's worth knowing about.

Step 1: Update Packages

Bump your package references from preview3 to preview4:

<PackageReference Include="EPiServer.CMS" Version="13.0.0-preview4" />
<PackageReference Include="EPiServer.CMS.UI.AspNetIdentity" Version="13.0.0-preview4" />
<PackageReference Include="Optimizely.Graph.Cms" Version="13.0.0-preview4" />

Known Issue: Database Schema Upgrade from Older CMS 12 Versions

If you're upgrading directly from an older CMS 12 version (e.g. 12.34.1 or earlier) to a CMS 13 preview and not from preview3 (which this article assumes), the database schema migration may fail with an error like:
Column names in each table must be unique. Column name 'Failed' in table 'dbo.tblNotificationMessage' is specified more than once.
This happens because certain columns were added in later CMS 12 releases, and the CMS 13 migration scripts don't check whether they already exist before trying to add them.
Workaround: First upgrade to the latest CMS 12 version so that your database schema is fully up to date, then upgrade from there to the CMS 13 preview. This ensures all intermediate schema changes are applied before the CMS 13 migration runs.

Step 2: Resolving the Start Page

In Preview 3, Alloy template resolved the start page by casting to Website and accessing RoutingEntryPoint. In Preview 4, the simplest approach is to use ContentReference.StartPage directly — no need to go through IApplicationResolver in most cases.

Before (Preview 3)

var website = _applicationResolver.GetByContext() as Website;
var startPageContentLink = website?.RoutingEntryPoint;

After (Preview 4)

var startPageContentLink = ContentReference.StartPage;

In the Alloy template this simplified things across several files by using ContentReference.StartPage 
- PageViewContextFactory.cs — CreateLayoutModel 
ContentLocator.cs — GetContactPages 
- PreviewController.cs — the Index action
- StartPageController.cs — the Index action
Breadcrumbs.cshtml and Header.cshtml — same change

If you do need more control, IRoutableApplication with its EntryPoint property is still available as an alternative.

The SiteDefinition migration keeps getting refined. Issues with default application provisioning and hostname resolution between preview and view modes from earlier previews have been sorted out.

Step 3: DAM Integration (optional)

Preview 4 adds a new package for Optimizely DAM integration. Its important to call out that even though DAM is a fundamental piece of CMS 13 it is possible to run without it. CMS still can store assets in te traditional sense.

Similar to CMS 12 the DAM configuration is handled using options directly requiring an application to be created in CMP from which the credentials can be retrieved for configuration in CMS. You'll also need the SSO ID which can be found under Settings \ Organization \ General in CMP.

The DAM integration no longer talks to the CMP REST API directly. Instead it's built on External Sources, which means DAM assets need to be indexed into the Optimizely Graph instance connected to your CMS. So before wiring up the code below, make sure you have Optimizely Graph set up, then contact Optimizely Support to connect DAM to your Graph instance. The onboarding steps — selecting your DAM instance, activating asset types — follow the same process as CMS SaaS and are documented in the Onboard DAM to CMS guide. Updated documentation specific to CMS 13 will be available at release. Once that's done, Content Manager can be used to discover and pick DAM assets directly from the editing UI.

Add the package:

<PackageReference Include="EPiServer.Cms.DamIntegration.UI" Version="13.0.0-preview4" />

Register the DAM UI in Startup.cs:

services.AddDamUI();

Add the DAM HTML helpers namespace to Views/_ViewImports.cshtml:

@using EPiServer.Cms.DamIntegration.UI.Helpers

This gives you access to helpers like RenderTagWithMetadata(...) for rendering DAM assets. Note that the epi-property tag helper you're already using comes from EPiServer.Cms.AspNetCore.TagHelpers, which should already be registered in your _ViewImports.cshtml via @addTagHelper.

Then configure your CMP credentials (note that these have defaults, included here for transparency) in appsettings.json:

"Optimizely": {
  "Cms": {
    "DamUI": {
      "Endpoint": "https://cmp.optimizely.com",
      "SsoId": "<your-sso-id>",
      "NavigationUrl": "https://cmp.optimizely.com/cloud/library"
    }
  },
  "Cmp": {
    "Client": {
      "TokenUrl": "https://accounts.cmp.optimizely.com/o/oauth2/v1/token",
      "ApiUrl": "https://api.cmp.optimizely.com/v3/",
      "ClientId": "<your-client-id>",
      "ClientSecret": "<your-client-secret>"
    }
  }
}

The DAM picker now also supports multi-select, which is a nice improvement for editors working with lots of media.

Migrating from CMS 12 DAM Integration

For the GA release of CMS 13, a standalone migration package will be available that converts the CMS 12-style DAM integration to the new one. This package will handle the migration of existing DAM asset references so that they work with the new EPiServer.Cms.DamIntegration.UI package.

The first version of the migration package will support:
  - ContentReference properties
  - IList<ContentReference> properties

Support for additional property types will be added in future releases.

Using DAM Assets in Your Content

To use DAM assets on a page, add a ContentReference property with the UIHint.Image hint:

using EPiServer.Web;
using System.ComponentModel.DataAnnotations;

public class DamExamplePage : StandardPage
{
    [Display(GroupName = Globals.GroupNames.Content)]
    [UIHint(UIHint.Image)]
    public virtual ContentReference Image { get; set; }
}

In the view, render it with the epi-property tag helper — same pattern as any other CMS property:

<img epi-property="@Model.CurrentPage.Image" />

Step 4: Audiences (optional)

Audiences are a separate package in CMS 13. If you were using services.AddVisitorGroups() in Preview 3, you'll need to add the new NuGet package and update your service registration.

Add the package:

<PackageReference Include="EPiServer.Cms.UI.VisitorGroups" Version="13.0.0-preview4" />

Then update your Startup.cs — the old AddVisitorGroups() call is replaced with two separate registrations:

using EPiServer.Cms.UI.VisitorGroups;
services.AddVisitorGroupsMvc().AddVisitorGroupsUI();

A few audience-related bugs have also been fixed: the policy-not-found error is gone, Geographic Location criteria works, and context menu positioning for personalized groups has been corrected.

What Else Is New in Preview 4

A few things worth knowing about beyond the upgrade steps:

Graph .NET SDK

There's a new .NET SDK for Optimizely Graph with a fluent API covering facets, caching, auth, tracking, and object-to-Graph field mapping. Extensibility points have also been added to ContentGraph.CMS so you can hook into the indexing pipeline.

Improved Migration from SiteDefinition

The migration from SiteDefinition to the Application Model has been improved. Creating in-process websites via the settings UI works again, and typed content types now show up correctly when picking the start page for an application.

For the full list of changes, check the official release notes.

Mar 20, 2026

Comments

Piotr
Piotr Mar 20, 2026 07:40 PM

Great series, Robert - following this closely as we're in the middle of our own CMS 13 migration.

One thing I haven't seen covered yet: any idea when a Commerce 15 preview targeting CMS 13 / .NET 10 might land? We're currently blocked because Commerce 14.45.0 still has a hard dependency on ISynchronizedObjectInstanceCache, which got removed in Framework 13.0.0.0 boots up with a lovely AggregateException full of ReflectionTypeLoadExceptions.

Would really help with planning if there's even a rough ETA or a preview feed we could point at.

Piotr

Robert Svallin
Robert Svallin Mar 22, 2026 08:58 PM

@Piotr thank you! Please refer to the new assembly EPiServer.Cache, EPiServer.Cache 13.0.0-preview4 - Optimizely Nuget. It should contain the ISynchronizedObjectInstanceCache. As we get closer to the GA release more documentation will come online. Regarding Commerce I dont want to speak on their behalf, but I think it is safe to assume that they are working on something.

Bien Nguyen
Bien Nguyen Mar 23, 2026 07:08 AM

Hi @Piotr, thank you for consistently staying up to date with Optimizely CMS and Commerce. The Commerce team is preparing to release the first preview of Commerce 15 - fully compatible with CMS 13 (with CMS13 preview4 packages as dependencies) - in about one week. Further details will be shared later. We appreciate your support and patience.

Johan Book
Johan Book Mar 23, 2026 10:40 AM

With preview3 we were fine just by installing EPiServer.CMS and EPiServer.Cms.UI.AspNetIdentity.

But with preview4 there are a bunch of version conflicts that forces us to explicitly install specific packages in a certain order. Just wanted to check if this is intentional?

These packages had to be added explicitly in order to build:

  • EPiServer.ImageLibrary.ImageSharp
  • EPiServer.Framework
  • EPiServer.LinkAnalyzer
  • EPiServer.Cms.AspNetCore.Routing
  • EPiServer.UI

Only after these packages were explictly installed, we could update EPiServer.Cms.

Magnus Rahl
Magnus Rahl Mar 23, 2026 10:56 AM

@Johan this is unintentional. I'll take a task back to the team to investigate. Can you share which dependencies you had in your project before the update so we can try to reproduce it? Do you have multiple projects in the same solution?

Robert Svallin
Robert Svallin Mar 23, 2026 10:56 AM

@Johan that is surprising. This are the dependencies in the csproj file that I have for the Alloy project I have upgraded from CMS 12 templates. Note that I have chosen to Content Manager, DAM integration and Graph. What does your setup look like? Are you running an Alloy template or something else?

<ItemGroup>
  <PackageReference Include="EPiServer.CMS" Version="13.0.0-preview4-pre-51" />
  <PackageReference Include="EPiServer.CMS.UI.AspNetIdentity" Version="13.0.0-preview4-pre-51" />
  <PackageReference Include="EPiServer.Cms.UI.ContentManager" Version="13.0.0-preview4-pre-51" />
  <PackageReference Include="EPiServer.Cms.DamIntegration.UI" Version="13.0.0-preview4-pre-51" />
  <PackageReference Include="Optimizely.Graph.Cms" Version="13.0.0-preview4-pre-51" />
  <PackageReference Include="EPiServer.Cms.UI.VisitorGroups" Version="13.0.0-preview4-pre-51" />
  <PackageReference Include="Wangkanai.Detection" Version="8.7.0" />
</ItemGroup>
  

Robert Svallin
Robert Svallin Mar 23, 2026 11:19 AM

@Johan I removed ContentManager, Dam integration and Graph. And I also cleaned my binary files and the modules folder. After rebuilding everything from scratch it compiles and runs as it should. Looking forward to some more information from you that we can forward to the team looking at this issue.

<ItemGroup>
  <PackageReference Include="EPiServer.CMS" Version="13.0.0-preview4-pre-51" />
  <PackageReference Include="EPiServer.CMS.UI.AspNetIdentity" Version="13.0.0-preview4-pre-51" />
  <PackageReference Include="Wangkanai.Detection" Version="8.7.0" />
</ItemGroup>

Johan Book
Johan Book Mar 23, 2026 12:25 PM

Here are our package references for preview3:

<ItemGroup>
  <PackageReference Include="EPiServer.CMS" Version="13.0.0-preview3" />
  <PackageReference Include="EPiServer.Cms.UI.AspNetIdentity" Version="13.0.0-preview3" />
  <PackageReference Include="Wangkanai.Detection" Version="8.7.0" />
</ItemGroup>

Step1: Trying to bump just EPiServer.CMS gives us the following error:

Version conflict detected for EPiServer.UI. Install/reference EPiServer.UI 13.0.0-preview4 directly to project alloy13preview to resolve this issue. 
 alloy13preview -> EPiServer.Cms 13.0.0-preview4 -> EPiServer.Cms.TinyMce 13.0.0-preview4 -> EPiServer.Cms.Shell.UI 13.0.0-preview4 -> EPiServer.UI (= 13.0.0-preview4) 
 alloy13preview -> EPiServer.Cms.UI.AspNetIdentity 13.0.0-preview3 -> EPiServer.UI (= 13.0.0-preview3).

Step 2: Trying to install EPiServer.UI directly gives us the following error:

Version conflict detected for EPiServer.ImageLibrary.ImageSharp. Install/reference EPiServer.ImageLibrary.ImageSharp 13.0.0-preview4 directly to project alloy13preview to resolve this issue. 
 alloy13preview -> EPiServer.UI 13.0.0-preview4 -> EPiServer.Shell.UI 13.0.0-preview4 -> EPiServer.Shell 13.0.0-preview4 -> EPiServer.ImageLibrary.ImageSharp (= 13.0.0-preview4) 
 alloy13preview -> EPiServer.Cms 13.0.0-preview3 -> EPiServer.ImageLibrary.ImageSharp (= 13.0.0-preview3).

Step 3: Trying to install EPiServer.ImageLibrary.ImageSharp works.

Step 4: Trying to install EPiServer.UI works.

Step 5: Trying to bump EPiServer.CMS again gives us the following error:

Version conflict detected for EPiServer.Shell.UI. Install/reference EPiServer.Shell.UI 13.0.0-preview4 directly to project alloy13preview to resolve this issue. 
 alloy13preview -> EPiServer.Cms 13.0.0-preview4 -> EPiServer.Cms.UI 13.0.0-preview4 -> EPiServer.Cms.UI.Core 13.0.0-preview4 -> EPiServer.Shell.UI (= 13.0.0-preview4) 
 alloy13preview -> EPiServer.UI 13.0.0-preview3 -> EPiServer.Shell.UI (= 13.0.0-preview3).

And so on and so on....

Do note that I use the interactive "Nuget package manager" in Visual Studio, I don't just swap the numbers in the csproj, fwiw.

Phu Nguyen
Phu Nguyen Mar 24, 2026 06:11 AM

Hi @Johan, could you try upgrading both CMS and Cms.UI.AspNetIdentity from preview 3 to preview 4. From your steps, it looks like your Cms.UI.AspNetIdentity is still on the preview3 version

alloy13preview -> EPiServer.Cms 13.0.0-preview4 -> EPiServer.Cms.TinyMce 13.0.0-preview4 -> EPiServer.Cms.Shell.UI 13.0.0-preview4 -> EPiServer.UI (= 13.0.0-preview4
alloy13preview -> EPiServer.Cms.UI.AspNetIdentity 13.0.0-preview3 -> EPiServer.UI (= 13.0.0-preview3).

Manoj Kumawat
Manoj Kumawat Mar 24, 2026 07:58 AM

Is customizing Dojo plugins still a nightmare?

Johan Book
Johan Book Mar 24, 2026 10:21 AM

Thanks! @Phu

Bumping both packages at the same time made wonders! 🎉

Robert Svallin
Robert Svallin Mar 25, 2026 07:11 AM

@Manoj that is an excellent question. I would encourage you to submit it to the Webinar that takes place tomorrow, see Optimizely CMS 13 and Commerce Connect 15 Technical Webinar - Optimizely

Piotr
Piotr Mar 25, 2026 06:58 PM

@Robert Thank you for the heads-up! I am looking forward to the webinar tomorrow and can't wait to submit questions.

Robert Svallin
Robert Svallin Mar 26, 2026 06:19 AM

@Piotr no need to wait to submit. There is a form to submit questions on the invite. You can find it at CMS 13 Technical Webinar. Pre submitted questions will be prioritized.

Please login to comment.
Latest blogs
Optimizely migration from CMS 12 to CMS 13

Upgrading from Optimizely CMS 12 to CMS 13 alongside moving the runtime from .NET 8.0 to .NET 10.0 is far more than a routine version upgrade. It i...

Sanjay Kumar | Apr 24, 2026

Optimizely CMS 13 host(s) management

One of the features I found most impressive is the way Optimizely CMS 13 handles hosts with clear definition and intent. It may sound low level...

Harish Yadav | Apr 23, 2026

Building Opal tools on Optimizely Connect Platform: a Mailchimp walkthrough

About the Mailchimp Opal Tool The  Mailchimp Opal Tool  is an Optimizely Connect Platform app that brings Mailchimp audience operations directly in...

Sanjay Kumar | Apr 22, 2026

📣 Build, Automate, and Scale Content Operations with CMS REST API v1 - now live!

Now available for both CMS13 and CMS SaaS We are excited to announce the  v1 release of our CMS REST API —a major milestone in delivering a stable,...

Kathy Copeland | Apr 21, 2026

Introducing AI Assistant v4 for Optimizely CMS 12 and 13

Epicweb AI Assistant v4.0 adds full support for Optimizely CMS 13 on .NET 10 while staying compatible with CMS 12 on .NET 8, plus new AI Chat tools...

Luc Gosso (MVP) | Apr 20, 2026 |