Complete guide for exporting content and assets from your Contentful space.
Before exporting, ensure you have:
- ✅ Contentful account with access to the source space
- ✅ Node.js >= 18.0.0 installed (LTS recommended)
- ✅ Contentful Management API Token (CMA)
- ✅ Space ID of the source space
- ✅ Sufficient disk space (export can be several GB)
Go to Contentful Web App
- Select your organization
- Go to Settings → API keys
- Navigate to Content management tokens
- Click Generate personal token
- Enter a descriptive name (e.g., "Export Token for US Space")
- Click Generate
- Copy the token immediately (it won't be shown again!)
- In Contentful Web App, open your space
- Go to Settings → General settings
- Copy the Space ID (format:
abc123xyz456)
npm install -g contentful-clicontentful space export \
--space-id YOUR_SPACE_ID \
--management-token YOUR_TOKEN \
--export-dir ./contentful-export \
--download-assetscontentful space export \
--space-id YOUR_SPACE_ID \
--environment-id master \
--management-token YOUR_TOKEN \
--export-dir ./contentful-export \
--download-assets \
--max-allowed-limit 1000 \
--use-verbose-renderernpm install contentful-exportCreate export-from-contentful.js:
const contentfulExport = require('contentful-export');
const options = {
spaceId: 'YOUR_SPACE_ID',
environmentId: 'master',
managementToken: 'YOUR_TOKEN',
exportDir: './contentful-export',
contentFile: 'exported-space.json',
downloadAssets: true,
maxAllowedLimit: 1000,
saveFile: true,
useVerboseRenderer: true
};
contentfulExport(options)
.then((result) => {
console.log('✅ Export completed successfully!');
console.log('Exported:', result);
})
.catch((err) => {
console.error('❌ Export failed:', err);
});node export-from-contentful.js{
"spaceId": "YOUR_SPACE_ID",
"environmentId": "master",
"managementToken": "YOUR_TOKEN",
"exportDir": "./contentful-export",
"contentFile": "exported-space.json",
"downloadAssets": true,
"includeDrafts": false,
"includeArchived": false,
"skipContentModel": false,
"skipContent": false,
"maxAllowedLimit": 1000,
"useVerboseRenderer": true
}npx contentful-export --config export-config.json| Option | Description | Recommended |
|---|---|---|
spaceId |
Source space ID | Required |
managementToken |
CMA token | Required |
exportDir |
Output directory | ./contentful-export |
downloadAssets |
Download asset files | true |
| Option | Description | Default |
|---|---|---|
includeDrafts |
Include draft entries | false |
includeArchived |
Include archived entries | false |
skipContentModel |
Skip content types | false |
skipContent |
Skip entries and assets | false |
skipRoles |
Skip roles | false |
skipWebhooks |
Skip webhooks | false |
| Option | Description | Default |
|---|---|---|
maxAllowedLimit |
Items per request | 1000 |
useVerboseRenderer |
Detailed progress | false |
contentFile |
JSON filename | contentful-export.json |
saveFile |
Save to disk | true |
{
"queryEntries": {
"content_type": "blogPost"
}
}{
"queryEntries": {
"sys.createdAt[gte]": "2023-01-01",
"sys.createdAt[lte]": "2023-12-31"
}
}{
"queryEntries": {
"locale": "en-US"
}
}After export, you'll have:
contentful-export/
├── exported-space.json # Main export file
├── assets.ctfassets.net/ # Downloaded assets
│ └── SPACE_ID/
│ └── ASSET_ID/
│ └── HASH/
│ └── filename.ext
├── downloads.ctfassets.net/ # More assets
├── images.ctfassets.net/ # Image assets
└── videos.ctfassets.net/ # Video assets
{
"contentTypes": [...], // Content type definitions
"entries": [...], // Content entries
"assets": [...], // Asset metadata
"locales": [...], // Locale configurations
"tags": [...], // Tags
"editorInterfaces": [...], // Editor UI configs
"webhooks": [...] // Webhooks (if included)
}--download-assets trueWithout this, you'll only get asset metadata, not the files.
--use-verbose-rendererShows detailed progress for long-running exports.
--export-dir ./contentful-exportKeep exports organized and avoid mixing with other files.
Start with a smaller export:
contentful space export \
--space-id YOUR_SPACE_ID \
--management-token YOUR_TOKEN \
--export-dir ./test-export \
--max-allowed-limit 100Large exports can be several GB:
# Check available space (macOS/Linux)
df -h .
# Check available space (Windows)
dirCreate a summary file:
echo "Exported on: $(date)" > contentful-export/EXPORT-INFO.txt
echo "Space ID: YOUR_SPACE_ID" >> contentful-export/EXPORT-INFO.txt
echo "Environment: master" >> contentful-export/EXPORT-INFO.txtcontentful space export \
--space-id prod-abc123 \
--environment-id master \
--management-token CFPAT-xxx \
--export-dir ./exports/prod-$(date +%Y%m%d) \
--download-assets \
--max-allowed-limit 1000 \
--use-verbose-renderercontentful space export \
--space-id YOUR_SPACE_ID \
--management-token YOUR_TOKEN \
--export-dir ./contentful-export \
--download-assets \
--include-drafts falsecontentful space export \
--space-id YOUR_SPACE_ID \
--environment-id staging \
--management-token YOUR_TOKEN \
--export-dir ./contentful-export-staging \
--download-assetsPerfect for batch migration:
contentful space export \
--space-id us-space-123 \
--environment-id production \
--management-token CFPAT-xxx \
--export-dir ./contentful-export \
--download-assets true \
--include-drafts false \
--include-archived false \
--max-allowed-limit 1000 \
--use-verbose-rendererSymptom: Export fails with "Too many requests"
Solution:
# Reduce request limit
--max-allowed-limit 500Symptom: Some assets fail to download
Causes:
- Network timeout
- Asset URL expired
- Permissions issue
Solution:
- Re-run export (it will skip existing files)
- Check asset URLs in Contentful
- Verify network connectivity
Symptom: Export crashes with memory error
Solution:
# Increase Node.js memory
node --max-old-space-size=4096 export-script.jsTips:
- Run during off-peak hours
- Use
--max-allowed-limit 1000 - Check network speed
- Consider exporting in smaller chunks
Symptom: Assets have empty URLs in JSON
Check:
# Verify assets in Contentful UI
# Some assets might be processing or failed to upload originallyBefore running batch migration, verify:
- Export completed successfully (no errors)
-
exported-space.jsonexists and is valid JSON - Asset directories exist (e.g.,
assets.ctfassets.net/) - Asset files downloaded (check file count)
- Export size matches expectations
- All content types exported
- All locales exported
- Backup created (optional but recommended)
# Count content types
jq '.contentTypes | length' contentful-export/exported-space.json
# Count entries
jq '.entries | length' contentful-export/exported-space.json
# Count assets
jq '.assets | length' contentful-export/exported-space.json
# Count downloaded files
find contentful-export -type f -name "*.*" | wc -l# Total export size
du -sh contentful-export/
# JSON file size
du -sh contentful-export/exported-space.json
# Asset files size
du -sh contentful-export/*.ctfassets.net/After successful export:
- ✅ Verify export integrity
- ✅ Create a backup copy
- ✅ Configure
batch-config.json - ✅ Proceed to IMPORT-GUIDE.md
Need help? Open an issue on GitHub