You made a content type change directly in the ContentGrid dashboard last week and now staging and production have different schemas. Nobody remembers exactly what changed. Schema migrations as code solve this: every change is a file in your repository, runs in order, and produces the same result in every environment.
Setting Up Migration Files
Create a migrations/ directory in your project root. Each migration is a JavaScript or TypeScript file with a timestamp prefix and a descriptive name:
- 20250519_001_add-author-field.ts
- 20250519_002_rename-excerpt-to-summary.ts
- 20250519_003_add-published-at-index.ts
Each file exports a up() function that applies the change and an optional down() function that reverses it. The ContentGrid SDK provides methods for every schema operation: createField, deleteField, renameField, changeFieldType, and createContentType.
Writing a Migration
A typical migration file looks like this in structure:
- Import the ContentGrid Management client.
- Export an up() async function.
- Inside up(), call SDK methods to add, rename, or remove fields.
- Export a down() async function that reverses the change.
For a field rename, up() calls client.renameField({ contentType: 'post', from: 'excerpt', to: 'summary' }). The down() function calls the same method with from and to swapped. Keep migrations small and focused on one change each.
Running Migrations
The ContentGrid CLI tracks which migrations have run using a migration log stored in your ContentGrid space. Run migrations with:
- contentgrid migrate up --env development — run pending migrations on development.
- contentgrid migrate up --env staging — run on staging after testing.
- contentgrid migrate up --env production — run on production during your deploy.
- contentgrid migrate down --env development — roll back the last migration during development.
Add the production migration command to your CI/CD pipeline, running it after the build but before the new front-end code deploys. This ensures the schema is ready before code that depends on it goes live.
Handling Destructive Migrations
Field deletions and type changes are destructive — they can lose data. Follow this pattern for any destructive change:
- Add the new field first and deploy the front-end code to use it.
- Write a data migration script to copy values from the old field to the new field for all existing entries.
- Run the data migration and verify the values are correct.
- Delete the old field in a separate migration after the front-end no longer references it.
This expand-and-contract pattern means you never have a moment where the schema change and the code change are out of sync. It takes two deploys instead of one, but it eliminates data loss and downtime.
Ready to start tracking your competitors?
ContentGrid automatically monitors competitor websites, emails, and social media — and delivers structured intelligence straight to your inbox.