Migrating New Document Templates
The newDocumentOptions
lets you configure templates for new documents that can be reactive to contextual info such as the currently logged-in user.
Templates for “New Document”-items should be declared on the document.newDocumentOptions
property. It accepts either a static array of template objects or a callback function that returns the same. The callback function is invoked with the current value as its first argument and a configuration context object as its second.
In v2, you would set it up like this:
// sanity.json
{
"root": true,
"project": {
"name": "My Project"
},
// ...
"parts": [
{
"name": "part:@sanity/base/initial-value-templates",
"path": "./initialValueTemplates.js"
},
{
"name": "part:@sanity/base/new-document-structure",
"path": "./newDocumentStructure.js"
}
]
}
// ./newDocumentStructure.js
import S from '@sanity/base/structure-builder'
const personTemplateId = 'personWithRole'
const roles = [
{name: 'developer', title: 'Developer'},
{name: 'designer', title: 'Designer'},
{name: 'admin', title: 'Administrator'},
{name: 'manager', title: 'Manager'}
]
export default [
...roles.map(role =>
S.initialValueTemplateItem(personTemplateId, {role: role.name})
.id(`personRole-${role.name}`)
.title(role.title)
),
...S.defaultInitialValueTemplateItems()
]
In v3, you would do something like this:
v3
// sanity.config.ts
import {defineConfig} from 'sanity'
import {templates} from './schema/templates'
export default defineConfig({
name: 'default',
title: 'My Cool Project',
projectId: 'my-project-id',
dataset: 'production',
schema: {
templates: [
{
id: 'personWithRole',
schemaType: 'person',
title: 'Person with Role',
// See `document.newDocumentOptions[].parameters.name`
parameters: [{name: 'role', type: 'string'}],
value: ({role}) => ({role}),
},
],
},
document: {
newDocumentOptions: [
{name: 'developer', title: 'Developer'},
{name: 'designer', title: 'Designer'},
{name: 'admin', title: 'Administrator'},
{name: 'manager', title: 'Manager'},
].map((roleExample) => ({
id: 'personWithRole',
templateId: 'personWithRole',
type: 'initialValueTemplateItem',
title: roleExample.title,
parameters: {name: roleExample.name},
})),
},
})
The example above shows you a combination of using Initial Value Templates to automatically generate a new person
document that takes a parameter called role
and uses its value for the role
field type on the person
document type.
In the document
property for the Workspace configuration, we find newDocumentOptions
that takes an array of objects that define how the New document options should behave and what Initial Value Template they should invoke. In the example, we're keeping the code dry by looping over an array with the different options. Notice that we pass name
into the parameters.name
property. This is the value that's used by the schema.templates.value
function.
We can also return initial value templates based on the current user or other contextual variables. Building on the minimal example above is how to return only the new document templates mapping the predefined initial values with the role value of the current user.
// sanity.config.ts
import {defineConfig} from 'sanity'
import {templates} from './schema/templates'
export default defineConfig({
// ...
document: {
// NOTE: the function variant of this API is useful for conditionals
newDocumentOptions: (prev, {currentUser, creationContext}) => {
// the `currentUser` and `creationContext` can be used to conditionally add templates
if (currentUser.roles.find((role) => role.name === 'admin')) {
return [
// `prev` is equivalent to `S.defaultInitialValueTemplateItems()`
...prev,
{
id: 'adminRole',
templateId: 'personWithRole',
type: 'initialValueTemplateItem',
parameters: {role: 'admin'},
},
]
}
if (creationContext.type === 'document' && creationContext.schemaType === 'book') {
// this could be used to change the options in the create-new menu for refs in place
}
return prev
},
},
})
These guides are under development. If you have questions or suggestions for improvement, then we want to hear from you. Get in touch via our GitHub discussions page.