Get a peek at our latest innovations at Sanity Product Day on Dec 8th →

Migrate plain text field to Portable Text

By Knut Melvær

Migration script to convert plain text to block content across your content lake

convertToPortableText.js

/* eslint-disable no-console */
import client from 'part:@sanity/base/client'

// length(description) returns null if description isn't a (Portable Text) array
const fetchDocuments = () =>
  client.fetch(`*[_type == 'post' && length(description) == null][0...100] {_id, _rev, description}`)

const buildPatches = docs =>
  docs.map(doc => ({
    id: doc._id,
    patch: {
      set: {description: [
        {
          "style": "normal",
          "_type": "block",
          "children": [
            {
              "_type": "span",
              "marks": [],
              "text": doc.description
            }
          ],
          markDefs: []
        }
      ]},
      // this will cause the migration to fail if any of the documents has been
      // modified since it was fetched.
      ifRevisionID: doc._rev
    }
  }))

const createTransaction = patches =>
  patches.reduce((tx, patch) => tx.patch(patch.id, patch.patch), client.transaction())

const commitTransaction = tx => tx.commit()

const migrateNextBatch = async () => {
  const documents = await fetchDocuments()
  const patches = buildPatches(documents)
  if (patches.length === 0) {
    console.log('No more documents to migrate!')
    return null
  }
  console.log(
    `Migrating batch:\n %s`,
    patches.map(patch => `${patch.id} => ${JSON.stringify(patch.patch)}`).join('\n')
  )
  const transaction = createTransaction(patches)
  await commitTransaction(transaction)
  return migrateNextBatch()
}

migrateNextBatch().catch(err => {
  console.error(err)
  process.exit(1)
})

This script queries all documents that match the GROQ filter and builds transactions of 100 patches to convert a plain text field (description) to Portable Text. It takes the text string and places it inside a span of a block.

You can run this script with sanity exec --with-user-token convertToPortableText.js from your command line inside the studio folder.

Contributor

Other schemas by author