The Wait is Over: Sitecore Content SDK 1.3.1 with Next.js App Router Support

A Next.js Developer's Long-Awaited Journey into Modern Sitecore
Remember when Next.js 13 dropped the App Router in late 2022? While the React and Next.js community collectively gasped at the paradigm shift - server components, streaming, nested layouts, and a fundamentally different mental model - those of us building CMS-driven applications watched from the sidelines. We experimented with hobby projects, built side apps, and marveled at the performance gains and DX improvements. But when it came to our production Sitecore applications? We stayed put in Pages Router land.
Fast forward to today, and Sitecore Content SDK 1.3.1 is here with General Availability (GA) support for the Next.js App Router.
If you're like me, a Next.js enthusiast who's spent years building with Sitecore's headless architecture - this isn't just another version bump. It's a fundamental shift in how we think about building CMS-driven applications. After watching the Next.js ecosystem evolve without us, we can finally ask the question that's been burning in our minds:
How did Sitecore pull this off? How do you make a completely CMS-driven, dynamic-by-nature application work with App Router's server-first architecture?
Why This Matters (And Why It Took So Long)
Let's be honest: CMS-driven applications are inherently tricky beasts when it comes to modern React patterns. Everything is dynamic - your routes come from Sitecore, your component tree is determined by content editors, and your data structure changes with every page. The traditional Next.js static generation model was never a perfect fit, but Pages Router gave us the flexibility to handle this dynamism through client-side patterns we'd grown comfortable with.
Then App Router arrived with a radically different philosophy: server-first, streaming, and React Server Components by default. The benefits were clear - smaller JavaScript bundles, better SEO, faster initial loads. But the question lingered: how do you reconcile a framework optimized for static-first with a CMS that's dynamic-first?
Sitecore took their time to get it right. They released it first in beta to get the feedback from community and eventually moved from Beta to stable 1.3.1, and that patience shows in the architecture.
What Makes This Release Different
This isn't just a "now you can use app/ instead of pages/" update. Content SDK v1.3.1 introduces full support for server components, streaming, and intuitive data-fetching patterns that align with Next.js's evolving framework. Let's talk about what that actually means:
1. Server Components as the Default Paradigm
Remember prop drilling layout service data through multiple component layers? Remember getStaticProps and getServerSideProps littering your catch-all route file? With App Router, developers can fetch data directly in component logic from XM Cloud's Layout Service, eliminating the need for client-side hydration or manual orchestration.
This is huge. Your Sitecore components can now be true server components, fetching their own data where needed, streaming content to the browser, and keeping your client-side JavaScript bundle lean.
The Code Difference:
// Pages Router (old way)
export async function getServerSideProps(context) {
const page = await client.getPage(context.params.path);
return { props: { page } };
}
// App Router (new way)
export default async function Page({ params }: PageProps) {
const { path } = await params; // Note: params is now a Promise!
const page = await client.getPage(path ?? [], { site, locale });
return <Layout page={page} />;
}
The data fetching happens right where you need it, in the component itself. No more prop drilling, no more getServerSideProps boilerplate.
2. Separation of Concerns & The AppPlaceholder
In the new SDK, specific attention has been paid to how components are resolved and rendered. The AppPlaceholder component is the new glue that holds everything together, designed specifically for the App Router context.
Coupled with this is the support for separate server and client component maps. The SDK generates:
The SDK generates two component maps:
.sitecore/component-map.ts- Server components (default, most components).sitecore/component-map.client.ts- Client components (only when interactivity is needed)
Think about what this means: you can now explicitly declare which Sitecore components should render on the server (most of them) and which need client-side interactivity (forms, carousels, interactive widgets). The framework handles the rest, automatically code-splitting and optimizing your bundles.
3. The Promise-Based API Revolution
One of the most noticeable changes when you first look at App Router code is that params and searchParams are now Promises.
// Old: Synchronous params
export default function Page({ params }) {
const { path } = params;
// ...
}
// New: Async params
export default async function Page({ params }: PageProps) {
const { path } = await params; // Unwrap the Promise
// ...
}
This change enables Next.js to start rendering parts of your page while other parts are still fetching data - a key enabler for streaming and better perceived performance.
4. Draft Mode: The New Preview Pattern
Remember managing preview mode with cookies and custom logic? App Router introduces draftMode() from next/headers - a cleaner, more integrated way to handle preview and editing scenarios.
import { draftMode } from 'next/headers';
export default async function Page({ params, searchParams }: PageProps) {
const draft = await draftMode();
let page;
if (draft.isEnabled) {
// Handle preview/editing mode
const editingParams = await searchParams;
if (isDesignLibraryPreviewData(editingParams)) {
page = await client.getDesignLibraryData(editingParams);
} else {
page = await client.getPreview(editingParams);
}
} else {
// Handle published content
page = await client.getPage(path ?? [], { site, locale });
}
}
5. Internationalization with next-intl
The i18n story has been modernized too. Sitecore now leverages next-intl, a mature library purpose-built for App Router. This means better type safety, deep integration with React Server Components, and alignment with widely accepted Next.js best practices rather than custom, proprietary implementations.
6. Streaming and Suspense Support
Streaming support enables faster time-to-interactive and unlocks hyper-fast personalization scenarios. This is the kind of feature that makes you rethink your entire architecture. Imagine streaming your page shell while personalized content loads in progressively. Imagine Sitecore-driven pages that feel as fast as static sites.
7. Future-Proofing for PPR and Beyond
The setup enables optional use of Partial Prerendering (PPR). While PPR is still evolving in Next.js, Sitecore has architected the SDK to support it. This allows static parts of your route to be prerendered while dynamic parts are streamed in, offering the best of both static and dynamic worlds.
Why I'm Excited (And You Should Be Too)
After years of building Sitecore applications with patterns that sometimes felt parallel to the main Next.js ecosystem, we now have a path that feels native.
By adopting App Router, Sitecore reduces the amount of code that runs in the browser, improving speed, SEO, and maintainability. But beyond the technical benefits, there's something deeper here: we're no longer playing catch-up. We're joining the ecosystem.
The patterns we learn building Sitecore apps with App Router are now directly applicable to any Next.js project. We're finally speaking the same language as the rest of the React world.
The Business Impact:
Performance: Smaller bundles mean faster page loads and better Core Web Vitals
SEO: Server-rendered by default means better search engine visibility
Developer Experience: Modern patterns mean easier onboarding and maintenance
Cost: Less JavaScript means lower bandwidth costs and better mobile performance
Future-Proofing: Aligned with Next.js direction means easier upgrades
The Developer Experience Impact:
Type Safety: Promise-based params with better TypeScript support
Less Boilerplate: No more
getServerSidePropseverywhereBetter Patterns: Composable middleware, route handlers, component maps
Community Alignment: Using the same patterns as the broader Next.js community
Tooling: Better integration with Next.js dev tools and debugging
Let's Begin
In this series, we'll roll up our sleeves and dive into the actual code. We'll explore:
Project Structure & Setup: How
app/differs frompages/.Server vs Client Components: Building decision trees for component rendering.
Data Fetching Patterns: Moving from
getServerSidePropsto async components.Middleware & Route Handlers: Deep dive into the composable architecture.
Content SDK 1.3.1 with App Router support is a major milestone. Let's make sure we understand what they built, why it matters, and how to use it effectively.
Have questions, thoughts, or things you're curious about? Drop them in the comments. This series is as much about my exploration as yours, and I'd love to know what aspects you're most interested in diving deep on.
Stay tuned for the next post where we'll dive into the project structure, setup process, and all the new features in the SDK.


