
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeThe "window is not defined" error you're encountering happens because sanity exec runs your script in a Node.js environment, not a browser. When you try to import schema files or other code that references browser globals like window, it fails.
Here's how to write import scripts that work with sanity exec:
Create a script file (e.g., scripts/import.ts) that uses the Sanity client in a Node environment:
// scripts/import.ts
import {getCliClient} from 'sanity/cli'
const client = getCliClient()
async function importContent() {
console.log(`Importing to:`)
console.log(`Project ID: ${client.config().projectId}`)
console.log(`Dataset: ${client.config().dataset}`)
// Your import logic here
const documents = [
{
_type: 'post',
_id: 'my-post-id',
title: 'My Post Title',
}
]
const transaction = client.transaction()
documents.forEach(doc => {
transaction.createOrReplace(doc)
})
await transaction.commit()
.then(() => console.log('Import complete!'))
.catch(err => console.error('Import failed:', err))
}
importContent()Run it with:
npx sanity exec scripts/import.ts --with-user-tokenThe --with-user-token flag provides authentication using your credentials.
If you need to reference your schema types but get window is not defined errors, you have a few options:
Option 1: Don't import the full schema
Instead of importing schema files directly, just use plain objects that match your schema structure. The client doesn't need the schema definitions to create documents.
Option 2: Import only type definitions
If you're using TypeScript, import just the generated types (not the schema):
import type {Post} from '../sanity.types'Option 3: Use Schema.compile for validation (as shown in the demo content guide)
If you need schema validation, compile it specifically for Node:
import {Schema} from '@sanity/schema'
import {schemaTypes} from '../schemas'
const defaultSchema = Schema.compile({types: schemaTypes})
const postSchema = defaultSchema.get('post')Here's a more complete example that imports content with transactions in batches to avoid rate limits:
// scripts/import.ts
import {getCliClient} from 'sanity/cli'
import type {SanityDocumentLike} from 'sanity'
const client = getCliClient()
// Your source data (could come from an API, file, etc.)
const sourceData = [
{title: 'Post 1', slug: 'post-1'},
{title: 'Post 2', slug: 'post-2'},
// ... more data
]
async function importContent() {
console.log(`Starting import...`)
// Transform your source data to Sanity documents
const documents: SanityDocumentLike[] = sourceData.map(item => ({
_type: 'post',
_id: item.slug, // Use source ID for idempotency
title: item.title,
}))
// Create in batches to avoid rate limits
const BATCH_SIZE = 100
for (let i = 0; i < documents.length; i += BATCH_SIZE) {
const batch = documents.slice(i, i + BATCH_SIZE)
const transaction = client.transaction()
batch.forEach(doc => transaction.createOrReplace(doc))
await transaction.commit()
console.log(`Imported batch ${i / BATCH_SIZE + 1}`)
}
console.log('Import complete!')
}
importContent()getCliClient() from sanity/cli - it's configured for Node.js--with-user-token flag for authenticated operationscreateOrReplace() for idempotent imports (can run multiple times safely)The demo content creation guide I linked above has extensive examples including:
For more complex migrations with validation and better tooling, consider using sanity migration instead, which provides built-in batching, dry-run capabilities, and schema validation. The migration tooling is often preferred for content migrations as it provides additional conveniences and safety features.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store