Media url in the content editor - Edge ready

Created: 27 Nov 2023, last update: 3 Oct 2024

Tech guide: How to create a URL for your media file in the content editor

This blog is about offering a simple and user-friendly way for the content editor to retrieve the media URL through a content editor warning in Sitecore XM Cloud or Sitecore XM/XP.

We're using the editor warning

I am a big fan of the content editor warning, especially now with Sitecore PowerShell Extensions (SPE) or with the rule engine, there is no longer a need for file deployment to add a new content editor warning; it can all be done through items in the content tree. Sitecore PowerShell Extensions is available out of the box in Sitecore XM Cloud and Sitecore with SXA.

Let's say I want to use a media, such as a .pdf document or an image uploaded in the Sitecore XM Cloud or Sitecore XP media library, in an external location. Think of a QR code or other online or offline applications outside the Sitecore environment. What is the URL to this media in Sitecore? And can the media continue to work if I upload a new version, change the name, or move the media within the Sitecore media library? Can I automatically scale the media to the desired size?

Retrieve your URL using a DAM

The best solution is to use a Digital Asset Management (DAM) system. For example, Sitecore Content Hub Public links are suitable for this purpose. That doesn't mean Sitecore XM Cloud without Content Hub can't do it. The trick is to give the content editor easy access to the MediaManager API to generate a URL. Then you can choose to scale as desired, especially if you have media protection enabled, which is typical for Sitecore XP without Edge but not default for XM Cloud. You need to use the MediaManager to generate a hash when scaling with media protection. When generating the URL, you can also choose to set UseItemPath to false; then, you get a URL with a GUID so that you can rename or move the underlying media without changing the URL. However, this only works for URLs served by Sitecore CMS. If published to Sitecore Edge, only the Edge URL based on the path works. Sitecore Edge supports scaling, so you can include parameters like width and height.

Retrieve your URL in Sitecore XP

For Sitecore XP without Sitecore Edge, you can retrieve the URL, including the hostname of media, by generating it under the desired site context. However, when using Sitecore Edge, the complete URL is not easily obtainable. Yes, it can be done through an Edge GraphQL query, you will get an URL like this: edge.sitecorecloud.io/{instance name}}-{hex number 4 digits}/media/Project/PLAY/playwebsite/media/img/bicycleactionbw.jpg?h=333&w=500

Where the hostname, instance name, and an additional 4-digit hex number seem constant for a Sitecore instance, followed by the logical path in the Sitecore tree. With this logic, you can build the media URL, which works as long as the logic remains the same in Edge, but you have no control over that it is SaaS. So, with Edge, the ability to get the media URL by ID from the Sitecore MediaManager has also come to an end.

We can create a content editor warning or, better, a blue informational message about what the media URL is with this information. I choose to hardcode the Edge URL for now, which may be incorrect or break if Sitecore updates, but as of now, I don't know of any simple solutions.

The PowerShell Script

In the PowerShell Script Library inside Sitecore. Create a new module with Content Editor Warning Integration point.

powershell item media url

Past the script below in the Script body Field and Create Enable Rule for the location inside the media library where you want this media URL info message. Adjust the edge URL in the code. Adjust the code if you want to scale the image, change the MediaUrlBuilderOptions as desired.

  function Get-MediaUrlOptions() {
  #Adjust to the desired website (with names for XP and multiple host names), for example playwebsite or use website for default.
  $siteContext = [Sitecore.Sites.SiteContext]::GetSite("website");
  $muobj = New-UsingBlock(New-Object Sitecore.Sites.SiteContextSwitcher $siteContext) {
  New-Object Sitecore.Links.UrlBuilders.MediaUrlBuilderOptions
  }
  $muobj.AlwaysIncludeServerUrl = 1
  $muobj.UseItemPath = 0
  return $muobj
  }
  function Get-MediaUrl($item, $muo) {
  $siteContext = [Sitecore.Sites.SiteContext]::GetSite("playwebsite");
  $result = New-UsingBlock(New-Object Sitecore.Sites.SiteContextSwitcher $siteContext) {
  [Sitecore.Resources.Media.MediaManager]::GetMediaUrl($item,$muo)
  }
  return $result
  }
   
  $item = Get-Item -Path .
  [Sitecore.Links.UrlBuilders.MediaUrlBuilderOptions]$muo = Get-MediaUrlOptions
  $muo.UseItemPath = 0
  $muo.AlwaysIncludeServerUrl = 1
  $guidmedia = Get-MediaUrl $item $muo
  $muo.UseItemPath = 1
  $nicemedia = Get-MediaUrl $item $muo
  $muo.AlwaysIncludeServerUrl = 0
  $nicemediaPath = Get-MediaUrl $item $muo
  $edgemediaPath = $nicemediaPath.Substring(2)
   
  #Adjust to the desired environment, note: we build the likely url, if media is published to edge,
  $edgemedia = "https://edge.sitecorecloud.io/uxbee-playsummitd0101-demo-f1a0$edgemediaPath"
   
  $icon = $PSScript.Appearance.Icon
  $iconUrl = [Sitecore.Resources.Images]::GetThemedImageSource($icon)
  $title = "Media URL"
  $text = "This item has internal URL $nicemedia<br>Or without path: $guidmedia<br>Edge url <a href='$edgemedia' target='_blank'>$edgemedia</a>"
   
  $warning = $pipelineArgs.Add()
  $warning.Title = $title
  $warning.Text = $text
  $warning.Icon = "/sitecore/shell/themes/standard/Images/information.png"
   
  $warning.HideFields = $false

References