Preview Anything: Introducing Views and Split Panes

Written by Even Westvang, Knut Melvær

Starting with this release you can add multiple views to a single document in Sanity Studio. You can open several of them at the same time with Split Panes. This allows you to build richer and more advanced authoring experiences. It lets you add custom previews, metadata , and other ways of seeing your documents in context. Just using React components. Upgrade your Studio(s) to the latest version, check out the new documentation, and explore our example studio featuring a wide array of previews.

With the release of Structure Builder we found a good pattern for how you can customize and design great authoring experiences that evolve from simple structures to more advanced ones. Today we’re announcing additional features that takes this pattern even further.

Out of the box the Sanity Studio will list out document types, the documents themselves, and the forms for the selected document in panes. The panes are mobile responsive and can be collapsed. But often you want more control over how documents are grouped, and you want to accommodate different workflows, where you want to access the same document, but through different routes.

PortableText [components.type] is missing "ui.screenshot"

That’s why we made Structure Builder as a way of giving you full flexibility over how documents are listed in these panes. It allows you to make everything from a studio that only shows a form for one specific document, to a Studio that renders custom document lists from real-time events. Structure builder also allows you to set up editorial workflows by grouping documents based on their values.

We have now added more methods to the Structure Builder API that allows you to define a set of Views for how each document is rendered within its pane. Currently, a view can either be the default form, or any React-component you specify. The latter receives props, including the document in its draft, published, historical, and displayed state. This makes it possible to more easily create customized authoring experiences using the real-time data that already flows through the Studio.

The technical possibilities aside, this a good occasion to talk about something we have thought about for a while: Previews.

Rethinking previews

Most CMSs with “live preview” functionality let you resolve to an external URL, or tap into a built-in templating engine. Some also solve this by creating a What You See Is What You Get (WYSIWYG) authoring experience. This makes total sense when your content is modelled around a very specific presentation. But that's also the cost: You end up with content tied to a certain presentation. And instead of organizing content around what it actually means, you end up tying it to the pages it's stuck on right now.

Structured content increases the value of your text, images, and other media, by unlocking them from specifics. It also comes at a slightly higher level of abstraction, and some new ways of working. It makes less sense to accommodate for inline WYSIWYG editing experiences for example as your website is probably sharing content between different presentations.

Even if you are using Sanity.io mainly as a website backend, you are probably reusing the same content across different pages and components. Or perhaps more importantly: retain the freedom to rework your content into new presentations later.

Previews are a way for the authors and editors to get a sense of not only how their work is presented, but more importantly, perceived. We think of preview as “empathy portals”, as tools that make authoring easier by letting you relate to the user experience.

Looking at previews this way forces the question: Why should previews then be restricted to just a web preview? If your content will end up in different places in front of different people, shouldn’t that inform how we accommodate previews in the CMS? Content strategists such as Karen McGrane and Jeff Eaton raised this question over half a decade ago, but it still seems to us, that previews are mostly thought of in terms of seeing how changes look like on the website. At least, there is where the current innovation and energy goes.

We want to broaden and challenge the established ideas of what previews in a CMS can be. So we made an array of examples of different previews that we hope can be of use and inspiration.

And of course, we'll start with the obvious example, just to get that out of the way.

Web previews

Say you want a live preview of a web page you're editing for. You can have that. Here we're using a Gatsby frontend. First, sign up for Gatsby Preview (if you have used our source plugin, it should work out of the box). Enable watchMode and add a read token. Now you’ll have low-latency real-time preview in the cloud. You can check how it's done in our example studio on GitHub.

Here's a minimal example using Structure Builder:

import S from '@sanity/desk-tool/structure-builder'

// Simple example of web preview
const url = 'https://yourDomain.gtsb.io/projects/'
const WebPreview = ({document}) => {
  const {displayed} = document
  return (
    <iframe 
      src={url + displayed.slug.current} 
      frameBorder={0} 
    />
  )
}

export const getDefaultDocumentNode = ({schemaType}) => {
 // Conditionally return a different configuration based on the schema type
 if (schemaType === "project") {
   return S.document().views([
     S.view.form(),
     S.view.component(WebPreview).title('Web')
   ])  
 }
}

export default S.defaults()
PortableText [components.type] is missing "muxVideo"

SERP and social

If you think about it, the first place where most of your audience encounters your content isn’t actually your website, it’s in search and on social. When your content is presented in search results and as social media cards, there are other constraints in play, that can be harder to control. That can be how many characters you have available, or the cropping of the image connected to your content. In the example-studio you’ll find some simple components to preview how content looks like on Google, Twitter, and Facebook. You can borrow this code from the example Studio on GitHub.

PortableText [components.type] is missing "muxVideo"

Accessibility previews

Thinking about previews in terms of empathy and user experience made us think of accessibility. People bring with them different capabilities and have different challenges, and when it comes to perception, it’s easy to forget the challenges you yourself don’t have. So we made three examples to highlight this:

A preview that lets you simulate how your website looks like for people with different types of colorblindness.

PortableText [components.type] is missing "muxVideo"

A preview that lets you select a text field from your document and use the in-browser speech synthesis to mimic screen readers.

PortableText [components.type] is missing "muxVideo"

A preview that gives you a visual representation of a field in Braille. This is of course, not that useful for people that depend on Braille. Our hope though, is that efforts like those presented in this talk by Theodore Vorillas can help bridge the gap and make Braille-preview on physical interfaces more accessible.

PortableText [components.type] is missing "muxVideo"

Go and explore the code for the accessibility previews on GitHub.

IRL previews

We already have customers that use content from Sanity APIs digital signage, kiosks, interactive and installations. Why not give your editors an approximation of how their work is presented in these settings?

With a bit of CSS and matrix calculus we made a component that lets you map content into real world settings. Again, it underscores that you design content for scenarios with different constraints.

PortableText [components.type] is missing "muxVideo"

The code for IRL previews on GitHub.

Structured content isn’t just used in digital channels! OMA uses content from Sanity to print books at their in-house publishing. Others have used it to make a pizza recipe book. And we know of other organizations that consume content from Sanity.io into a PDF-generator used to produce printed material.

We wanted to make a simple example for this as well and set up a service on Zeit’s Now that lets us run Puppeteer (headless Chrome) in a serverless function. Then we could design a business card using HTML and CSS, and produce not only previews of how the cards would look like on the fly but also the actual PDF. That you can download from within the Studio.

PortableText [components.type] is missing "muxVideo"

Towards empathic previews

We're fans of all efforts that attempt to improve user experiences, but we are not sure that re-inventing inline WYSIWYG content editing that locks content to a specific presentation is the way to go. Instead, let’s use modern tools to make better, more versatile authoring experiences. That not only seek to give authors a sense of control, but also empowers them to explore how their content is perceived by their audiences.