Take the community feedback survey now.

PuneetGarg
Oct 15, 2024
  78
(0 votes)

Headless with Content Delivery API

Hello Everyone,

This blog will help anyone who wants to start or build an architecture of headless using content delivery api.

When we shifted to headless CMS 12 my first question was how content would be fetched from the front end (I know we have direct API's for them) it's about the building JSON for those pages or blocks.

So I'll share my code experience step by step (I'm taking an example of a page but we can do the same for blocks)

  1. Create a normal Page Type.
  2. Now how will your compiler know which page it has to run we are not directly calling it from view to controller as we are used to it in normal architecture so for that we will create ApiFilters(it will run all every call)
    • Register that Api Filter as Singleton like this  _services.AddSingleton<IContentApiModelFilter, ProductCollectionPageApiModelFilter>();
    • Inside your filter, you need to check if the current request matches your type If not return and do nothing.
    • If it matches your type then we need to create custom code to add our contentarea to our JSON results for that we will create a method where we will do our filtering and binding our model that will be passed in JSON.
    • public void AddContentAreaItemsToContentApiModel(string key, ContentArea contentArea, ContentApiModel contentApiModel)
      {
          var items = new Dictionary<string, object>();
      
          if (contentArea == null || contentArea.FilteredItems == null)
          {
              contentApiModel.Properties.Add(key, items);
              return;
          }
      
          var Filtereditems = contentArea.FilteredItems;
          var index = 0; //Will be appended to the item name in the contentApiModel to prevent duplicate keys in case we have multiples of the same block type 
      
          foreach (var contentAreaItem in Filtereditems)
          {
              _contentLoader.TryGet<IContent>(contentAreaItem.ContentLink, out var content);
      
              if (content == null)
                  continue;
      
              switch (content)
              {
                  // all blocks and pages that will be there in the content area create a case for it like this 
                  case PageType x:
                      {
                          items.Add(nameof(PageType ) + "_" + index, _commerceViewModelBuilder.GetPageDetails(x));
                          index++;
                          break;
                      }
                  default:
                      {
                          index++;
                          break;
                      }
              }
          }
      
          contentApiModel.Properties.Add(key, items);
      }
             
    • this filter will create a key-value pair which will be our JSON result.
    • GetPageDetails -> method that will accept that type and create the model we want to add.
  3. Add this method to our Page type filter, and call your content area in that to filter all things example 
      public class PageApiModelFilter : ContentApiModelFilter<ContentApiModel>
        {
            public override void Filter(ContentApiModel contentApiModel, ConverterContext converterContext)
            {
                try
                {
                    if (!_contentLoader.TryGet(converterContext.ContentReference, out ProductCollectionPage productCollectionPage) || productCollectionPage is not ProductCollectionPage)
                    {
                        return;
                    }
                   
                    AddContentAreaItemsToContentApiModel(nameof(productCollectionPage.TopContentArea), productCollectionPage.TopContentArea, contentApiModel);
                    AddContentAreaItemsToContentApiModel(nameof(productCollectionPage.MainContentArea), productCollectionPage.MainContentArea, contentApiModel);
                    AddContentAreaItemsToContentApiModel(nameof(productCollectionPage.BottomContentArea), productCollectionPage.BottomContentArea, contentApiModel);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
      

4. Now you can call your API from the front end using ID or any other means and in JSON you will have all data that was serialized.

If you want to remove extra data pre and post serialization you can refer to my other blog here is the link https://world.optimizely.com/blogs/puneetgarg/dates/2024/9/remove-unwanted-properties-for-headless-implementation-using-content-delivery-api-/

Hope that helps!

Thank you 

 

Oct 15, 2024

Comments

Please login to comment.
Latest blogs
A day in the life of an Optimizely OMVP - Opticon London 2025

This installment of a day in the life of an Optimizely OMVP gives an in-depth coverage of my trip down to London to attend Opticon London 2025 held...

Graham Carr | Oct 2, 2025

Optimizely Web Experimentation Using Real-Time Segments: A Step-by-Step Guide

  Introduction Personalization has become de facto standard for any digital channel to improve the user's engagement KPI’s.  Personalization uses...

Ratish | Oct 1, 2025 |

Trigger DXP Warmup Locally to Catch Bugs & Performance Issues Early

Here’s our documentation on warmup in DXP : 🔗 https://docs.developers.optimizely.com/digital-experience-platform/docs/warming-up-sites What I didn...

dada | Sep 29, 2025

Creating Opal Tools for Stott Robots Handler

This summer, the Netcel Development team and I took part in Optimizely’s Opal Hackathon. The challenge from Optimizely was to extend Opal’s abiliti...

Mark Stott | Sep 28, 2025

Integrating Commerce Search v3 (Vertex AI) with Optimizely Configured Commerce

Introduction This blog provides a technical guide for integrating Commerce Search v3, which leverages Google Cloud's Vertex AI Search, into an...

Vaibhav | Sep 27, 2025

A day in the life of an Optimizely MVP - Opti Graph Extensions add-on v1.0.0 released

I am pleased to announce that the official v1.0.0 of the Opti Graph Extensions add-on has now been released and is generally available. Refer to my...

Graham Carr | Sep 25, 2025