How to hide a document from the Sanity Studio left nav using code snippets.

9 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, absolutely! You can hide document types from the left navigation in Sanity Studio using the Structure Builder. This is a common pattern when you have "child" documents (like sections, blocks, or components) that should only be referenced from within other documents, not managed directly from the main navigation.

By default, the Structure tool displays all document types in your schema. To hide specific types, you need to explicitly define which document types should appear in the navigation using the Structure Builder API.

Here's how to do it in your sanity.config.ts:

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

export default defineConfig({
  // ...other config
  plugins: [
    structureTool({
      structure: (S) =>
        S.list()
          .title('Content')
          .items([
            // Only list the document types you want to show
            S.documentTypeListItem('page').title('Pages'),
            S.documentTypeListItem('post').title('Blog Posts'),
            // Don't include 'pageSection' or other child document types here
          ])
    }),
    // ...other plugins
  ],
})

In this example, if you have a pageSection document type that's only referenced from within page documents, it won't appear in the left navigation because it's not included in the .items([]) array.

Key points:

  • Once you define a custom structure, only the document types you explicitly list will appear in the navigation
  • Hidden document types are still fully functional—they can be created, edited, and referenced through the normal reference/relationship fields
  • You can still access them directly via URL if needed (like /structure/pageSection)
  • This doesn't affect permissions or API access, just the Studio UI navigation

This approach gives you complete control over your Studio's content organization and helps keep the navigation clean for your editors!

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?