9

I am aware there are a number of Cache settings for media library items in Sitecore (as described here: Sitecore Implementation - HTML Cache Control Setting options).

However the MediaResponse.MaxAge value stays the same (default is 7 days) even when I publish an update to an image within Sitecore. If I update and image but keep the same name then the cache doesn't expire until 7 days has passed so end-users won't see the updated image straight away unless they clear their browser cache.

I can work-around this by uploading the image with a new name and including the new image in my component instead of the old one. However is there a way to ensure Sitecore clears the cache for updated images without renaming the image?

Further info: Sitecore 8.1 Update 2 and MediaResponse.Cacheability = "public". All other MediaResponse settings set to default.

  • It seems you are looking for Media.AlwaysAppendRevision setting. Take a look at this post for more details. – Reza Aghaei May 19 '18 at 9:23
7

Adding a unique URL parameter will force the browser to request the updated image, as mentioned by both the other answers. You'll also face this same issue if you are using a CDN by the way and using the same technique works well in this situation too. I provided code for an updated MediaProvider in my post about CDNs. This will ensure you don't need to upload the image with a different name and stops the issue of re-linking the image to your components.

Create a new MediaProvider which inherits from the default Sitecore one and override the GetMediaUrl() appending the revision or date property. You only need to append one of these and which one you append is down to preference - both achieve the same goal.

using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Resources.Media;

namespace MyProject.CMS.Custom.Media
{
    public class MediaProvider: Sitecore.Resources.Media.MediaProvider
    {
        public override string GetMediaUrl(MediaItem item)
        {
            Assert.ArgumentNotNull((object)item, "item");
            return this.GetMediaUrl(item, MediaUrlOptions.Empty);
        }

        public override string GetMediaUrl(MediaItem item, MediaUrlOptions options)
        {
            Assert.ArgumentNotNull((object) item, "item");
            Assert.ArgumentNotNull((object) options, "options");

            string mediaURL = base.GetMediaUrl(item, options);

            mediaURL = Sitecore.Web.WebUtil.AddQueryString(mediaURL, new string[] {"revision", ((Item)item).Statistics.Revision });
            //OR, you only need one of these
            mediaURL = Sitecore.Web.WebUtil.AddQueryString(mediaURL, new string[] {"modified", ((Item)item).Statistics.Updated.ToString("yyyyMMddHHmmss") });

            return mediaURL;
        }
    }
}

And then create a config patch to use the new provider.

<mediaLibrary>
  <mediaProvider>
    <patch:attribute name="type">MyProject.CMS.Custom.Media.MediaProvider, MyProject.CMS.Custom</patch:attribute>
  </mediaProvider>
</mediaLibrary>

The URLs generated for the media items should now be in the format /-/media/path-to/image.png?la=en&h=123&w=123&hash={hash}&modified=20170817134500

| improve this answer | |
  • 1
    Cheers JammyKam, what you and Mark said is a good idea around unique URL generation on updates. This is what I'll go for though as I already have a custom media provider so adding in for datetime it was updated like your examples should be simple :) – Adam Seabridge Aug 17 '17 at 17:55
5

There is a Media.AlwaysAppendRevision setting in Sitecore.config. If the setting set to true then Sitecore appends media item revision number to the media URLs generated by LinkManager.

You can set it to true in Sitecore.config:

<setting name="Media.AlwaysAppendRevision" value="true" />

Example

If you create the medial url this way:

<%=Sitecore.Resources.Media.MediaManager.GetMediaUrl(item)%>

Then the result will be:

http://example.com/-/media/Default-Website/item.ashx?rev=04951d8eb3934adbbe42ec1c595768dd

Above result has been gained using the following configurations:

<setting name="Media.AlwaysIncludeServerUrl" value="true" />
<setting name="Media.AlwaysAppendRevision" value="true" />
<setting name="Media.MediaLinkServerUrl" value="http://example.com" />
| improve this answer | |
  • Nice, great catch and good to see this available OOTB now. FYI, this is available since Sitecore 8 update-6. – jammykam May 19 '18 at 20:49
  • 2
    @jammykam Thanks for the feedback :) just to be more precise, it's been added since Sitecore 8.2 rev. 170728 (AKA update 5). – Reza Aghaei May 22 '18 at 6:55
  • You're right, it is update-5. – jammykam May 22 '18 at 13:34
  • 2
    Be aware of this issue related to that setting: github.com/sitecoresupport/Sitecore.Support.219261/releases – josedbaez Nov 19 '18 at 11:11
3

The problem is that the cache in this case is the browser cache, so the cache expiration for the image was set when the image file was originally retrieved. So there's no way for the browser to know that a new file was published.

Only easy way to do this, is if you are willing to drop the 7 day browser cache period to a smaller duration, like 1 second. This makes Sitecore set Cache-Control: max-age and Expires headers of the HTTP response for media request to 1 second. So basically, when the user reloads the page, the image in the browser cache has expired. But this means that there's basically no caching of images.

You could build somekind of extension where you add a query string parameter with a hash based on the image file for every image. Replacing the image, would therefore change the hash, which means the browser would request the new image. Basically buildling the same mechanism used by JavaScript and CSS bundling.

Links: https://kb.sitecore.net/articles/218124

| improve this answer | |
  • Thanks Javi. That makes sense. I did think about adding a custom id to the image URL but wasn't sure if I could avoid this or not. Seems like I can't. – Adam Seabridge Aug 17 '17 at 17:53
2

Jarmo's answer nails it - Sitecore cannot force a new version of the image to be downloaded, when the browser simply never requests it.

One thing you could do, however, short of disabling caching as suggested by Jarmo (and I would add, I would not recommend this approach at all). If you incorporate the Revision field into your Media Urls (you would need to override/extend the MediaManager for this) - a new Url would be generated for your image, even if you just change the media. Revision gets a new stamp every time the item updates.

That would work you around the caching issues, and not give you the hassle of uploading new media side by side and relinking content.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.