Open document in new pane from custom component with multiple types
I've dealt with this exact issue! The problem you're encountering is that when you define a custom component in your Structure, Sanity doesn't know what child panes to expect until a user actually clicks on something. The warning about "desk structure child was not found" happens because the Structure builder can't resolve the navigation path ahead of time.
The solution that works is actually documented in this community answer. You need to use Object.assign() to serialize a documentList and then override it with your custom component properties:
S.listItem()
.title("Page tree")
.child(
Object.assign(
S.documentList()
.filter('_type in ["typeA", "typeB"]')
.title("Page tree")
.serialize(),
{
__preserveInstance: true,
key: 'pageTree',
id: 'pageTree',
type: 'component',
component: CustomComponent,
}
),
)This approach works because internally it's still a document list from the Structure builder's perspective, which means the pane router knows how to handle document navigation properly. When users click links in your custom component to open documents, the Structure tool will correctly open them in new panes.
The key insight here is that you're not trying to define .child(S.document().schemaType('typeA')) for each type. Instead, you're letting the document list handle multiple types through its filter, while your custom component just provides the visual representation.
This pattern is used by plugins like the orderable-document-list plugin, which renders custom components for list items while maintaining proper pane navigation behavior.
Once you have this structure in place, the <IntentLink /> from usePaneRouter should work as expected, because the Structure builder now understands that this is a document list that can have document children, even though it's rendering through your custom component.
Show original thread4 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.