How to execute a dynamic query in deskStructure every time in Sanity.io.
The Structure Builder in Sanity Studio does cache and memoize structure definitions by design, which is causing your issue. However, there's a proper way to achieve dynamic filtering that re-evaluates on each access.
The key is understanding that child() resolvers are called every time a pane is opened, while top-level structure definitions are evaluated once. Based on the Structure Builder documentation, you can leverage this behavior:
S.listItem()
.title('Filtered Pages')
.child(() =>
S.documentList()
.title('All Pages')
.filter(`_type == 'page' && ${dynamicQuery()}`)
)By wrapping your S.documentList() inside a child() function, the entire document list (including its filter) gets re-evaluated each time the pane is opened, rather than being cached at structure initialization time.
If you need this at the root level (not nested under a list item), you can make your entire structure resolver return items with child functions:
export const structure: StructureResolver = (S) =>
S.list()
.id('root')
.title('Content')
.items([
S.listItem()
.title('Pages')
.child(() =>
S.documentList()
.title('All Pages')
.filter(`_type == 'page' && ${dynamicQuery()}`)
),
// other items...
])The Structure Builder supports asynchronous operations, so if your dynamicQuery() needs to fetch data, you can also make the child resolver async:
.child(async () => {
const dynamicPart = await someAsyncOperation()
return S.documentList()
.title('All Pages')
.filter(`_type == 'page' && ${dynamicPart}`)
})This approach is cleaner than using context.documentStore.listenQuery and ignoring the response, as it works with the Structure Builder's intended architecture where child resolvers are naturally re-evaluated on navigation. The child() function is specifically designed to be called every time you navigate to that pane, making it perfect for dynamic queries that need fresh evaluation.
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.