<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><language>en</language><title>Blog posts by Robert Svallin</title> <link>https://world.optimizely.com/blogs/robert-svallin/</link><description></description><ttl>60</ttl><generator>Optimizely World</generator><item> <title>CMS 13 Preview 4 — Upgrading from Preview 3</title>            <link>https://world.optimizely.com/blogs/robert-svallin/dates/2026/3/cms-13-preview-4--upgrading-from-preview-3/</link>            <description>&lt;p&gt;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 &lt;a href=&quot;/link/401767d8a5e8446db6e213b139618c2d.aspx&quot;&gt;first post&lt;/a&gt; covered upgrading from CMS 12 to Preview 2, and the &lt;a href=&quot;/link/440e06e8b64e4e80aa1b65dc833d9ec2.aspx&quot;&gt;second&lt;/a&gt; looked at the key changes in Preview 3. If you&#39;re following along, pick up where we left off.&lt;/p&gt;
&lt;p&gt;Preview 4 is out. The package bump is easy enough, but there&#39;s an API change around how you resolve the start page that&#39;ll ripple through your code. Here&#39;s what to change and what&#39;s worth knowing about.&lt;/p&gt;
&lt;h2&gt;Step 1: Update Packages&lt;/h2&gt;
&lt;p&gt;Bump your package references from preview3 to preview4:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code&gt;&amp;lt;PackageReference Include=&quot;EPiServer.CMS&quot; Version=&quot;13.0.0-preview4&quot; /&amp;gt;
&amp;lt;PackageReference Include=&quot;EPiServer.CMS.UI.AspNetIdentity&quot; Version=&quot;13.0.0-preview4&quot; /&amp;gt;
&amp;lt;PackageReference Include=&quot;Optimizely.Graph.Cms&quot; Version=&quot;13.0.0-preview4&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;h3&gt;Known Issue: Database Schema Upgrade from Older CMS 12 Versions&lt;/h3&gt;
If you&#39;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:&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code&gt;Column names in each table must be unique. Column name &#39;Failed&#39; in table &#39;dbo.tblNotificationMessage&#39; is specified more than once.&lt;/code&gt;&lt;/pre&gt;
This happens because certain columns were added in later CMS 12 releases, and the CMS 13 migration scripts don&#39;t check whether they already exist before trying to add them.&lt;br /&gt;
&lt;div&gt;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.&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;Step 2: Resolving the Start Page&lt;/h2&gt;
&lt;p&gt;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 &amp;mdash; no need to go through IApplicationResolver in most cases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Before (Preview 3)&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;var website = _applicationResolver.GetByContext() as Website;
var startPageContentLink = website?.RoutingEntryPoint;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;After (Preview 4)&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;var startPageContentLink = ContentReference.StartPage;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the Alloy template this simplified things across several files by using ContentReference.StartPage&amp;nbsp;&lt;br /&gt;- &lt;strong&gt;PageViewContextFactory.cs&lt;/strong&gt; &amp;mdash; CreateLayoutModel&amp;nbsp;&lt;br /&gt;-&amp;nbsp;&lt;strong&gt;ContentLocator.cs&lt;/strong&gt; &amp;mdash; GetContactPages&amp;nbsp;&lt;br /&gt;- &lt;strong&gt;PreviewController.cs&lt;/strong&gt; &amp;mdash; the Index action&lt;br /&gt;- &lt;strong&gt;StartPageController.cs&lt;/strong&gt; &amp;mdash; the Index action&lt;br /&gt;-&amp;nbsp;&lt;strong&gt;Breadcrumbs.cshtml&lt;/strong&gt; and &lt;strong&gt;Header.cshtml&lt;/strong&gt;&amp;nbsp;&amp;mdash; same change&lt;/p&gt;
&lt;p&gt;If you do need more control, IRoutableApplication with its EntryPoint property is still available as an alternative.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;Step 3: DAM Integration (optional)&lt;/h2&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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&#39;ll also need the SSO ID which can be found under &lt;strong&gt;Settings \ Organization \ General&lt;/strong&gt; in CMP.&lt;/p&gt;
&lt;p&gt;The DAM integration no longer talks to the CMP REST API directly. Instead it&#39;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 &amp;mdash; selecting your DAM instance, activating asset types &amp;mdash; follow the same process as CMS SaaS and are documented in the &lt;a href=&quot;https://docs.developers.optimizely.com/content-management-system/v1.0.0-CMS-SaaS/docs/onboard-dam-to-cms-saas&quot;&gt;Onboard DAM to CMS guide&lt;/a&gt;. Updated documentation specific to CMS 13 will be available at release. Once that&#39;s done, Content Manager can be used to discover and pick DAM assets directly from the editing UI.&lt;/p&gt;
&lt;p&gt;Add the package:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code&gt;&amp;lt;PackageReference Include=&quot;EPiServer.Cms.DamIntegration.UI&quot; Version=&quot;13.0.0-preview4&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Register the DAM UI in Startup.cs:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;services.AddDamUI();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add the DAM HTML helpers namespace to Views/_ViewImports.cshtml:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;@using EPiServer.Cms.DamIntegration.UI.Helpers&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives you access to helpers like RenderTagWithMetadata(...) for rendering DAM assets. Note that the epi-property tag helper you&#39;re already using comes from EPiServer.Cms.AspNetCore.TagHelpers, which should already be registered in your _ViewImports.cshtml via @addTagHelper.&lt;/p&gt;
&lt;p&gt;Then configure your CMP credentials (note that these have defaults, included here for transparency) in appsettings.json:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code&gt;&quot;Optimizely&quot;: {
  &quot;Cms&quot;: {
    &quot;DamUI&quot;: {
      &quot;Endpoint&quot;: &quot;https://cmp.optimizely.com&quot;,
      &quot;SsoId&quot;: &quot;&amp;lt;your-sso-id&amp;gt;&quot;,
      &quot;NavigationUrl&quot;: &quot;https://cmp.optimizely.com/cloud/library&quot;
    }
  },
  &quot;Cmp&quot;: {
    &quot;Client&quot;: {
      &quot;TokenUrl&quot;: &quot;https://accounts.cmp.optimizely.com/o/oauth2/v1/token&quot;,
      &quot;ApiUrl&quot;: &quot;https://api.cmp.optimizely.com/v3/&quot;,
      &quot;ClientId&quot;: &quot;&amp;lt;your-client-id&amp;gt;&quot;,
      &quot;ClientSecret&quot;: &quot;&amp;lt;your-client-secret&amp;gt;&quot;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The DAM picker now also supports multi-select, which is a nice improvement for editors working with lots of media.&lt;/p&gt;
&lt;h3&gt;Migrating from CMS 12 DAM Integration&lt;/h3&gt;
&lt;p&gt;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&amp;nbsp;will handle the migration of existing DAM asset references so that they work with the new EPiServer.Cms.DamIntegration.UI package.&lt;/p&gt;
&lt;p&gt;The first version of the migration package will support:&lt;br /&gt;&amp;nbsp; - ContentReference properties&lt;br /&gt;&amp;nbsp; - IList&amp;lt;ContentReference&amp;gt; properties&lt;/p&gt;
&lt;p&gt;Support for additional property types will be added in future releases.&lt;/p&gt;
&lt;h3&gt;Using DAM Assets in Your Content&lt;/h3&gt;
&lt;p&gt;To use DAM assets on a page, add a ContentReference property with the UIHint.Image hint:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;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; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the view, render it with the epi-property tag helper &amp;mdash; same pattern as any other CMS property:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code&gt;&amp;lt;img epi-property=&quot;@Model.CurrentPage.Image&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Step 4: Audiences (optional)&lt;/h2&gt;
&lt;p&gt;Audiences are a separate package in CMS 13. If you were using services.AddVisitorGroups() in Preview 3, you&#39;ll need to add the new NuGet package and update your service registration.&lt;/p&gt;
&lt;p&gt;Add the package:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;&amp;lt;PackageReference Include=&quot;EPiServer.Cms.UI.VisitorGroups&quot; Version=&quot;13.0.0-preview4&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then update your Startup.cs &amp;mdash; the old AddVisitorGroups() call is replaced with two separate registrations:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;using EPiServer.Cms.UI.VisitorGroups;
services.AddVisitorGroupsMvc().AddVisitorGroupsUI();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;What Else Is New in Preview 4&lt;/h2&gt;
&lt;p&gt;A few things worth knowing about beyond the upgrade steps:&lt;/p&gt;
&lt;h3&gt;Graph .NET SDK&lt;/h3&gt;
&lt;p&gt;There&#39;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.&lt;/p&gt;
&lt;h3&gt;Improved Migration from SiteDefinition&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;For the full list of changes, check the official release notes.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/robert-svallin/dates/2026/3/cms-13-preview-4--upgrading-from-preview-3/</guid>            <pubDate>Fri, 20 Mar 2026 12:08:15 GMT</pubDate>           <category>Blog post</category></item><item> <title>CMS 13 Preview 3: Key changes</title>            <link>https://world.optimizely.com/blogs/robert-svallin/dates/2026/2/cms-13-preview-3-key-changes/</link>            <description>&lt;p&gt;If you&#39;ve been following along with the CMS 13 preview, you&#39;ve likely worked through the initial upgrade path covered in my previous post. Preview 3 brings us another step closer to a production-ready release. Based on feedback on Preview 2 we have made changes so that &lt;strong&gt;Content Manager and Optimizely Graph are no longer enabled by default. &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It is however important to understand that: while these features are opt-in from a technical perspective, Optimizely Graph is effectively required if you want to unlock the full potential of CMS 13. &lt;span class=&quot;fabric-background-color-mark&quot;&gt;In practice, we expect most customers to adopt Graph as part of their CMS 13 journey, since many of the platform&amp;rsquo;s most meaningful innovations depend on it. Let&amp;rsquo;s unpack what that means.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;What&#39;s New in Preview 3?&lt;/h2&gt;
&lt;p&gt;Preview 3 includes the usual improvements and bug fixes, but I wont highlight them here but instead refer to the official &lt;a href=&quot;https://docs.developers.optimizely.com/content-management-system/v13-Pre-Release/docs/release-notes-for-cms-13-pre-release-preview-3&quot;&gt;release notes&lt;/a&gt;. What is worth discussing is the change in having Optimizely Graph and Content Manager enabled through opt in.&lt;/p&gt;
&lt;h2&gt;Why Optimizely Graph Matters&lt;/h2&gt;
&lt;p&gt;Several of CMS 13&#39;s new features are built on top of Optimizely Graph. Let&amp;acute;s look at some of the bigger examples:&lt;/p&gt;
&lt;ul class=&quot;ak-ul&quot;&gt;
&lt;li&gt;
&lt;p&gt;Content Manager: The new editorial experience relies on Graph for content discoverability.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;External Content: Integrating content from external sources outside of CMS requires Graph&#39;s indexing capabilities&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Content Binding: The approach to rendering external content leverages Graph&#39;s structured queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class=&quot;fabric-background-color-mark&quot;&gt;RAG for Opal: Graph allows Opal to &amp;ldquo;see&amp;rdquo; and &amp;ldquo;understand&amp;rdquo; your content. Allowing Opal to query all content, understand tone of voice, and more.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, if you&#39;re planning to use any of the new CMS 13 features that differentiate it from CMS 12, you need Optimizely Graph - they wont work without it. At Optimizely, we view Optimizely Graph as a &lt;strong&gt;mandatory&lt;/strong&gt; and foundational component for using CMS 13 to its full potential. Running CMS 13 without Optimizely Graph will be very close to running CMS 12 compiled for .NET 10 with a smaller subset of new features. Over time, Optimizely Graph will increase in usage in CMS 13 and beyond since it is at the very center of functionality that we build.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;fabric-background-color-mark&quot;&gt;For organizations that truly cannot adopt Graph, it&amp;rsquo;s worth carefully evaluating the value of moving to CMS 13 in the near term, since several of the headline innovations will not be available without it.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Is Optimizely Graph required?&lt;/h2&gt;
&lt;p&gt;Let&#39;s be pragmatic about this. You can run CMS 13 without Graph in some scenarios, for example:&lt;/p&gt;
&lt;ul class=&quot;ak-ul&quot;&gt;
&lt;li&gt;
&lt;p&gt;You&#39;re maintaining a CMS 12 codebase with minimal changes during migration&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You&#39;re in the early phases of migration and haven&#39;t yet enabled the new features&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;fabric-background-color-mark&quot;&gt;One example is customers with strict on-prem or data residency requirements where introducing a cloud service is not feasible. That said, many customers who run CMS &amp;ldquo;on-prem&amp;rdquo; Today are already operating in hybrid models (self-hosted in cloud environments, partner-hosted infrastructure, etc.), and in those cases Graph is often still a viable option.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;If you&#39;re upgrading to CMS 13 for its new capabilities, then its likely that you will be adopting Graph. The question probably isn&#39;t &quot;if&quot; but rather &quot;when&quot; in your migration timeline.&lt;/p&gt;
&lt;h2&gt;Enabling Content Manager and Optimizely Graph&lt;/h2&gt;
&lt;p&gt;Since you&#39;ll almost certainly need these features, or at least want to try them out, here&#39;s the straightforward opt-in process:&lt;/p&gt;
&lt;p&gt;Step 1: Add the NuGet Packages&lt;br /&gt;Reference the appropriate packages in your project:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;dotnet add package EPiServer.Cms.UI.ContentManager
dotnet add package Optimizely.Graph.Cms&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Step 2: Update Your Startup Configuration&lt;br /&gt;In your Startup.cs (or wherever you&#39;re configuring services in your Alloy-based project), add the following calls to your service registration:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;public void ConfigureServices(IServiceCollection services)
{
  // ... your existing service configuration
  services.AddContentGraph();
  services.AddContentManager();
  // ... rest of your configuration
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the order matters here: AddContentGraph() should come before AddContentManager() since Content Manager depends on Graph&#39;s infrastructure.&lt;/p&gt;
&lt;h2&gt;My perspective on Graph Adoption&lt;/h2&gt;
&lt;p&gt;Here&#39;s what I am thinking with this change on Opt In approach: Graph isn&#39;t a nice-to-have feature add-on&amp;mdash;it&#39;s a corner stone for content delivery in the Optimizely ecosystem.&lt;/p&gt;
&lt;ul class=&quot;ak-ul&quot;&gt;
&lt;li&gt;
&lt;p&gt;Content Manager gives editors a performant content discovery experience powered by Graph queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;External Content lets you unify disparate content sources through Graph&#39;s indexing&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Content Binding enables developers to work with strongly-typed content models backed by Graph&#39;s schema&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These aren&#39;t isolated features; they are puzzle pieces that tell a joint story. And Graph is the connective tissue that bind them together.&lt;/p&gt;
&lt;p&gt;If you&#39;re building greenfield projects or undertaking significant modernization efforts, I think that you should embrace Graph from day one. Trying to retrofit it later when you want to adopt Content Manager or External Content will be more painful than including it from the start.&lt;/p&gt;
&lt;h2&gt;So, Alloy Template&lt;/h2&gt;
&lt;p&gt;If you&#39;re working with the Alloy template as a learning tool or project foundation, you&#39;ll want to enable both features to get the full editorial experience. The Alloy template shows Content Manager&#39;s capabilities, and Graph powers both its search functionality and the new content delivery patterns.&lt;/p&gt;
&lt;p&gt;This is actually a good learning environment to understand how Graph integrates with the platform before you build your production architecture.&lt;/p&gt;
&lt;p&gt;As always, remember that Preview 3 is not production-ready. Use it for evaluation, experimentation, and preparation&amp;mdash;but keep your production sites on CMS 12 until the official CMS 13 release.&lt;/p&gt;
&lt;p&gt;Happy coding!&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/robert-svallin/dates/2026/2/cms-13-preview-3-key-changes/</guid>            <pubDate>Thu, 19 Feb 2026 13:44:31 GMT</pubDate>           <category>Blog post</category></item><item> <title>From 12 to 13 preview: A Developer&#39;s Guide to testing an Optimizely CMS 13 Alloy Site</title>            <link>https://world.optimizely.com/blogs/robert-svallin/dates/2026/1/from-12-to-13-a-developers-guide-to-upgrading-an-optimizely-cms-alloy-site/</link>            <description>&lt;p&gt;The release of Optimizely CMS 13 marks a significant step forward, embracing a more composable and headless-first architecture. While this unlocks powerful new capabilities, it also introduces important changes to the underlying framework.&lt;/p&gt;
&lt;p&gt;This guide provides a hands-on walkthrough for upgrading a standard CMS 12 Alloy starter site to the CMS 13 preview. We&#39;ll cover dependency updates, code migrations for obsolete APIs, and the new application configuration model.&lt;/p&gt;
&lt;h2&gt;Step 1: Create a Baseline CMS 12 Site&lt;/h2&gt;
&lt;p&gt;First, let&#39;s establish a starting point. Create a fresh CMS 12 Alloy site using the Optimizely templates. This ensures we have a clean, working installation before we begin the upgrade.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;# Create a new Alloy project
dotnet new epi-alloy-mvc -n alloy13preview

# Build and run the site
dotnet build
dotnet run&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;fabric-editor-breakout-mark fabric-editor-block-mark css-p8f2xz&quot;&gt;
&lt;div class=&quot;code-block css-ggxefa&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Once the site is running, register a new user account so you can log in. Verify that the site is fully functional. When you&#39;re ready, shut down the application.&lt;/p&gt;
&lt;h2&gt;Step 2: Update Project Dependencies&lt;/h2&gt;
&lt;p&gt;With our baseline established, the next step is to update the project file and NuGet packages.&lt;/p&gt;
&lt;ol class=&quot;ak-ol&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update the Target Framework&lt;/strong&gt;: Open the .csproj file and change the target framework to&lt;/p&gt;
&lt;div class=&quot;code-block css-ggxefa&quot;&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code&gt;&amp;lt;PropertyGroup&amp;gt;
  &amp;lt;TargetFramework&amp;gt;net10.0&amp;lt;/TargetFramework&amp;gt;
&amp;lt;/PropertyGroup&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update NuGet Packages&lt;/strong&gt;: Update all EpiServer.* package versions to 13.0.0-preview2.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add AspNetIdentity&lt;/strong&gt;: CMS 13 decouples the UI&#39;s identity management. Add a new package reference for EPiServer.CMS.UI.AspNetIdentity.&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;code-block css-ggxefa&quot;&gt;
&lt;div class=&quot;css-9n57oc&quot;&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;&amp;lt;PackageReference Include=&quot;EPiServer.CMS.UI.AspNetIdentity&quot; Version=&quot;13.0.0-preview2&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Step 3: Code Migration and Mitigating Obsolete APIs&lt;/h2&gt;
&lt;p&gt;CMS 13 refactors several core APIs. The compiler will now report a series of warnings and errors related to obsolete members. Let&#39;s work through them.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A Friendly Pro-Tip:&lt;/strong&gt; As you begin the migration, make it a habit to check the compiler warnings in your IDE or build output. These warnings are your roadmap to finding every instance of a deprecated or obsolete API in your specific project. While this guide covers the common changes for the Alloy template, your codebase may have other areas needing attention.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Use ContentReference and ContentLink&lt;/h3&gt;
&lt;p&gt;The PageReference and PageData.PageLink types are now obsolete. This change reflects a broader shift to treat all content more generically. The fix is a straightforward replacement across your solution:&lt;/p&gt;
&lt;ul class=&quot;ak-ul&quot;&gt;
&lt;li&gt;
&lt;p&gt;Replace PageReference with ContentReference.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace .PageLink with .ContentLink.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Replace SiteDefinition with the New Application Model&lt;/h3&gt;
&lt;p&gt;The concept of SiteDefinition is replaced by a more flexible &lt;strong&gt;Application Model&lt;/strong&gt;. An application connects a starting point in the content tree with a specific rendering mode (e.g., &quot;In-Process&quot; or &quot;Headless&quot;) and hostnames.&lt;/p&gt;
&lt;p&gt;To resolve this, you&#39;ll need to inject IApplicationResolver into your controllers and services to get the context of the current application (IApplication).&lt;/p&gt;
&lt;p&gt;Here is an example of how to refactor the StartPageController:&lt;/p&gt;
&lt;div class=&quot;fabric-editor-breakout-mark fabric-editor-block-mark css-p8f2xz&quot;&gt;
&lt;div class=&quot;code-block css-ggxefa&quot;&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;using alloy13preview.Models.Pages;
using alloy13preview.Models.ViewModels;
using EPiServer.Web;
using EPiServer.Web.Mvc;
using Microsoft.AspNetCore.Mvc;
using EPiServer.Applications;
using EPiServer.Shell.Security;
using EPiServer.Web.Routing;

namespace alloy13preview.Controllers;

public class StartPageController : PageControllerBase&amp;lt;StartPage&amp;gt;
{
  private readonly IApplicationResolver _applicationResolver;
  
  public StartPageController(IApplicationResolver applicationResolver)
  {
    _applicationResolver = applicationResolver;
  }

  public async Task&amp;lt;IActionResult&amp;gt; Index(StartPage currentPage, CancellationToken cancellationToken)
  {
    var model = PageViewModel.Create(currentPage);
    var application = await _applicationResolver.GetByContextAsync(cancellationToken);

    var website = application as Website;
    
    if (website is not null &amp;amp;&amp;amp; website.RoutingEntryPoint.CompareToIgnoreWorkID(currentPage.ContentLink))
    {
      // Connect the view models logotype property to the start page&#39;s to make it editable
      var editHints = ViewData.GetEditHints&amp;lt;PageViewModel&amp;lt;StartPage&amp;gt;, StartPage&amp;gt;();
      editHints.AddConnection(m =&amp;gt; m.Layout.Logotype, p =&amp;gt; p.SiteLogotype);
      editHints.AddConnection(m =&amp;gt; m.Layout.ProductPages, p =&amp;gt; p.ProductPageLinks);
      editHints.AddConnection(m =&amp;gt; m.Layout.CompanyInformationPages, p =&amp;gt; p.CompanyInformationPageLinks);
      editHints.AddConnection(m =&amp;gt; m.Layout.NewsPages, p =&amp;gt; p.NewsPageLinks);
      editHints.AddConnection(m =&amp;gt; m.Layout.CustomerZonePages, p =&amp;gt; p.CustomerZonePageLinks);
    }

    return View(model);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You will need to apply a similar pattern to other places in the code that reference SiteDefinition.Current. For SiteDefinition.Current.RootPage, you can replace it with ContentReference.RootPage.&lt;/p&gt;
&lt;h3&gt;Modernize Dependency Injection&lt;/h3&gt;
&lt;p&gt;Service location using InitializationEngined.Locate is obsolete. Instead, use constructor injection to get an IServiceProvider instance.&lt;/p&gt;
&lt;ul class=&quot;ak-ul&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;: context.Locate.Advanced.GetInstance&amp;lt;T&amp;gt;()&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;: Inject IServiceProvider&amp;nbsp;and call serviceProvider.GetRequiredService&amp;lt;T&amp;gt;()&amp;nbsp;In an IInitializationModule, you can access it via context.Services.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Other Small API Changes&lt;/h3&gt;
&lt;ul class=&quot;ak-ul&quot;&gt;
&lt;li&gt;IContentTypeRepository&amp;lt;T&amp;gt;: The generic argument is no longer needed. Change IContentTypeRepository&amp;lt;PageType&amp;gt;()&amp;nbsp;to IContentTypeRepository()&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PageController.PageContext.Page This property is now of type IContent. Update your code to reflect this change.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Step 4: Configuration Updates&lt;/h2&gt;
&lt;p&gt;Next, we need to make a few adjustments in Startup.cs and appSetting.json&lt;/p&gt;
&lt;ol class=&quot;ak-ol&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable Database Compatibility Update&lt;/strong&gt;: In Startup.cs,&amp;nbsp;add the following to allow the database compatibility level to be updated automatically.&lt;/p&gt;
&lt;div class=&quot;code-block css-ggxefa&quot;&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;services.Configure&amp;lt;DataAccessOptions&amp;gt;(options =&amp;gt;
{
    options.UpdateDatabaseCompatibilityLevel = true;
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Content Graph&lt;/strong&gt;: Content Graph is enabled by default in the preview of CMS 13 and cant be disabled. This will likely change in subsequent releases. You must add your credentials to appSettings.json.&lt;/p&gt;
&lt;div class=&quot;code-block css-ggxefa&quot;&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code&gt;&quot;Optimizely&quot;: {
  &quot;ContentGraph&quot;: {
    &quot;GatewayAddress&quot;: &quot;https://staging.cg.optimizely.com&quot;,
    &quot;AllowSendingLog&quot;: &quot;true&quot;,
    &quot;SingleKey&quot;: &quot;INSERT SINGLEKEY HERE&quot;,
    &quot;AppKey&quot;: &quot;INSERT APPKEY HERE&quot;,
    &quot;Secret&quot;: &quot;INSERT SECRET HERE&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Visitor Groups&lt;/strong&gt;: Due to a known issue in the preview, the menu system will not render correctly unless Visitor Groups are installed. Add this to Startup.cs&lt;/p&gt;
&lt;div class=&quot;code-block css-ggxefa&quot;&gt;
&lt;div class=&quot;css-9n57oc&quot;&gt;
&lt;div class=&quot;css-4osl21&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;services.AddVisitorGroups();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Step 5: Fixing the Post-Upgrade 404&lt;/h2&gt;
&lt;p&gt;After making all the changes, run the application:&lt;/p&gt;
&lt;div class=&quot;fabric-editor-breakout-mark fabric-editor-block-mark css-p8f2xz&quot;&gt;
&lt;div class=&quot;code-block css-ggxefa&quot;&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;dotnet run&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You will notice the site returns a &lt;strong&gt;404 Not Found&lt;/strong&gt; error. This is expected. The migrated database still has the old SiteDefinition configuration, which doesn&#39;t align with the new Application Model.&lt;/p&gt;
&lt;p&gt;Follow these steps to fix it:&lt;/p&gt;
&lt;ol class=&quot;ak-ol&quot;&gt;
&lt;li&gt;
&lt;p&gt;Navigate to the CMS admin interface: &lt;code class=&quot;_ca0qyh40 _u5f3m5ip _n3tdyh40 _19bvm5ip _2rkofajl _11c819w5 _1reo1wug _18m91wug _1dqoglyw _1e0c1nu9 _bfhk187e _16d9qvcn _syazi7uo _vwz41kw7 _1i4q1hna _o5721jtm&quot;&gt;https://localhost:5000/Optimizely/CMS&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to &lt;strong&gt;Settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Applications&lt;/strong&gt;. If the page fails to render, clear your browser cache and reload. You will see a default &quot;Headless&quot; application.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the application and click &lt;strong&gt;Delete Application&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click &lt;strong&gt;Create New Application&lt;/strong&gt;.&lt;/p&gt;
&lt;ul class=&quot;ak-ul&quot;&gt;
&lt;li&gt;
&lt;p&gt;Set the &lt;strong&gt;Type&lt;/strong&gt; to &lt;strong&gt;In Process&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select your original Alloy start page as the &lt;strong&gt;Application start page&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Give it a name.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the new &quot;In Process&quot; application you just created.&lt;/p&gt;
&lt;ul class=&quot;ak-ul&quot;&gt;
&lt;li&gt;
&lt;p&gt;In the &lt;strong&gt;Hosts&lt;/strong&gt; section, add a new host with the name localhost:5000&amp;nbsp;and set it as the default.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Your Alloy site should now render correctly on the frontend, and preview in Edit mode will be functional.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Congratulations! You have successfully upgraded your Alloy site to CMS 13. This process highlights the key architectural shifts in the new version, particularly the move to a composable Application Model and modernized APIs. You are now ready to explore the new features and possibilities of Optimizely CMS 13.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important Note&lt;/strong&gt;: The steps outlined in this guide are intended for developers to explore the CMS 13 preview with the Alloy template. This is an incomplete preview, and these instructions are not recommended for use with an actual development project and certainly not a live production site. We will share more as we get closer to the release date of CMS 13.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/robert-svallin/dates/2026/1/from-12-to-13-a-developers-guide-to-upgrading-an-optimizely-cms-alloy-site/</guid>            <pubDate>Fri, 23 Jan 2026 14:21:45 GMT</pubDate>           <category>Blog post</category></item><item> <title>CMP DAM asset sync to Optimizely Graph self service</title>            <link>https://world.optimizely.com/blogs/robert-svallin/dates/2025/2/cmp-dam-asset-graph-self-service/</link>            <description>&lt;p&gt;The CMP DAM integration in CMS introduced support for querying Optimizly Graph (EPiServer.Cms.WelcomeIntegration.Graph 2.0.0) for metadata such as alternative texts. Up until now interaction with Optimizely has been needed when adding this integration from CMP to Optmizely Graph but that is no longer the case. CMP now contains a self service feature where Optimizely Graph can be added and initial synchronization of assets started. This makes it easier to get started and reap the performance benefits of moving from REST API integration with CMP to the more performant Optimizely Graph integration.&lt;/p&gt;
&lt;p&gt;In CMP simply header over to &lt;strong&gt;Settings \ Organization \ Misc&lt;/strong&gt;, scroll to the bottom of the view and hit the &lt;strong&gt;Enable &amp;amp; Sync&lt;/strong&gt;&amp;nbsp;button that you will find there. Once the sync has completed you will find a URL to the Optimizely Graph UI which contains the &lt;strong&gt;SingleKey&lt;/strong&gt; needed to configure CMS.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/ff2c84cbf623455ba306902f5ed5b262.aspx?1739443330051&quot; alt=&quot;Enabling and syncing DAM assets to Optimizely Graph&quot; width=&quot;195&quot; height=&quot;94&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The URL will look something like below.&lt;/p&gt;
&lt;p&gt;&lt;a title=&quot;Optimizely Graph UI with single key&quot; href=&quot;https://cg.optimizely.com/app/graphiql?auth=SINGLE_KEY&quot;&gt;https://cg.optimizely.com/app/graphiql?auth=SINGLE_KEY&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you havent already read about our integration with CMP, either with REST API, or with Optimizely Graph, then please head over to &lt;a href=&quot;https://docs.developers.optimizely.com/platform-optimizely/docs/cmp-dam-cms&quot;&gt;CMP DAM in CMS&lt;/a&gt; to find details on how to get started.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/robert-svallin/dates/2025/2/cmp-dam-asset-graph-self-service/</guid>            <pubDate>Thu, 13 Feb 2025 10:48:51 GMT</pubDate>           <category>Blog post</category></item><item> <title>DAM integration new major version, performance improvements and Library Picker folder selection</title>            <link>https://world.optimizely.com/blogs/robert-svallin/dates/2024/11/dam-integration-new-major-version-performance-improvements-and-library-picker-folder-selection/</link>            <description>&lt;p&gt;As you might already have seen we have decided to delist the EPiServer.CMS.WelcomeIntegration version 1.4.0 where we introduced Graph support. Unfortunately a return type was changed that we didn&amp;rsquo;t catch which means that it became a breaking change. We have decided to delist 1.4.0 and release the performance improvements we have been working on as a new major. We apologize for any inconvenience this has caused and suggest that you either downgrade to 1.3.9 and rely on the CMP API instead of Graph, or upgrade to 2.0.0 instead. We recommend to upgrade to 2.0.0 for the best performance.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The integration between CMS and CMP uses a combination of the CMP Library Picker, in which the editor selects the asset to reference and, either the CMP&amp;acute;s REST API, or indexed assets in Graph. The API or Graph is used to pull metadata regarding the assets such as sizing or alt texts. The integration with REST API has been around for quite some time and the Graph integration was released in the previous version, 1.4.0, and we described how to configure it in &lt;a href=&quot;/link/652f47770cce478882e5e0481d69b6c8.aspx&quot;&gt;this blog post by Bartosz Sekula&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are now releasing a change in how metadata is cached in the CMS for assets referenced from CMP DAM. Moving forward from version 2.0.0 the cache will move to the database and stored permanently. This removes the need for any page request that contain CMP DAM assets to perform outbound network requests to retrieve that metadata when cache has expired.&lt;/p&gt;
&lt;p&gt;The metadata will be fetched for Image assets from CMP when a content that contains references to those images is &lt;strong&gt;published&lt;/strong&gt;. So metadata will be available once the page starts to receive traffic. Please note that fetching the metadata is handled in the background to not block the editor from interacting with the UI. If the images are already referenced by other pages or block then the already existing metadata will be used.&lt;/p&gt;
&lt;p&gt;Should for some reason the metadata not have been populated then the image will still render but with the public URL which was stored the first time the asset was referenced, instead of the latest URL provided by CMP through the metadata.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Renditions&lt;/strong&gt; of &lt;strong&gt;Images&lt;/strong&gt; is a bit different and a topic to which we will return. Currently the renditions for an image asset will render without alt-text. As already stated, we are working on resolving that. The HtmlHelper and TagHelper as well as DamImageAssetViewComponent will still render the correct rendition.&lt;/p&gt;
&lt;p&gt;Example of using HtmlHelper&lt;/p&gt;
&lt;pre class=&quot;language-markup&quot;&gt;&lt;code&gt;@model PageViewModel&amp;lt;StandardPage&amp;gt;
@using EPiServer.Cms.WelcomeIntegration.UI.Helpers

@await Html.RenderTagWithMetadata(p =&amp;gt; p.CurrentPage.Image)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Example of using TagHelper&lt;/p&gt;
&lt;pre class=&quot;language-markup&quot;&gt;&lt;code&gt;@model PageViewModel&amp;lt;StandardPage&amp;gt;
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

&amp;lt;dam-asset content-reference=&quot;@Model.CurrentPage.Image&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Maintaining asset metadata&lt;/h3&gt;
&lt;p&gt;Since the metadata for Images now have moved to the database, how does it get updated? A new scheduled job has been created which will, on schedule, pull metadata from CMP DAM for all assets and update in CMS. This job can be executed manually should the need arise to sync metadata between CMP and CMS.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/7771fed1d3e54efbb6c8f8b4142cecc8.aspx?1732854990499&quot; alt=&quot;The scheduled job for maintaining CMP DAM asset metadata in CMS&quot; width=&quot;834&quot; height=&quot;471&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Metrics from testing scenarios indicate big performance improvements when serving content with DAM assets to visitors.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Asset Library folder selection&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;CMP has the possibility to organize content in folder structures and it is now possible configure either globally or by type which folder to open in the &lt;strong&gt;CMP Library Picker&lt;/strong&gt;. Configuration is done at startup or appSettings as usual.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;.AddDAMUi(o =&amp;gt; {
    o.Enabled = true;
    o.GlobalRootFolderGuid = &quot;a7fd6357c13d49829715f38fe8114c40&quot;;
    o.RootFolderForTypes = new Dictionary&amp;lt;string, IEnumerable&amp;lt;Type&amp;gt;&amp;gt;
    {
        { &quot;57523add60d04e328d7fc1e02c05ed40&quot;, new Type[] { typeof(DAMImageAsset) } },
        { &quot;7bce1de28e66411590ac32896eff2ce1&quot;, new Type[] { typeof(DAMVideoAsset) } },
        { &quot;72b89ab1b83041acaab861a035db7e7b&quot;, new Type[] { typeof(DAMAsset) } }
    };
});&lt;/code&gt;&lt;/pre&gt;</description>            <guid>https://world.optimizely.com/blogs/robert-svallin/dates/2024/11/dam-integration-new-major-version-performance-improvements-and-library-picker-folder-selection/</guid>            <pubDate>Fri, 29 Nov 2024 04:37:35 GMT</pubDate>           <category>Blog post</category></item><item> <title>EPiServer.CMS UI 12.17.0 delisted from Nuget feed</title>            <link>https://world.optimizely.com/blogs/robert-svallin/dates/2023/3/episerver-cms-ui-12-17-0-delisted-from-nuget-feed/</link>            <description>&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;The 12.17.0 version of the UI packages have been delisted from our Nuget feed and is no longer available. We are working on providing a patch, 12.17.1 to correct an issue that affects string properties that use &lt;span class=&quot;classLib&quot;&gt;SelectMany&lt;/span&gt; attribute and a &lt;span class=&quot;classLib&quot;&gt;ISelectionFactory&lt;/span&gt; to handle the available options.&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;The root issue is that the representation of the selected values is now stored in a different way in the database and that needs to be considered a breaking change. We moved from a comma separated list in favor of a Json array. I.e. from &quot;value1,value2,value3&quot; to &quot;[\&quot;value1\&quot;,\&quot;value2\&quot;,\&quot;value3\&quot;] in an effort to try and broaden the capabilities. The change only applies to properties that have been updated and saved to the database since the 12.17.0 upgrade was done on the installation.&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;An installation can be checked if it has been affected by the issue, by running a query against the database to see if the properties store a JSON array or comma separated strings. Please note that only installations using 12.17.0 and that uses properties that are using SelectMany attribute is potentially affected.&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;An example would be that 12.17.0 would store&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11pt; padding-left: 40px;&quot; lang=&quot;sv&quot;&gt;&lt;span class=&quot;classLib&quot;&gt;[&quot;1&quot;,&quot;2&quot;,&quot;3&quot;]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;Instead of the previously used&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11pt; padding-left: 40px;&quot; lang=&quot;sv&quot;&gt;&lt;span class=&quot;classLib&quot;&gt;1,2,3&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li style=&quot;font-family: Calibri; font-size: 11pt;&quot; lang=&quot;sv&quot;&gt;&lt;a href=&quot;/epiui/CMS/Content/support/Bug-list,,149001/bug/CMS-26903?epieditmode=False&amp;amp;epsremainingpath=bug/CMS-26903&quot; title=&quot;CMS-26903&quot;&gt;CMS-26903&lt;/a&gt;&lt;br /&gt;When addressing the issue &lt;a href=&quot;/epiui/CMS/Content/support/Bug-list,,149001/bug/CMS-23405?epieditmode=False&amp;amp;epsremainingpath=bug/CMS-23405&quot; title=&quot;CMS-23405&quot;&gt;CMS-23405&lt;/a&gt; &lt;span lang=&quot;sv&quot; style=&quot;font-family: Calibri; font-size: 11.0pt;&quot;&gt;a breaking change was introduced in how the values for string properties using&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;en-SE&quot; style=&quot;font-weight: bold; font-family: -apple-system; font-size: 10.5pt; color: #272b32; background: white;&quot;&gt;SelectManyAttribute&lt;/span&gt;&lt;span lang=&quot;sv&quot; style=&quot;font-family: Calibri; font-size: 11.0pt;&quot;&gt;&amp;nbsp;and&amp;nbsp;&lt;/span&gt;&lt;span lang=&quot;en-SE&quot; style=&quot;font-weight: bold; font-family: -apple-system; font-size: 10.5pt; color: #272b32; background: white;&quot;&gt;ISelectionFactory&lt;/span&gt;&lt;span lang=&quot;sv&quot; style=&quot;font-family: Calibri; font-size: 11.0pt;&quot;&gt;&amp;nbsp;are stored in the database. A change was made to serialize the selected options as JSON instead of comma separated strings.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;We offer our apologies that this occured and we are sorry that this has affected our customers. For installations that are in the process of migrating to 12.17.0 we ask that you verify if you are affected. Wait for the 12.17.1 version that will arrive shortly and then verify that data is stored correctly.&lt;/p&gt;
&lt;p style=&quot;margin: 0in; font-family: Calibri; font-size: 11.0pt;&quot; lang=&quot;sv&quot;&gt;This blog post will be updated as we move forward with this issue. Thank you for your patience.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/robert-svallin/dates/2023/3/episerver-cms-ui-12-17-0-delisted-from-nuget-feed/</guid>            <pubDate>Wed, 01 Mar 2023 05:30:45 GMT</pubDate>           <category>Blog post</category></item><item> <title>Improving And Unifying The UI</title>            <link>https://world.optimizely.com/blogs/robert-svallin/dates/2022/6/ui-refresh/</link>            <description>&lt;p&gt;&lt;span&gt;We aim to unify and make a seamless user experience across all Optimizely products. This change will make our products more predictable, easy to use, and accessible. T&lt;/span&gt;herefor the CMS in Content Cloud has, over the last few versions (starting with 12.3.0), received multiple updates to the UI.&amp;nbsp; This work is still ongoing, and in the coming weeks/months we expect to release even more updates. However, we wanted to pause and talk a bit about what we have done recently.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with a direct comparison of how the UI has changed during this period. The screenshots below clearly outline the differences.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/e22dea18564b4579a02de912701e2f89.aspx&quot; width=&quot;2844&quot; alt=&quot;A comparison of form edit between 12.7.0 (left) and 12.2.0 (right).&quot; style=&quot;border-style: solid;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: helvetica, arial, sans-serif;&quot;&gt;&lt;em&gt;Image: A comparison of form edit between 12.7.0 (left) and 12.2.0 (right).&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The UI now uses icons from Font Awesome Pro 6, which is a font-based icon library which in turn means that there are fewer resources to download and the icons scale better since they are vector-based. Icons are no longer solid instead, they are outlined, more sharp, crisp, and modern looking. All products from Optimizely use the same set of icons.&lt;/p&gt;
&lt;p&gt;The new icons use the same CSS classes as the old ones did, so for example the home icon still uses the .epi-iconObjectStart CSS class. However, the new icons use a licensed version of Font Awesome 6 Pro, and this limits how the icons can be used. Third-party add-ons and extensions need to use either a free version of Font Awesome 6/equivalent or purchase their license. The new icons have the following sizes, small (16 x 20), medium (24 x 30), and large (32 x 40).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Spacing has also been reworked to introduce more padding to create an improved visual clarity, balancing the layout and making it easier to overview. By introducing more white space into the layout important elements draw the user&amp;rsquo;s attention, allowing the user to focus on call-to-action items and making everything easier to read. In general, alignment has been given an overhaul as well.&lt;/p&gt;
&lt;p&gt;Primary buttons have moved to the right-most side in a button group and the secondary button no longer has a border unless it receives focus or the user hovers on it. This further makes the primary button easier for the eye to catch.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/6f5baee0cc0c464799cea3b323ff351f.aspx&quot; width=&quot;800&quot; alt=&quot;Button placement and disabled state in 12.7.0 (left) and 12.2.0 (right)&quot; height=&quot;808&quot; style=&quot;border-style: solid;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: helvetica, arial, sans-serif;&quot;&gt;&lt;em&gt;Image: Button placement and disabled state in 12.7.0 (left) and 12.2.0 (right)&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Disabled buttons are not transparent anymore. Instead, they have a specific look to them to make sure that they stand out as inactive. For example, a disabled primary button was previously a muted blue that became brighter when enabled. Now the disabled version is instead grey and becomes blue once enabled.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Content Selectors have been reworked to support the user in selecting content without using drag and drop. This was made possible by allowing all content selectors to have a drop-down menu that allows the user to select as well as create content. Drag-n-drop is still present in the UI and the borders of drop zones have been adjusted so that they are coherent and visible.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/b7383116577b428e9e0db0cded611f6c.aspx&quot; width=&quot;1024&quot; alt=&quot;Creating and selecting content in 12.7.0 (left) and 12.2.0 (right)&quot; height=&quot;254&quot; style=&quot;border-style: solid;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: helvetica, arial, sans-serif;&quot;&gt;&lt;em&gt;Image: Creating and selecting content in 12.7.0 (left) and 12.2.0 (right).&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: helvetica, arial, sans-serif;&quot;&gt;Multi-targeting .NET 6 and .NET 5&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;As of EPiServer.CMS.UI 12.4.0 our nugets multi-target both .NET 6.0 and .NET 5.0. EPiServer.CMS.TinyMCE 3.2.0 also supports both as well as EPiServer.Telemetry.UI 2.1.0.&lt;/p&gt;
&lt;p&gt;This was a small selection of the many updates that have been made in the UI and as you upgrade you will discover many more. In the coming versions the team will work on more updates, and we are looking forward to your feedback.&lt;/p&gt;
&lt;h2&gt;&lt;b&gt;New support for tiff files&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;The CMS UI supports tiff files and adds Tiff to &lt;span class=&quot;classLib&quot;&gt;SupportedEditExtensions&lt;/span&gt; list. Currently, tiff is quite an old image extension and It is supported by a few browsers (for example, safari, IE11).&lt;/p&gt;
&lt;h3&gt;What is in the box?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;On Chrome/other browsers users can:
&lt;ul&gt;
&lt;li&gt;Upload a .tiff image&lt;/li&gt;
&lt;li&gt;Open in Image Editor to edit a .tiff image&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;On Safari/IE11 browser users can:
&lt;ul&gt;
&lt;li&gt;Upload a .tiff image&lt;/li&gt;
&lt;li&gt;DnD a .tiff image into Image property (content reference/content reference list/link item collection/URL to (doc,image, page), XhtmlString, Content Area)&lt;/li&gt;
&lt;li&gt;Open a .tiff image on OPE or All properties mode&lt;/li&gt;
&lt;li&gt;Open in Image Editor to edit a .tiff image&lt;/li&gt;
&lt;li&gt;View a .tiff image on View mode&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Known issues&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Thumbnails in Media gadget have a hard-coded content-type (image/png) in CMS Core, and they are not going to change it. That explains why tiff or ico files don&#39;t show thumbnails.&lt;/li&gt;
&lt;li&gt;We only support *.tiff extension. *.tif is not supported&lt;/li&gt;
&lt;/ul&gt;</description>            <guid>https://world.optimizely.com/blogs/robert-svallin/dates/2022/6/ui-refresh/</guid>            <pubDate>Thu, 16 Jun 2022 14:17:55 GMT</pubDate>           <category>Blog post</category></item></channel>
</rss>