Discussion on organizing schemas and splitting schemas with the same name in Sanity
I understand your frustration - this is a common challenge when learning Sanity! The good news is that you can reorganize your schema structure without losing content, but it's important to understand what's actually happening under the hood.
The Core Issue
The folder structure (schema/sections/abc/hero.js) is purely for your organization - Sanity doesn't care about it at all. What Sanity does care about is the _type field stored in each document. This is what identifies the schema type.
However, there's a critical constraint: the _type field is immutable. According to the official Sanity migration documentation, you cannot change _type, _id, _createdAt, _updatedAt, or _rev once they're set. These are immutable properties in the Content Lake.
The Right Solution: Unique Schema Names
Instead of trying to have multiple schemas with the same name in different folders, you should give each schema a unique name property that reflects its context:
schema/
documents/
objects/
sections/
abc/
abcHero.js // name: 'abcHero'
xyz/
xyzHero.js // name: 'xyzHero'In each schema file, make sure the name field is unique:
// schema/sections/abc/abcHero.js
export default {
name: 'abcHero', // This is what becomes _type
type: 'object',
title: 'ABC Hero Section',
fields: [
// your fields
]
}If You Already Have Conflicting Names
If you've already created content with conflicting schema names, you'll need to migrate the data. Since _type is immutable, you can't use the standard migration toolkit's at('_type', set(...)) approach. Instead, you need to:
1. Export Your Dataset
sanity dataset export production --no-assetsThis creates a .tar.gz file containing an NDJSON file with all your documents.
2. Modify the Export File
tar -xzvf production.tar.gzOpen the .ndjson file and find/replace the _type values. For example, change documents from:
{"_id": "abc123", "_type": "hero", ...}to:
{"_id": "abc123", "_type": "abcHero", ...}Important: You'll also need to update any references to these documents throughout your dataset. If other documents reference these by type (in arrays with type filters, for example), those need updating too.
3. Update Your Schema
Before reimporting, update your schema files with the new unique names.
4. Delete Old Documents (if keeping same IDs)
If you're keeping the same _id values but changing the _type, you'll need to delete the old documents first. Create a migration:
import {defineMigration, delete_} from 'sanity/migrate'
export default defineMigration({
title: 'Delete old hero documents',
documentTypes: ['hero'], // the old type name
migrate: {
document(doc) {
return delete_(doc._id)
}
}
})Run this with:
sanity migration run "Delete old hero documents" --dataset production5. Reimport Your Modified Data
sanity dataset import production.ndjson production --replaceAlternative: Create New Documents with Different IDs
If the above seems too risky, you could also:
- Keep your old documents as-is
- Create new schema types with unique names (
abcHero,xyzHero) - Manually recreate the content in Studio with the new types
- Delete the old documents once you've verified everything works
This is safer but more manual work.
Better Approach for the Future
To avoid this entirely, establish a naming convention from the start:
- Prefix by context:
homeHero,productHero,aboutHero - Prefix by document type:
pageHero,postHero - Use descriptive names: Instead of generic "hero", use
fullWidthHero,splitHero, etc.
The folder structure is just for your convenience - the name field in the schema is what matters to Sanity.
Important Notes
- Backup first: Always export your dataset before attempting any destructive operations
- Test on development: Try this process on a development dataset first
- Strong references: If documents have strong references to the ones you're changing, you'll need to handle those carefully in your NDJSON edits
- Validate after: Run
npx sanity documents validateafter migration to ensure everything is correct
The key takeaway: organize your files however you want, but make sure every schema has a unique name property. That's what Sanity uses to identify content types, not the file structure. The migration cheat sheet has more examples of common migration patterns, though changing _type specifically requires the export/modify/reimport approach.
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.