Migration checklist, troubleshooting, and next steps
The migration is finished when your app can fetch the same published and preview content through the new SDK, not when the import statement compiles. Use this final chapter as a practical closeout list.
What you'll learn
How to review the migration before merge
Which behaviors to test manually
Which errors usually point to configuration issues
How to roll the migration out safely
Where to go next in the Contentstack docs
Migration checklist
Before merging, confirm that you have handled the core SDK changes:
contentstack package replaced with @contentstack/delivery-sdk
contentstack.Stack() replaced with contentstack.stack()
Stack.ContentType() calls replaced with stack.contentType()
Entry() calls replaced with entry()
Assets() or Asset() calls replaced with asset()
Query() calls replaced with entry().query()
language() replaced with locale()
ascending() and descending() replaced with orderByAscending() and orderByDescending()
toJSON() removed from migrated SDK chains
cache policy usage moved to @contentstack/persistance-plugin when needed
utility usage moved to @contentstack/utils when needed
Then confirm the application behavior:
homepage renders published content
listing pages render expected entries
detail pages resolve by UID or URL
references are included at the expected depth
rich text embedded items still render
assets include the fields your components expect
locale and fallback behavior matches the old implementation
preview mode can read draft content
route generation or static path generation returns the same routes
build, lint, and type checks pass where the project defines them
Troubleshooting
The app cannot initialize the stack
Check the import and initializer first:
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey,
deliveryToken,
environment,
});If this code is correct, check environment variable availability in the runtime. Server-only variables may not exist in browser code, and browser-exposed variables may need a framework-specific prefix.
A single entry fetch works, but a listing page fails
The entry fetch path and query path are different. Convert old Query() chains to the new query starting point:
const query = stack.contentType('blog').entry().query();Then reapply filters, sorting, references, limits, and locale behavior one by one.
Sorting changed
Add explicit sorting:
await stack.contentType('blog')
.entry()
.query()
.orderByDescending('published_date')
.find();Do not rely on implicit ordering when the UI depends on order.
Locale content is missing
Replace language() with locale() and verify that the requested locale has published entries:
await stack.contentType('page')
.entry('entry_uid')
.locale('fr-fr')
.includeFallback()
.fetch();If fallback content is expected, confirm that fallback behavior is configured in Contentstack and included in the request chain.
Cache behavior changed
If the old app set cache policies directly on the stack or query, install and configure the persistence plugin. If the app renders on the server, do not configure a browser-only store such as localStorage in a server-only code path.
Preview does not work
Separate preview troubleshooting from published delivery troubleshooting. A successful published request only proves that the delivery token and environment are correct.
Check preview token, preview host, Live Preview configuration, route handling, and any frontend preview mode flags. Then test a simple entry before testing a page with references or embedded items.
Rollout strategy
For larger sites, do not migrate every content fetch in one pull request unless the Contentstack access layer is already centralized.
A safer rollout is:
Add the new SDK behind a wrapper.
Migrate one low-risk page or route.
Compare the old and new response shapes.
Migrate shared helpers.
Migrate high-traffic pages.
Migrate preview and cache behavior.
Remove the old SDK after no imports remain.
Use logs or temporary response comparison in development if your page rendering hides missing fields.
Next steps
After the migration, consider adding typed content shapes for the content types your team changes most often. Start with content types that power routes, navigation, landing pages, or product pages.
Useful references:
Key takeaways
The migration is complete when published delivery, preview delivery, references, assets, locales, and route generation all work.
Query chains need the most careful review.
Cache and utility behavior may require separate packages.
JavaScript projects can use the TypeScript Delivery SDK without converting the whole codebase.
Typed response shapes can be added gradually after the runtime migration is stable.
Frequently asked questions
When is the SDK migration considered complete?
When your app can fetch the same published and preview content as before, including references, assets, locales, and route generation.
How do I replace the old Query() chain in the new Delivery SDK?
Start queries from the entry chain: stack.contentType('blog').entry().query(), then reapply filters, sorting, references, limits, and locale step by step.
Why did my listing pages break when single entry fetches still work?
Single entry fetch and listing queries use different chains in the new SDK. Migrate Query() usage to entry().query() and rebuild the query incrementally.
How do I fix missing localized content after migrating?
Replace language() with locale() and confirm the locale has published entries. If you expect fallback, ensure includeFallback() is in the request and fallback is configured.
What should I check if preview works differently than published delivery?
Verify preview token, preview host, Live Preview configuration, route handling, and any preview-mode flags. Test a simple entry before pages with references or embedded items.