Headless CMS Integration

by Jarrett Retz December 15th, 2019

At the end of this project I was able to;

  • improve editing experience for content
  • implement a customized editor
  • make publishable content more accessible
  • improve user experience by adding better navigation of content within site

It's obvious that I post articles on the site sometimes because you're reading one right now! However, the editing experience was poor and I sometimes have the same content on my business site as well as my personal blog. I was rendering the content with a Django backend editor that was structured with Markdown. This was less than ideal editing. With the plan to recreate my blog in the future, and the opportunity to explore content management systems, I chose to improve my publishing and programming efficiency.

I researched 3-4 headless-CMS providers and chose Sanity.io for the project. Sanity provided a customizable editing portal, real-time editing, and GraphQL-like query language that allows for more concise HTTP requests. Sanity is geared more towards Javascript runtimes and frameworks, so I had to change the way the data was provided to the Django template.

Furthermore, the data is returned in 'blocks', which means that it is not structured HTML. It provides information for identifying how to create HTML from the object. Fortunately, Sanity has a "blocks-to-html" NPM package.

Unfortunately, the website backend is Python and the NPM package is Javascript. I had a quick fix in mind.

I have experience using Azure (Microsoft's cloud computing platform), and I was able to create a serverless function that retrieves and converts the block data to HTML. The NPM package also allows the serializers to be tweaked so I was able to present code properly, and provide 'alt' attributes for images. The query language that Sanity uses was designed for precise queries that remove the necessity to destructure objects in the backend when the data is queried in bulk. It was fairly simple to add another section to the website that displays just the title, main image, and date (just below this content!).

I remain enthused as to what headless-CMS's can provide.

If interested, I provided the code for adding the "alt" attribute to the <img> tag because it's important to be able to have that rendered on the page.

Create "Alt" field to input text for attribute.

// blockContent.js

...
  {
    type: 'image',
    options: {hotspot: true},
    fields: [
      {
        title: "Alt",
        name: "alt",
        type: "string",
        options: {
          isHighlighted: true // <-- make this field easily accessible
        }
      }
    ]
  }
...

Modify the serializer while using the sanity "block-content-to-html" NPM package.

// This is only a small addition to the code already provided at
// https://github.com/sanity-io/block-content-to-html in conjunction
// with the field addition above.

const serializers = {
...
    image: props => (
        h('figure',
         h('img', {alt: props.node.alt}, {src: getImageUrl(props)})
        )
    )
  }
}