the best way of displaying a list of documents that are referenced to the currently viewed document.

3 replies
Last updated: Sep 9, 2020
Hi all, I just want to check the best way of displaying a list of documents that are referenced to the currently viewed document. So if I'm editing the Europe Continent page I'd like an auto-generated list of all the Countries that are referenced to it.Better off with some kind of Input Component or would it be best to use a reactComponent via the Structure Builder? Any other better approach? Thanks very much
🤘
AI Update

For displaying a list of documents that reference the currently viewed document (like showing all Countries that reference a Europe Continent page), your best approach is using a custom Component View via the Structure Builder. This is the recommended, documented way to add custom displays to your document editing experience.

The Structure Builder's Component View lets you add custom React components as additional tabs in your document editor. Here's how to set it up:

1. Create your custom component that queries for incoming references:

// components/IncomingReferences.tsx
import {type UserViewComponent} from 'sanity/structure'
import {useEffect, useState} from 'react'
import {useClient} from 'sanity'

export const IncomingReferences: UserViewComponent = (props) => {
  const client = useClient({apiVersion: '2024-01-01'})
  const [references, setReferences] = useState([])
  
  useEffect(() => {
    client.fetch(
      `*[references($id)]`,
      {id: props.documentId}
    ).then(setReferences)
  }, [props.documentId])
  
  return (
    <div>
      <h2>Referenced By</h2>
      {references.map(doc => (
        <div key={doc._id}>{doc.title || doc._id}</div>
      ))}
    </div>
  )
}

2. Configure it in your Structure Builder setup:

// structure.ts
import type {DefaultDocumentNodeResolver} from 'sanity/structure'
import {IncomingReferences} from './components/IncomingReferences'

export const getDefaultDocumentNode: DefaultDocumentNodeResolver = (S, {schemaType}) => {
  // Only add for continent documents, or add to all with just S.document()
  if (schemaType === 'continent') {
    return S.document().views([
      S.view.form(),
      S.view.component(IncomingReferences).title('Referenced By')
    ])
  }
  
  return S.document().views([S.view.form()])
}

3. Add to your Studio config:

// sanity.config.ts
import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'
import {getDefaultDocumentNode} from './structure'

export default defineConfig({
  // ... other config
  plugins: [
    structureTool({
      defaultDocumentNode: getDefaultDocumentNode
    })
  ]
})

This gives you a clean "Referenced By" tab next to your form view with full control over presentation.

Alternative: Documents Pane Plugin

The sanity-plugin-documents-pane is another solid option that lets you display GROQ query results in a view pane. It's specifically designed for showing related documents and has an example for incoming references in the README. Install with:

npm i sanity-plugin-documents-pane

Why NOT a Custom Input Component

You're right to question this approach - custom input components are not recommended for displaying incoming references because:

  • They're meant for editing field values, not displaying read-only related data
  • They take up space in your form unnecessarily
  • Component Views are the proper pattern for this use case

The Component View approach keeps your editing interface clean while giving you exactly the custom display you need, with full access to the document's ID and state to query for references.

Show original thread
3 replies
Sweet, thanks! I'll look into that and see how things go... cheers.

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?