Get random document in Sanity.io with the Structure Builder

One of the countless ways to use Sanity's structure builder to build unique and effective UIs for your editors

The most complicated part of content is its long term maintainability. Sure, producing is hard - you should see how long I'm taking to write these words -, but keeping your words up-to-date with organizational & product changes, market shifts and even the cultural climate is an entirely new beast.

One way you can improve this process is by re-surfacing old content to editors for review. In Sanity, a quick way to do that is to add a menu item that displays a random piece of content. It's the perfect use-case for Sanity's structure builder.

I've recorded a video going through it, in case you prefer that format.

Displaying a random document with the structure builder

Here's the high-level approach to getting to that:

  1. Create a new S.listItem in your structure
  2. Before rendering content inside of it, we'll fetch all ids of a given collection of documents
  3. Then we'll pick a random id from this list
  4. And render a S.document(chosenId) with this id

The code to implement is short - without comments it could fit in 12 formatted lines:

import S from '@sanity/desk-tool/structure-builder'
import client from 'part:@sanity/base/client'

export default () =>
  S.list()
    .title('Content')
    .items([
      S.documentTypeListItem('idea').title('Ideas'),
      // New item in the desk menu:
      S.listItem()
        // Add a recognizable title & icon
        .title('Random idea')
        .icon(FiHelpCircle)
        // And use an async function to resolve its content
        .child(async () => {
          // It'll first fetch the ids of every idea in the dataset
          const ids = await client.fetch(`*[_type == 'idea']._id`)
          // Get a random one from that list
          const chosenId = getRandomItem(ids)
          // And display the document for this random one
          return S.document().id(chosenId).schemaType('idea')
        }),
      // ...
    ])
    
// Used to find a random id every time the
// "Random Idea" menu is clicked
function getRandomItem(arr) {
  const randomIndex = Math.floor(Math.random() * arr.length)
  return arr[randomIndex]
}

Over the course of the next months I'll try to share other examples of how the structure builder can be used to create effective editing environments. My goal is to show how Sanity can make content maintenance easier (or "Content Ops" in general).

The structure above is something I'm using for myself. On a personal level, I'm hoping that by reviewing my ideas more often, I'll learn better. After all, Learning life-long wisdom takes time ;)