Is there any way of hiding a document (that you call from another document) from the sanity studio left nav?

11 replies
Last updated: Feb 4, 2021
Is there any way of hiding a document (that you call from another document) from the sanity studio left nav?
AI Update

Yes! You can definitely hide specific document types from the Structure Tool's left navigation. This is commonly needed when you have documents that should only be referenced from other documents (like reusable content blocks or metadata) but don't need their own top-level navigation.

The key is to customize the Structure Tool using the Structure Builder API. Here's how to do it:

Basic Approach: Filter Document Types

In your sanity.config.js (or .ts), customize the Structure Tool to explicitly control which document types appear:

import { structureTool } from 'sanity/structure'
import { defineConfig } from 'sanity'

export default defineConfig({
  // ... other config
  plugins: [
    structureTool({
      structure: (S) =>
        S.list()
          .title('Content')
          .items([
            // Explicitly list the document types you WANT to show
            S.documentTypeListItem('post').title('Blog Posts'),
            S.documentTypeListItem('author').title('Authors'),
            // 'reusableBlock' is omitted, so it won't appear in the nav
          ])
    })
  ]
})

Filter Out Specific Types

If you have many document types and only want to hide a few, you can filter the default list:

structureTool({
  structure: (S) =>
    S.list()
      .title('Content')
      .items([
        // Get all default document type list items except the ones you want to hide
        ...S.documentTypeListItems().filter(
          (listItem) => !['reusableBlock', 'seoMetadata'].includes(listItem.getId())
        )
      ])
})

This approach uses S.documentTypeListItems() to get all your schema types, then filters out the ones you don't want visible in the left nav.

Why This Works

When you reference these hidden documents from other documents (using reference fields), they're still fully functional—editors can still create and edit them through the reference picker or by navigating directly via URL. They just won't clutter your main navigation.

The Structure Tool is extremely flexible, so you can also create custom groupings, nested lists, and filtered views to organize your content exactly how your editors need it. Check out the Structure Builder guide for more advanced customization options.

Show original thread
11 replies
Hi Karin, there is! Something like this should work:
// deskStructure.js

const hiddenDocTypes = listItem => ![
  'myHiddenDocType1',
  'myHiddenDocType2'
].includes(listItem.getId())

export default () =>
  S.list()
    .title('Content')
    .items([
      // Your custom list items go here
          
      // Followed by an array of all remaining document types defined in
      // schema.js, with the hidden ones filtered out
      ...S.documentTypeListItems().filter(hiddenDocTypes)
    ])
Hi Karin, there is! Something like this should work:
// deskStructure.js

const hiddenDocTypes = listItem => ![
  'myHiddenDocType1',
  'myHiddenDocType2'
].includes(listItem.getId())

export default () =>
  S.list()
    .title('Content')
    .items([
      // Your custom list items go here
          
      // Followed by an array of all remaining document types defined in
      // schema.js, with the hidden ones filtered out
      ...S.documentTypeListItems().filter(hiddenDocTypes)
    ])
Hi Karin, there is! Something like this should work:
// deskStructure.js

const hiddenDocTypes = listItem => ![
  'myHiddenDocType1',
  'myHiddenDocType2'
].includes(listItem.getId())

export default () =>
  S.list()
    .title('Content')
    .items([
      // Your custom list items go here
          
      // Followed by an array of all remaining document types defined in
      // schema.js, with the hidden ones filtered out
      ...S.documentTypeListItems().filter(hiddenDocTypes)
    ])
Thank you Peter! I will definitely look into that. 💕
Hi again,
user M
! I've been trying to implement above code into my project, but I get an error message saying "ReferenceError: S is not defined".. Am I missing something here? 😬☺️
Now I have this code, but my error message says "List items must be of type "listItem", got "document"."
import S from '@sanity/desk-tool/structure-builder';


import grid from './schemas/grid';

import home from './schemas/home';

import creator from './schemas/creator';

import project from './schemas/project';

import recipe from './schemas/recipe';

import contact from './schemas/contact';


const hiddenDocTypes = (_listItem_) => ![grid].includes(_listItem_.getId());

export default () =>

S.list()

.title('Content')

.items([

home,

project,

recipe,

creator,

contact,

// Your custom list items go here

// Followed by an array of all remaining document types defined in

// schema.js, with the hidden ones filtered out

...S.documentTypeListItems().filter(hiddenDocTypes),

]);
Hi Karin, could you share one of your imported schemas?
Of course. Home looks like this:
import { string } from 'prop-types';


export default {

name: 'home',

title: 'Home',

type: 'document',

fields: [

{

name: 'hero_image',

title: 'Hero Image',

type: 'image',

},

{

name: 'hero_title',

title: 'Hero Title',

type: 'string',

},

{

name: 'hero_text',

title: 'Hero Text',

type: 'text',

},

{

name: 'intro_text',

title: 'Intro',

type: 'text',

},

],

};
That explains: the structure builder expects a list item here, not a document. A list item looks as follows, for example:
S.listItem()
  .title('Completed projects')
  .child(
    S.documentTypeList('project')
      .title('Projects')
      .filter('_type == $type && completed == true')
      .params({ type: 'project' })
  ),
Please note that you'll only have to manually set these up if you want to have variations of what's shown by default, i.e. if you want to set up a custom desk structure.

If not, you could simply hide the one you want to hide and that's it (no need to import the document type either as that's already done in your
schema.js
file):
import S from '@sanity/desk-tool/structure-builder';

const hiddenDocTypes = (listItem) => !['grid'].includes(listItem.getId());
export default () =>
  S.list()
    .title('Content')
    .items([
      ...S.documentTypeListItems().filter(hiddenDocTypes),
    ]);
Hope that helps
🙂 Here's some additional info on the structure builder: https://www.sanity.io/docs/overview-structure-builder
Ohh, OK. I'll try that 🙂 Thank you so much!
Yay! It worked. Thanks again! 💕

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?