How to control entity titles in Sanity (e.g., "row 1", "row 2")?

5 replies
Last updated: Apr 19, 2021
Hi everyone! Short question: how do you control entities titles? For example, I want all the rows to have a “row 1”, “row 2" etc titles. If there is no title, entities have strange names based on values. Where to read about this? Would really appreciate your help!
AI Update

You're looking for preview configuration in Sanity! This controls how documents and objects appear in lists throughout the Studio.

By default, Sanity tries to automatically generate preview titles from your document fields, which can result in those strange names you're seeing. You can take full control using the preview property in your schema.

Here's how to set up basic preview configuration:

{
  name: 'row',
  type: 'object',
  preview: {
    select: {
      title: 'name',  // Use the 'name' field as the title
      subtitle: 'description'
    }
  }
}

If you need custom logic (like combining multiple fields or formatting), use the prepare function:

preview: {
  select: {
    firstName: 'firstName',
    lastName: 'lastName'
  },
  prepare({firstName, lastName}) {
    return {
      title: `${firstName} ${lastName}`,
      subtitle: 'Customer'
    }
  }
}

For your specific case of wanting "Row 1", "Row 2" numbering, this is trickier since the standard preview configuration doesn't have built-in access to the array index. You have a few options:

  1. Add an explicit number field to your row object and use that in the preview
  2. Use a custom input component that can access the array context and display custom numbering
  3. Set up an initialValue function that automatically numbers rows as they're created

The simplest approach is option 1 - add a field to store the row number:

{
  name: 'row',
  type: 'object',
  fields: [
    {
      name: 'rowNumber',
      type: 'number',
      hidden: true,
      readOnly: true
    },
    // your other fields
  ],
  preview: {
    select: {
      rowNumber: 'rowNumber'
    },
    prepare({rowNumber}) {
      return {
        title: `Row ${rowNumber || '?'}`
      }
    }
  }
}

You can read more about this in the official preview configuration documentation and check out this guide on creating richer array item previews for more advanced examples.

Show original thread
5 replies
Sanity tries to infer a name based on your schema, you can customize the behavior with this config: https://www.sanity.io/docs/previews-list-views#770fd57a8f95
Hi Vlad. I’d definitely recommend taking a look at the link Derek posted. There’s a lot of power in what data you can return as a title, subtitle, description, etc.
You didn’t mention your reasons for not having a title on your document, but if you don’t want to add a visible title in the studio, you could take advantage of the string’s
hidden property as well as an asynchronous initialValue function to query your document count. If your document is named “mainPage,” you could do something like:

import client from 'part:@sanity/base/client';

export default {
  name: 'mainPage',
  type: 'document',
  title: 'Main page row',
  fields: [
    ..., // Your other [boolean] fields
    {
      name: 'title',
      type: 'string',
      hidden: true,
    }
  ],
  initialValue: async () => ({
    title: "row " + await client.fetch(`
      count(*[_type == "mainPage"]) + 1
    `)
  })
}
This would produce a title named
row #
based on the number of
mainPage
documents, but would hide it in the studio.
However, if you were ever to delete a document the next one produced would probably have a duplicate title, and since the title is hidden you’d need to take out-of-studio steps to fix it. That, or better handling of incrementing your row count.
Hi Vlad. I’d definitely recommend taking a look at the link Derek posted. There’s a lot of power in what data you can return as a title, subtitle, description, etc.
You didn’t mention your reasons for not having a title on your document, but if you don’t want to add a visible title in the studio, you could take advantage of the string’s
hidden property as well as an asynchronous initialValue function to query your document count. If your document is named “mainPage,” you could do something like:

import client from 'part:@sanity/base/client';

export default {
  name: 'mainPage',
  type: 'document',
  title: 'Main page row',
  fields: [
    ..., // Your other [boolean] fields
    {
      name: 'title',
      type: 'string',
      hidden: true,
    }
  ],
  initialValue: async () => ({
    title: "row " + await client.fetch(`
      count(*[_type == "mainPage"]) + 1
    `)
  })
}
This would produce a title named
row #
based on the number of
mainPage
documents, but would hide it in the studio.
user G
,
user A
, thank you so much, that’s exactly what I was trying to achieve.

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?