Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Thomas Grant 5 posts 95 karma points
    1 week ago
    Thomas Grant
    0

    Umbraco Headless static site media urls.

    Hi,

    I have a .net core static route site, that is using using headless to get some content, this content is for locations, each node has a name, address, lat/long and some "promo images". I am having a major issue getting media items, that are using the media picker in the back office. I can add images to the node just fine, but when I access the node through code, all the image urls are relative, so I can't display them.

    Has anyone solved this issue with headless? Does the site need to be a content managed site (with umbraco urls) for this to even be possible? The site is an Angular SPA, with umbraco headless being used just for content, and not to define url structure. Attempting to change the site to use umbraco urls is not something that can be considered.

    Regards,

    Edit

    Here is the code grabbing the content from the headless instance,

    var location = (await publishedContentService.GetAll<Location>()).FirstOrDefault(x => x.ExternalID == locationId);
    foreach(var promo in location.PromoImages) //PromoImages is IEnumerable<ContentItem>
    {
       //promo.Url exists, but is relative. e.g '/media/1001/image.png'
       var image = await mediaService.GetById(promo.Id);
    
      //image, of type MediaItem, has no url property.
    }
    

    this object has a collection called PromoImages, each of these is only showing a relative Url.

  • Craig Mayers 164 posts 505 karma points
    1 week ago
    Craig Mayers
    0

    Hi Thomas,

    Would've been handy to see the code you're using to fetch the media items...

    Having you tried using the .UrlAbsolute() extension method that is part of the PublishedContentExtensions ?

    For example:

    var fullMediaItemPath = Umbraco.TypedMedia(1234).UrlAbsolute();

    1234

    Would be the media node ID from your picker.

    Thanks

    Craig

  • Thomas Grant 5 posts 95 karma points
    1 week ago
    Thomas Grant
    0

    Unfortunately the .net core Headless client API doesn't have the Umbraco helper I would expect. There is no Umbraco.TypedMedia in the API at all. There is only the PublishedContentService and MediaService, neither of which will give me an absolute Url.

  • Thomas Grant 5 posts 95 karma points
    1 week ago
    Thomas Grant
    100

    The missing piece of the puzzle was the Umbraco HeadlessConfiguration.

    Instead of creating services like this

    public MyService : IMyService {
         private readonly PublishedContentService publishedContentService;
         private readonly MediaService mediaService;
    
        public MyService(PublishedContentService publishService, MediaService mediaService)
        {
            this.publishedContentService = publishedContentService;
            this.mediaService = mediaService;
        }
    }
    

    Pass over the IHeadlessConfiguration, the settings are in appsettings.json. It's called ImageBaseUrl.

    Add the following to Startup.cs

    services.AddSingleton<IHeadlessConfiguration, HeadlessConfiguration>();
    

    Then change the service layer to:

    public MyService : IMyService {
         private readonly PublishedContentService publishedContentService;
         private readonly MediaService mediaService;
         private readonly IHeadlessConfiguration configuration;          
    
        public MyService(IHeadlessConfiguration config)
        {
            this.publishedContentService = new PublishedContentService(config);
            this.mediaService = new MediaService (config);
            this.configuration = config;
        }
    }
    

    When accessing the media, the url will still be relative, but now we have the base url, so we can build the url ourselves.

    public async Task<Location> GetLocationByIdAsync(int locationId)
        {
            var query = Query.Where.Property(nameof(Location.locationId)).EqualTo(locationId);
            var location = (await publishedContentService.Query<Location>(query)).FirstOrDefault();
            if(location != null ) 
            {
                location.ImageUrls = location.PromoImages.Select(x => $"{configuration.ImageBaseUrl}{x.Url}");
            }
    
            return location;
        }
    
Please Sign in or register to post replies

Write your reply to:

Draft