CMS 12 - Optimizely DAM Integration 2.2.0
What's New in Optimizely DAM Integration 2.2.0
Version 2.2.0 of the Optimizely DAM (CMP) integration for CMS 12 is a pretty big release. Many of the improvements here come directly from customer feedback and real-world production observations. The result is a more reliable, faster, and more consistent integration across the board.
This release was developed in parallel with CMS 13, and will most likely be the last version to introduce new features for the CMS 12 integration. CMS 13 adopts the SaaS integration model, which works in a fundamentally different way. Going forward, our focus is on the CMS 13 integration. CMS 12 will continue to receive critical fixes, but new feature work will target CMS 13.
A Note on REST API vs Graph Integration
While this release includes improvements to both the REST API and Graph integration paths, Optimizely strongly encourages developers to move to the Graph integration if you haven't already. The REST API integration has inherent performance limitations and implements rate limiting that can result in 429 (Too Many Requests) status codes under heavy use. This becomes particularly problematic in high-traffic production environments where multiple concurrent requests to CMP can trigger throttling.
The Graph integration provides a better alternative. It handles high-volume requests without rate limiting issues, offers better query performance, and scales more effectively for production workloads. While this version continues to address issues in the REST API integration for those still using it, the recommended path forward is to migrate to Graph integration.
Performance: Cached Metadata During Rendering
All rendering helpers now reuse cached metadata from the database. This includes the DAMAssetTagHelper (<dam-asset> tag), HtmlHelpers.RenderTagWithMetadata(), and the new IUrlHelper.DamAssetUrl() extension method. The integration only makes API calls when cached metadata is incomplete, specifically when the URL or MIME type is missing. In typical use cases, metadata is populated during content publishing or by the scheduled maintenance job, which means render-time API calls are eliminated entirely.
For a page with 10 DAM assets, the previous implementation would make 10 separate Graph API calls on each render, adding 500-2000ms of latency depending on network conditions and API load. The cached approach retrieves the same data from the database in under 10ms total. For production sites with high traffic, this typically reduces API calls by 95% or more on steady-state pages.This is probably the change you'll notice most. Previously, the TagHelper and HtmlHelper components made live API calls to CMP Graph every time a page was rendered, even though the metadata was already cached in the CMS database. On high-traffic sites with many assets, this behavior led to SNAT port exhaustion and unnecessary load on the Graph API.
New URL Helper Extension
Version 2.2.0 introduces IUrlHelper.DamAssetUrl() for direct URL generation from cached metadata:
@using EPiServer.Cms.WelcomeIntegration.UI.Helpers
<!-- Basic asset URL -->
<img src="@Url.DamAssetUrl(Model.CurrentPage.HeroImage)" alt="Hero" />
<!-- Specific rendition URL -->
<img src="@Url.DamAssetUrl(Model.CurrentPage.HeroImage, "thumbnail")" alt="Thumbnail" />
The method follows this priority chain:
- Rendition URL (if rendition name provided and exists in cached metadata)
- Main asset URL (from cached metadata)
- IUrlResolver fallback (if metadata unavailable)
- Empty string (if ContentReference is null/empty)
DAM Deep Linking for All Property Types
When replacing an existing DAM asset on a content page, the DAM picker opens with the current asset pre-selected, making it easy to browse related assets or pick a different version. In previous releases, this deep linking only worked for properties backed by a `ContentReference`. Properties that store a URL instead, such as `UrlToImage` or `LinkItem`, would open the picker without any context about the current selection.
The integration now resolves URL-based values server-side before opening the picker. When an editor clicks "replace" on a property that stores a URL, the integration resolves the URL back to a content reference and looks up the corresponding DAM asset. The picker then opens with that asset pre-selected. A small improvement, but one that removes a real friction point for editors working with different property types.
Metadata Consistency Across REST API and Graph
The integration now provides consistent metadata regardless of whether you retrieve asset information through the CMP REST API or Optimizely Graph. Previously, the data available in the CMS database varied depending on the retrieval method, which created inconsistencies in how assets were stored and rendered.
The normalization work ensures that three key metadata properties are now consistently populated from both sources. The
Description field, which was previously only available when using the REST API, is now properly retrieved from Graph as well.
Renditions, alternative asset versions like thumbnails, banners, and other predefined sizes, are now correctly fetched and stored regardless of the data source. Additionally, the
FocalPoint property has been restored. This smart crop coordinate data (X, Y values) was available in the 1.x versions of the integration but had been missing in 2.x releases.
For REST API users, rendition fetching requires explicit configuration. Configure `GetRenditions` to enable rendition data, and optionally GetRenditionsWidthAndHeight to include dimension information:
services.AddCMPRestApi(options =>
{
options.GetRenditions = true;
options.GetRenditionsWidthAndHeight = true;
});
Graph queries are unaffected by these settings and include renditions by default. See the Upgrading section below for additional configuration details.
With Description, Renditions, and FocalPoint now included, the metadata story is complete. The integration covers the full set of properties that will be synchronized from CMP, and no additional metadata fields are planned for future releases.
Document and Video Fixes
Video and document metadata in Graph. The Graph integration now handles all asset types uniformly. In previous versions, retrieving metadata for videos or documents through Graph would result in a null DAMAssetInfo, while the same request through the REST API would return proper metadata including title, MIME type, and URL. This discrepancy has been resolved, and the Graph integration now correctly retrieves and populates metadata for images, videos, and documents alike.
Document rendering. The rendering helpers previously only recognized a hardcoded list of nine application/* MIME types (PDF, Office formats, ZIP) as downloadable documents. Assets with other application/* types fell through to a default case that rendered a <div> with the asset title but no link, making the output non-functional. Text-based documents like CSV or plain text files produced no output at all. This release fixes document rendering so that all document types produce working download links. Text-based documents (text/*) are now explicitly handled, the hardcoded allowlist for application/* types has been removed so all application formats are treated consistently, and the default fallback for any unrecognized MIME type now renders a download link as well.
Rendition Retrieval Fixes
Fixed a bug where Renditions was null when calling IDAMAssetMetadataService.GetAssetMetadata(Guid id) or when stored metadata had no Type value. The metadata service previously only fetched renditions when assetType was explicitly DAMAssetType.Image, but several code paths passed null for this parameter.
The service now fetches renditions regardless of the assetType value.
Asset Tracking Improvements
The asset tracking system has been improved to correctly handle removals from rich text fields. When you removed a DAM asset from an `XhtmlString` field and published the page, the tracking metadata would remain in the database, making it appear that the asset was still in use. The tracking system now properly updates when assets are removed from `XhtmlString` fields, ensuring the `Trackings` field is correctly nullified when assets are no longer referenced.
Upgrading to 2.2.0
Upgrading to version 2.2.0 is straightforward. Update the NuGet packages to version 2.2.0:
dotnet add package EPiServer.CMS.WelcomeIntegration.UI --version 2.2.0
dotnet add package EPiServer.Cms.WelcomeIntegration.Core --version 2.2.0
dotnet add package EPiServer.Cms.WelcomeIntegration.Graph --version 2.2.0
If you're still using the REST API endpoint, consider this a good time to migrate to the Graph integration. The REST API path carries inherent performance limitations including rate limiting that can cause 429 errors under load, and future development efforts will prioritize the Graph integration. The
official documentation covers the migration path.
For REST API users who are not yet ready to migrate and want to retrieve renditions, you'll need to add configuration:
{
"CMPRestApi": {
"GetRenditions": true,
"GetRenditionsWidthAndHeight": true
}
}
After upgrading, run the "Optimizely DAM Maintenance" scheduled job to backfill missing metadata for existing assets. The job will populate Description, Renditions, and FocalPoint data for assets that were created before the upgrade.
Version 2.2.0 closes a lot of gaps that we have received feedback on over time. If you run into issues after upgrading, or if something doesn't behave the way you'd expect, file an issue through Optimizely Support. That feedback is what shaped most of this release, and it will shape what comes next for CMS 13.
Apr 12, 2026
Comments