# Migration checklist, troubleshooting, and next steps

- **Authors:** Tim Benniks
- **Published:** 2026-04-27T10:09:45.761Z
- **Updated:** 2026-04-27T10:10:26.951Z
- **Tags:** sdk, api, headless, i18n, automation

---

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:

```javascript
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:

```javascript
const query = stack.contentType('blog').entry().query();
```

Then reapply filters, sorting, references, limits, and locale behavior one by one.

### Sorting changed

Add explicit sorting:

```javascript
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:

```javascript
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:

- [TypeScript Delivery SDK reference](https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/typescript/reference)


- [JavaScript Delivery SDK reference](https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/javascript-browser/reference)


- [Migration from JavaScript to TypeScript Delivery SDK](https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/typescript/migrate-from-javascript-to-typescript)



## 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.



---

## Chapter Navigation

**← Previous:** [Using the TypeScript Delivery SDK in JavaScript projects](https://developers.contentstack.com/guides/migrating-from-the-javascript-delivery-sdk-to-the-typescript-delivery-sdk/using-the-typescript-delivery-sdk-in-javascript-projects)

**Next →:** [AI agent migration playbook](https://developers.contentstack.com/guides/migrating-from-the-javascript-delivery-sdk-to-the-typescript-delivery-sdk/ai-agent-migration-playbook)
