How to add "New document" button in mixed folder/document hierarchy and set parent field automatically?

4 replies
Last updated: Dec 1, 2025
I’m setting up a user-configurable hierarchy, and starting to get happy with how it looks now.When I know I’m on the last level I can use
documentTypeList
to get a document list with a “New document” button. But for those cases where there is a mix of folders and documents, how can I get the “New document”-button to appear?
Also, for the newly created document I would like the field for it’s parent to be automatically filled. What is the best way to do this? Can I access the id of the parent folder from the
initialValue
block somehow?
AI Update

When building a user-configurable hierarchy in Sanity's Structure Builder, getting the "New document" button to appear in a mixed list of folders and documents requires using initialValueTemplates(). Here's how to solve both parts of your question:

Adding the "New Document" button

For document lists that mix folders and documents, you need to configure the list with initialValueTemplates() and canHandleIntent(). Here's the pattern from the parent-child taxonomy guide:

S.documentTypeList(schemaType)
  .title('Children')
  .filter(`_type == $schemaType && parent._ref == $parentId`)
  .params({schemaType, parentId: parent._id})
  .canHandleIntent(
    (intentName, params) =>
      intentName === 'create' && params.template === 'category-child'
  )
  .initialValueTemplates([
    S.initialValueTemplateItem('category-child', {
      parentId: parent._id,
    }),
  ])

The key methods are:

  • initialValueTemplates() - tells the list which template to use for creating new documents, which shows the "New document" button
  • canHandleIntent() - ensures the creation intent is handled by this specific list

Pre-filling the parent field

Yes, you can absolutely access the parent folder's ID in your initial value template! Configure this in your sanity.config.ts:

export default defineConfig({
  // ...other config
  schema: {
    types: schemaTypes,
    templates: (prev) => {
      const childTemplate = {
        id: 'category-child',
        title: 'Category: Child',
        schemaType: 'category',
        parameters: [{name: 'parentId', title: 'Parent ID', type: 'string'}],
        // The parentId value gets passed from the Structure Builder
        value: ({parentId}: {parentId: string}) => ({
          parent: {_type: 'reference', _ref: parentId},
        }),
      }
  
      return [...prev, childTemplate]
    },
  },
})

The parameters array defines what can be passed to the template, and the value function receives those parameters and returns the initial values for your document. When you pass parentId through initialValueTemplates() in your Structure Builder (as shown above), it automatically pre-fills the parent reference field.

This approach gives you a clean workflow where authors can create child documents from within a parent's context, and the relationship is automatically established. The complete working example is available in the Creating a Parent/Child Taxonomy guide.

Show original thread
4 replies

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?