Migrating from Sitecore JSS to Content SDK: Complete Runbook
Published: 21 May 2026

Introduction
Modernizing a Sitecore headless application is no longer just a dependency upgrade - it’s a complete architectural transformation.
In one of our recent enterprise implementations, we migrated a large-scale application from legacy Sitecore JSS (v22.12.3) to the modern Sitecore Content SDK (v2.1.0).
The primary goal was to eliminate maintenance-heavy custom scripts, simplify the rendering pipeline, improve build performance, and adopt a cleaner API-first architecture.
This blog documents the complete migration approach, architectural changes, component migration strategy, and production troubleshooting steps followed during the upgrade.
Why Migrate from JSS to Content SDK?
While Sitecore JSS provided flexibility for headless development, over time the application accumulated:
- Complex page-props plugin pipelines
- Heavy custom Node.js scripting
- Difficult component scaffolding workflows
- Deep framework dependencies
- Slower SSR and SSG builds
- Higher maintenance overhead
The new Sitecore Content SDK architecture simplifies this significantly.
Key Benefits After Migration:
- Centralized Sitecore client architecture
- Declarative CLI-driven component mapping
- Faster page rendering and build times
- Cleaner Next.js integration
- Reduced custom script maintenance
- Improved scalability for enterprise applications
Architecture Transformation
Legacy JSS Architecture
The previous implementation relied heavily on sequential plugin execution inside:
src/lib/page-props-factory/plugins/*
Each request processed multiple layers for:
- Site resolution
- Preview handling
- Personalization
- Layout props generation
- Dictionary loading
- Component-level data fetching
This architecture worked, but debugging and maintaining the system became increasingly difficult.
Modern Content SDK Architecture
The migration replaced the entire plugin chain with a centralized Sitecore client:
import { SitecoreClient } from '@sitecore-content-sdk/nextjs/client';Now all content operations are executed through optimized async APIs for:
- Layout data
- Dictionary assets
- Component props
- Preview rendering
Major Improvement:
100% of the custom scripts inside the /scripts folder were removed.
Dependency Migration
Removed Legacy JSS Packages
npm uninstall @sitecore-jss/sitecore-jss-nextjs @sitecore-jss/sitecore-jss-cli @sitecore-jss/sitecore-jss-dev-tools @sitecore-cloudsdk/personalize
Installed Modern Content SDK Packages
npm install @sitecore-content-sdk/nextjs@^2.1.0 @sitecore-content-sdk/analytics-core@~2.1.0 @sitecore-content-sdk/events@~2.1.0
Installed CLI Tooling
npm install --save-dev @sitecore-content-sdk/cli@^2.1.0 npm-run-all2@~8.0.1
Cleaning Legacy Build Scripts
One of the biggest improvements was removing old scaffolding and bootstrap scripts.
Deleted Folders
- /scripts
- /src/temp
Deleted Legacy Modules
- src/lib/page-props-factory/index.ts
- src/lib/site-resolver/*
- src/lib/sitemap-fetcher/*
This significantly reduced project complexity and maintenance overhead.
Modern Build Pipeline
The old build process depended on custom bootstrap execution.
After migration, everything became CLI-driven.
{
"sitecore-tools:generate-map": "sitecore-tools project component generate-map",
"sitecore-tools:generate-map:watch": "sitecore-tools project component generate-map --watch",
"sitecore-tools:build": "sitecore-tools project build"
}This improved:
- Developer experience
- CI/CD reliability
- Component synchronization
- Build consistency
Centralized Sitecore Client
A unified Sitecore client became the single source of truth for all Sitecore communication.
import { SitecoreClient } from '@sitecore-content-sdk/nextjs/client';
import scConfig from 'sitecore.config';
const client = new SitecoreClient({
...scConfig,
});
export default client;Next.js Routing Refactor
The catch-all dynamic route was heavily simplified.
Before Migration
- Multiple sequential page-props plugins
- Complex preview handling
- Deep dependency chain
After Migration
page = context.preview
? await client.getPreview(context.previewData)
: await client.getPage(path, { locale: context.locale });Dictionary and component props are now fetched independently using optimized APIs.
Component Migration Strategy
Most component migrations followed three primary rules.
1. Replace Legacy Imports
import { Placeholder } from '@sitecore-content-sdk/nextjs';2. Replace Context Hooks
Old:
const { sitecoreContext } = useSitecoreContext();New:
const { page } = useSitecore();3. Remove HOC Wrappers
The old withPlaceholder() wrappers were removed completely.
Components are now exported directly, resulting in cleaner component architecture.
SXA Styles Integration
A dedicated helper component was introduced for dynamically injecting Sitecore-managed styles into the Next.js application.
const headLinks = client.getHeadLinks(layoutData, {
enableStyles,
enableThemes,
});This ensures proper SXA theme rendering in headless mode.
Analytics & Event Tracking
The migration also modernized analytics integration using native Content SDK plugins.
initContentSdk({
plugins: [
analyticsPlugin(...),
eventsPlugin(),
],
});Benefits:
- Cleaner tracking initialization
- Standardized analytics integration
- Better personalization readiness
Troubleshooting Build Issues
During migration, some common build synchronization issues occurred.
Recommended Cleanup Process
Remove-Item -Recurse -Force .next, .sitecore, node_modules npm install npm run build
Additional Validation Steps
- Verify .sitecore/component-map.ts generation
- Exclude test and story files from component mapping
- Validate import-map synchronization
Production Environment Variables
The following environment variables are required for production deployment:
- NEXT_PUBLIC_SITECORE_API_KEY
- NEXT_PUBLIC_SITECORE_API_HOST
- NEXT_PUBLIC_DEFAULT_SITE_NAME
- NEXT_PUBLIC_DEFAULT_LANGUAGE
Final Results
After completing the migration:
- Removed all legacy bootstrap scripts
- Eliminated plugin-heavy architecture
- Improved SSR and SSG performance
- Simplified component development workflows
- Reduced long-term maintenance effort
- Modernized analytics implementation
- Improved build stability
- Automated component mapping completely
Key Takeaways
- Content SDK significantly simplifies Sitecore headless architecture
- CLI-driven workflows reduce manual maintenance
- Removing custom scripts improves long-term scalability
- Centralized client architecture improves debugging and development speed
- Migration requires both dependency and architectural modernization
Final Thoughts
Migrating from Sitecore JSS to Content SDK is much more than a package upgrade.
It is a complete modernization of the headless delivery architecture.
The result is a cleaner, faster, more scalable, and easier-to-maintain enterprise implementation built for the future of Sitecore headless development.

Vikesh Bhavsar
Associate Senior Software Engineer – Sitecore XM Cloud & SXA
Vikesh is a Sitecore professional at Addact with 4 years of experience, specializing in Sitecore XM Cloud, SXA, XP, and headless implementations, and delivering scalable, performance-driven CMS platforms.