The Drupal developer’s introduction to Sanity.io (ssr)

Written by Ronald Aveling

Missing Image!

Drupal 7 has maintained its place as the most popular version of Drupal for more than 8 years. It has a market share of more than 60% of all active installs, but after over a decade of active use it will reach its end of life in November 2021. With 600,000+ active installs, it leaves a lot of organisations and Drupal CMS developers in a quandary:

Why upgrading your CMS from Drupal 7 is tricky

At first glance, the notion of upgrading to a newer version of Drupal CMS appears to be a lot less painful than the prospect of migrating to a new CMS. However, that transition may not be as easy as it seems, as upgrading Drupal from a version older than 8 can be tricky and time consuming.

This is because Drupal 9 ushered in a big change to the way version upgrades were handled – it is built on top of Drupal 8, and uses deprecations with dependency updates being optional. However this iterative approach to development only started in version 8, so anyone using a version lower than 8 is looking down the barrel of a series of breaking changes that need to be reconciled before it reaches its end of life next year.

Drupal 7 has significant differences from Drupal 8 and 9. The jump from Drupal 7 to Drupal 9 can be an enormous undertaking. Third-party libraries replaced huge swaths of custom Drupal code. The procedural code was reworked into object-oriented code. The code changes were massive. Upgrading a Drupal 7 site to Drupal 9 will bring it into the new upgrade paradigm, but there's quite a bit of work to do to get there.

– Lullabot

Drupal 8 also introduced the Twig templating engine for theming. Developers of Drupal 7 who are used to PHPTemplate will need to learn a new syntax before rebuilding their themes.

Drupal CMS vs Sanity.io – their similarities and differences

PortableText [components.type] is missing "protip"

Headless vs monolithic architectures. Hosting & delivery

Drupal CMS

A typical Drupal 7 hosting setup involves installing on your own server in a LAMP (Linux, Apache, MySQL, PHP) stack. This stack provides a lot of autonomy if you have an interest in managing everything including your own maintenance and security, but there’s a bit involved in scaling content delivery and achieving optimal website performance due to all the dynamic server requests for page rendering.

Managed CMS hosting platforms like Pantheon and Acquia emerged to shoulder some of the burden of maintenance, performance, and security. These services often include a content distribution network (CDN) to help with faster delivery of static assets. You can also connect a self-hosted Drupal install to 3rd party CDNs like Cloudinary or AWS for asset delivery.

While Drupal was created at a time when Content Management Systems were coupled to frontend rendering workflows in a “monolithic” fashion, in recent years it has evolved to meet a growing demand for “decoupled” or “headless” approaches to content delivery. While headless Drupal is a possibility in some versions of the CMS – in Drupal 7 you have to install additional modules in order to setup a JSON API for decoupled content delivery. Drupal 8 made headless content management easier by including that module in its core package, but the API still requires configuration in order to work.

Sanity

Sanity is a fully decoupled, API-first structured content platform. It doesn’t concern itself with the work of generating websites at all. Instead it focuses on giving editors and developers flexible and intuitive ways to work with content. Sanity exposes that content to real-time APIs so that it can be consumed by any number of publishing and distribution frontends.

While we’re commonly referred to as a headless CMS, we believe our platform goes beyond that definition because: you get real-time collaborative editing out of the box, content structures are truly flexible, and we don’t store rich text as HTML. It's the only CMS that treats content as data.

Illustration: The basic architectural differences between traditional, and headless content management systems, and Sanity.io.

Your content is hosted by Sanity on edge-cached, GDPR compliant cloud infrastructure. We focus on all of the DevOps stuff so that you don’t have to. While you cannot self-host the datastore, you can host your own open source real-time editing environment. Sanity works as a SaaS with generous pay-as-you-go pricing for non-enterprise projects. We provide dedicated infrastructure (including custom domains) on enterprise level plans. If you’ve previously connected Drupal CMS to an API-based media platform like Cloudinary, you can continue to do that (we have a plugin) or use the Sanity’s built-in asset CDN for simplicity’s sake.

Developer experience

Drupal CMS

Drupal developers need to know PHP (for backend, CMS config, and possibly frontend templating), and MYSQL (for DB admin and queries). If you’re after a headless Drupal approach you may also need to know JavaScript in order to use a modern frontend framework like React, Vue, or Angular. Custom content entities (what you often need for headless and multichannel publishing) are assigned to database tables by Drupal – they can be time consuming to query, and come with the additional overhead of needing to understand how Drupal organises your data in order to query effectively.

Sanity

With Sanity, everything is oriented towards JavaScript. The Studio is an open source React app that you can customize with your own React components. Content modeling is all achieved with JavaScript, and your content is made available over APIs in JSON too. This provides a direct and intuitive relationship between the way you structure your content, and how it is queried. You can use GraphQL for queries, or our more powerful alternative GROQ: which lets you get exactly the content you need in any way or form you need it.

Editor experience

Drupal CMS

The core layout of Drupal CMS’s editing interface has not been built with customization in mind: you can't meaningfully map out the the primary interface windows and blocks to support a custom content architecture.

Some voices within the Drupal community would like the editing experience to be more modern and dynamic, and Drupal's founder has acknowledged the problem:

While we made important improvements between Drupal 7 and Drupal 8, the feedback from the Drupal agency owners doesn't lie: we have not done enough to keep Drupal's administration UI modern and up-to-date. This is something we need to address.

– Dries Buytaert, Drupal Founder (source)

To their credit, the Drupal community are working on a better UI experience based on a single page react app (similar to Sanity).

In Drupal 7 it's time consuming to provision user-friendly descriptions at the field level (they have to be tested in local, then manually applied to production separately). Drupal 8 made this easier: developers can add fields, descriptions, and any configuration on the site locally, then export that code and deploy to production. Config version control is a possibility in v8.

Access permissions are one of Drupal CMS’s strengths. It comes with an admin GUI that lets you provision a wide range of editor access permissions based on role and content type. Drupal CMS also includes capable revision history and post scheduling functionalities.

Real-time content collaboration is not a possibility in Drupal core. By default Drupal "locks" content nodes from being edited by another user while you have it open, but you can install a 3rd party module to unlock this behavior.

Sanity

Sanity has a highly customizable editing interface. Dashboards, interface panes, and editing workflows can all be shaped to resonate with the content you’re creating. The Structure Builder API lets you configure how lists, documents, views, menus, and initial value templates are organized in the Sanity Studio. You can also brand the studio to suit your project and use custom icons and fonts to match.

Sanity’s access control offers features similar to Drupal. You can define custom permissions in GROQ. Our history experience is full-featured with one-click restores.

Real-time collaboration is a core Sanity feature. You can watch your collaborator’s keystrokes change as they type from wherever they are in the world. Sanity’s presence feature lets you find where your colleagues are working with a single click.

PortableText [components.type] is missing "newsletterSignup"

Custom Content types

Drupal CMS

Drupal 7 comes with the default content types page and article, but you can also establish your own custom entities. Drupal CMS’s ability to create custom content entities is one of its core strengths, and played a big role in differentiating it from other open source CMS vendors like Wordpress over the last decade. This capability is the reason why many enterprise projects gravitated towards it.

Making adjustments to your content structure, and creating custom types is achieved through a GUI. Administrators add, remove, and modify fields through the dashboard interface. Unfortunately there’s no easy synchronization between your local development environment and production, so the typical approach is to model and test in local, then manually recreate those changes in production. Version 8 introduced YAML which simplified the process of configuring custom types, but it doesn’t include field validation.

Sanity

Sanity ships as a completely blank canvas. There are no content types setup with a clean installation; we don’t even presuppose that you should start out with a page content type.

While the concept of building from scratch may seem a little daunting, having a blank canvas gives you the power to build only what you need (we believe every content project has unique needs), and makes it easier to manage content in the long run.

We also made modeling in Sanity really fast – so if you need to build a page content type all you need is:

// page.js

export default {
  title: 'Page',
  name: 'page',
  type: 'document',
  fields: [
    {
    title: 'Title',
    name: 'title',
    type: 'string',
    required: true
    },
    {
    title: 'Slug',
    name: 'slug',
    type: 'slug',
    },
    {
    title: 'Content',
    name: 'content',
    type: 'array',
    of: [{type: 'block'}, {type: 'image'}, {type: 'callToAction'}]
    }
  ]
}

Content modeling is done in the /schema folder of Sanity studio. Provisioning documents, objects, and fields is all achieved in JSON objects which are referenced from a master schema.js file. We spent a lot of time getting this part right so that structuring data is fast and intuitive, and lets you model content on the fly with your collaborators.

Because Sanity Studio’s config is all handled in JavaScript, you can version control your content model. You can test changes in a local studio environment using the sanity start command, and when you’re ready to push changes to production just run sanity deploy and to get your editors working with the improved schema in a few minutes time.

Drupal CMS modules & Sanity plugins

Drupal CMS

The Drupal developer community has a diverse ecosystem of modules. It’s very common for production installations to include dependencies on a large number of modules in order to meet the unique needs of business. Popular community modules are often merged into future versions of Drupal core to improve the number of things it can do.

Sanity

Sanity has a growing ecosystem of official and community plugins. You can build your own plugins, dashboard widgets and React components. We also made Sanity really flexible so that developers can build unique solutions without the need to rely heavily on plugins maintained by others. Sanity’s API-first approach to content also means that you can connect your content with other API-based services.

Files & images

Drupal CMS

Images and files can be stored and hosted with Drupal 7. Image resizing requires the installation of a separate module. Asset delivery over a CDN needs to be achieved by managed hosting with the likes of Acquia and Pantheon, or integration with a 3rd party CDN service like AWS or Cloudinary.

Sanity

Out of the box, Sanity gives you the ability to host images and files (pdf, mpeg, docx, etc) and deliver them from a global CDN. The image asset pipeline lets you run on-the-fly transformations. You can also crop and focus your subject area across a range of sizes and aspect ratios using the hot-spot feature. If you prefer, you can also connect Sanity.io content with other AP-based asset services like Cloudinary and Mux.

PortableText [components.type] is missing "twitterEmbed"

Rich Text

Drupal CMS

Drupal CMS stores rich text blobs as HTML in a MYSQL database. This decision is a byproduct of Drupal’s original use case as a monolithic CMS for websites - HTML was the most practical solution to rich text storage at the time. HTML is fine when all you do is to deliver content to a web browser, but it’s not an optimal headless CMS storage solution for rich text, because you need to publish content decoupled from the view layer, and to more places than browsers. Parsing HTML into other formats for headless and multichannel applications can be difficult and unpredictable.

Sanity

In order to make Sanity truly multichannel and headless, we designed Portable Text: a JSON based specification for rich text storage. The editing experience has everything you’d expect from a HTML-based rich text editing interface, but with Portable Text you’re not restricted to HTML tags and can apply marks and annotations of any kind. Developers get a more predictable data format to work with that can be applied to any rendering or presentation context.

PortableText [components.type] is missing "twitterEmbed"

Page Builders

Drupal CMS

Drupal 7 core does not include page-building tools. This functionality is achieved by installing a separate module like “Paragraphs”. By comparison, Drupal 8 does include a layout builder which supports custom predefined blocks and real-time rendering.

Sanity

Sanity thinks of page builders as simply an array of types that you can reorder via drag-and-drop.

Drag and drop array behavior in Sanity.io studio

The types can be whatever you like: custom objects that group fields, objects with other arrays in them (like images for a gallery), or references to other documents. Sanity doesn’t come with a set of predefined building blocks, but it’s quick and easy to make what you need. Learn more about page building in Sanity.

Taxonomies and vocabularies

Drupal CMS

Drupal CMS developers set up taxonomies as vocabularies and tags. Each vocabulary can have a series of terms associated with it. You can have an unlimited number of vocabularies and terms, and terms can have hierarchies assigned to them. Tags come in the default installation of Drupal 7, and differ in that they don’t require a predefined list of terms.

Sanity

You may have guessed it by now – Sanity doesn’t come with any default taxonomies 🤓. However you can provide for them in a number of ways. Like Drupal, Sanity lets you architect taxonomies any way you like.

Simple tags and categories can be handled as an array of strings.

// tag field in a document

export default {
  name: 'tags',
  type: 'array',
  title: 'Tags',
  of: [{type: 'string'}],
  options: {
  layout: 'tags',
  },
}

If you want a taxonomy with a predefined list of terms and nothing more you can append a list of terms to it:

// category field in a document

export default {
  name: 'categories',
  type: 'array',
  title: 'Categories',
  of: [{type: 'string'}],
  options: {
  list: [
    {value: 'animal', title: 'Animal'},
    {value: 'vegetable', title: 'Vegetable'},
    {value: 'mineral', title: 'Mineral'},
    ]
  },
}

To reuse this list and control it from one location, you can place that field in an object then you’re free to include that object in any other object or document.

To append other content to your taxonomies you create a document (e.g. category.js) and add the additional fields you need like title, slug, and summary. From there you can have an array of references to that document type from anywhere else in your schema:

// array of refs to category doctype

export default {
  name: 'categories',
  type: 'array',
  title: 'Categories',
  of: [
  {type: 'reference', to: [{type: 'category'}]}
  ]
}

Version updates and backwards compatibility

Drupal CMS

From Drupal 8, version updates are backwards compatible, but upgrading from versions earlier than 8 can be time consuming. Drupal 8 uses Twig for templating. In comparison, Drupal 7 uses PHPTemplate. So if you're upgrading you have to learn a new templating language in addition to rebuilding your themes.

Sanity

All of Sanity’s high-level documented APIs are backwards compatible, and are subject to both statistical validation and exhaustive test suites. The parts of Sanity that use undocumented internal APIs may cause breaking changes, so be mindful of developing critical infrastructure around those parts of the platform.

Sanity Studio is regularly updated to provide improved performance, accessibility, and collaboration features. Studio updates are initiated with sanity update, and there are available pathways to downgrade the studio if you need to.

CMS Migrations

Drupal CMS

Migrating data in Drupal CMS can be time consuming because the data is stored in tables that don’t always have a direct correlation to the custom content types you provision – it’s sometimes hard to know what tables your content ends up in. Drupal CMS stores Rich Text as HTML which can be hard to parse if you need to use that content in a headless fashion, beyond the constraints of a web browser context.

Sanity

Data storage and migration is comparatively simpler in Sanity. All content is stored as JSON from the dataset level, to documents, and all the way through to inline spans. That JSON can be inspected in the Studio so you can view structure and query what you need in order to run migrations and transformations on it.

Sanity.io Studio inspector conducting a search for "headless"

If you decide that Sanity’s not right for you, you can export your datasets with a single CLI command and get everything you need in one file.

Summary

In this guide we discussed how Drupal 7’s upcoming end of life is forcing a lot of Drupal CMS developers to reevaluate the content part of their stack. We presented Sanity.io as an alternative to Drupal 7, and compared their similarities and differences.

How to find out more about Sanity.io

If you’d like to explore Sanity as a possible Drupal CMS replacement, you can:

PortableText [components.type] is missing "starterTemplates"