Watch a live product demo đź‘€ See how Sanity powers richer commerce experiences

Make a Field Read-Only After Publishing Once

By RD Pennell

Use a publishedOnce field to control other fields.

Warning

This schema is for an older version of Sanity Studio (v2), which is deprecated.

Learn how to migrate to the new Studio v3 →

document.js

{
  name: 'publishedOnce',
  type: 'boolean',
  hidden: true
},
{
  title: 'Read-only sometimes',
  name: 'readOnlySometimes',
  type: 'string',
  readOnly: ({ document }) => !document?.publishedOnce
},

sanity.json

//... 
"parts": [ 
  //... 
  { 
    "implements": "part:@sanity/base/document-actions/resolver", 
    "path": "resolveDocumentActions.js" 
  } 
]

setAndPublishAction.js

import {useState, useEffect} from 'react'
import {useDocumentOperation} from '@sanity/react-hooks'

export default function SetAndPublishAction(props) {
  const {patch, publish} = useDocumentOperation(props.id, props.type)
  const [isPublishing, setIsPublishing] = useState(false)
  
  useEffect(() => {
    // if the isPublishing state was set to true and the draft has changed
    // to become `null` the document has been published
    if (isPublishing && !props.draft) {
      setIsPublishing(false)
    }
  }, [props.draft])
  
  return {
    disabled: publish.disabled,
    label: isPublishing ? 'Publishing…' : 'Publish',
    onHandle: () => {
      // This will update the button text 
      setIsPublishing(true)
      
      // Set publishedAt to current date and time
      patch.execute([{set: {publishedOnce: true}}])
      
      // Perform the publish
      publish.execute()
      
      // Signal that the action is completed
      props.onComplete() 
    }
  }
}

resolveDocumentActions.js

import defaultResolve, { PublishAction } from 'part:@sanity/base/document-actions'
import SetAndPublishAction from './setAndPublishAction'

export default function resolveDocumentActions(props) {

  return defaultResolve(props)
    .map(Action =>
      Action === PublishAction ? SetAndPublishAction : Action
    )
}

It can be pretty hard to use an existing field in your document to distinguish whether or not something has been published before. The simplest solution is to add a hidden publishedOnce boolean field that updates via a document action.

Contributor

Other schemas by author