Best practices for backfilling content in Sanity when adding new fields to schema.

6 replies
Last updated: Jun 19, 2023
Hello everyone, I am fairly new to Sanity and was wondering if there is a native solution or best practice for backfilling content when a new field is added to the schema or if one of the existing fields changes. For example, lets say I had a blog schema with content already created but I want to add a subtitle field, how would I backfill all the existing content to have the subtitle field?
AI Update

Great question! Backfilling content when adding new fields to your schema is a common scenario, and Sanity has a recommended approach for this using the CLI migration tool.

When you add a new field like subtitle to your blog schema, existing documents won't automatically have that field populated. Here's how to handle it:

The CLI migration tool is the recommended approach. It provides built-in abstractions, automatic batching to avoid rate limits, dry-run mode by default, and document validation against your schema.

Create a new migration:

npx sanity@latest migration create

This creates a migration file where you can use defineMigration to backfill your new field. For your subtitle example:

import {defineMigration, at, setIfMissing} from 'sanity/migrate'

export default defineMigration({
  title: 'Add subtitle field to blog posts',
  documentTypes: ['blog'], // Only target blog documents
  
  migrate: {
    document(doc, context) {
      // Set a default value for subtitle if it doesn't exist
      return at('subtitle', setIfMissing('Default subtitle'))
      
      // Or derive it from another field:
      // return at('subtitle', setIfMissing(doc.title?.substring(0, 50)))
    }
  }
})

Run the migration:

# Dry run first (default) to see what would change
npx sanity migration run

# Then execute for real
npx sanity migration run --no-dry-run

Key Best Practices

The migration principles emphasize:

  1. Make it idempotent: Use setIfMissing instead of set so you can safely run the script multiple times without overwriting manually updated values
  2. Start simple: Begin with basic logic, test it, then add complexity incrementally
  3. Use dry-run mode: Always test first to preview changes before applying them
  4. Handle errors gracefully: Legacy content can be inconsistent, so plan for missing or corrupted data

Alternative Approaches

While the CLI migration tool is recommended, you can also:

For Your Specific Case

For adding a subtitle field to existing blog posts, you have several options:

  • Set a default placeholder: Use setIfMissing('Add subtitle here') so editors know to update it
  • Derive from existing content: Extract from the title or first paragraph: setIfMissing(doc.title?.substring(0, 50))
  • Leave it empty: If the field is optional in your schema, you might not need a migration at all—just let editors fill it in as they update posts
  • Use AI: For more sophisticated backfilling, you could even use Agent Actions to generate subtitles based on the post content

The migration tool makes this straightforward and safe, with dry-run giving you confidence before touching production data!

Hi
user A
. In some cases you might use a script to backfill existing documents, but I’m assuming subtitle will be fairly specific to each blog post so you might need a more manual approach. Do these subtitles already exist in your data outside of Sanity somewhere?
user A
In this example the subtitle would not exist outside of Sanity we would be creating them on the fly
In that case, once you’ve added the subtitle field to your schema, you’ll probably end up iterating over your blog posts in your Studio, adding the subtitle to each document. If it helps, you can add the subtitle field as the first item in your schema so that it gets focus when you open each document, then once you’re done you can move it where you want it to live in your schema file (the Content Lake doesn’t care).
An alternative approach would be to export your data, add all the subtitles to the NDJSON file, and then import that back into Sanity. This lets you work in a single file, and depending on the editor you’re using you may be able to take advantage of macros or repeatable actions to streamline this.
Ok that confirms our understanding of backfilling in the sanity environment. What if I added a default value for the subtitle? would all the existing documents get a subtitle with the default value? Is this a good practice?
If you mean an initial value, that can only be done when the document is initially created. Existing documents won’t be impacted.
I think leaving your
subtitle
empty in the meantime (it’s worth noting that in your Content Lake, the field will actually be undefined) is fine, so long as you account for that where you’re querying your data (e.g., your front end) with appropriate null checking or something similar.
user A
Ok thank you for the help!

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.

Was this answer helpful?