The folder structure itself tells a story. Gone is the pages directory, replaced by a more intuitive app directory:
  
src/
├── app/
│   ├── [site]/
│   │   ├── [locale]/
│   │   │   └── [[...path]]/
│   │   │       └── page.tsx
│   │   └── layout.tsx
│   ├── api/
│   ├── layout.tsx
│   ├── not-found.tsx
│   └── global-error.tsx
├── components/
├── lib/
└── middleware.ts
This structure is not only cleaner but also more powerful, allowing for features such as route groups and nested layouts that were previously cumbersome to implement in the Pages Router.
Data Fetching in Server Components
With the App Router, Server Components are the default. This means you can fetch data directly within your components without getServerSideProps or getStaticProps.
   Here’s a look at the new page.tsx:
// src/app/[site]/[locale]/[[...path]]/page.tsx
import { notFound } from 'next/navigation';
import { draftMode } from 'next/headers';
import client from 'src/lib/sitecore-client';
import Layout from 'src/Layout';
export default async function Page({ params, searchParams }: PageProps) {
  const { site, locale, path } = await params;
  const draft = await draftMode();
  let page;
  if (draft.isEnabled) {
    const editingParams = await searchParams;
    // ... handle preview and design library data
  } else {
    page = await client.getPage(path ?? [], { site, locale });
  }
  if (!page) {
    notFound();
  }
  return <Layout page={page} />;
}
Notice how clean and concise this is. We’re using async/await directly in our component, and Next.js handles the rest. This is a huge win for developer experience.
A New Approach to Layouts
The App Router also introduces a more powerful way to handle layouts. You can now create nested layouts that are automatically applied to child routes. Here’s a simplified example from the starter kit:
// src/app/[site]/layout.tsx
import { draftMode } from 'next/headers';
import Bootstrap from 'src/Bootstrap';
export default async function SiteLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: Promise<{ site: string }>;
}) {
  const { site } = await params;
  const { isEnabled } = await draftMode();
  return (
    <>
      <Bootstrap siteName={site} isPreviewMode={isEnabled} />
      {children}
    </>
  );
}
  This SiteLayout component wraps all pages within a given site, providing a consistent structure and allowing for site-specific logic.
Migrating from JSS to the Content SDK: A Checklist
For those of us with existing JSS projects, the migration to the Content SDK is now a top priority. While Sitecore provides a comprehensive 
migration guide, here’s a high-level checklist to get you started:
    - Update Dependencies: Replace your jss-nextjscode> packages with the new@sitecore-content-sdk/nextjs packages.
- Centralize Configuration: Create sitecore.config.tsandsitecore.cli.config.tsto consolidate your settings.
- Refactor Data Fetching: Replace your data fetching logic with the new SitecoreClient class.
- Update Middleware: Consolidate your middleware into a single middleware.tsfile using thedefineMiddleware utility.
- Register Components: Manually register your components in the .sitecore/component-map.tsfile.
- Update CLI Commands: Replace your jssCLI scripts with the newsitecore-toolscommands.
- Remove Experience Editor Code: Clean up any code related to the Experience Editor, as it’s no longer supported.
This is a non-trivial effort, but the benefits in terms of performance, maintainability, and developer experience are well worth it.
The Rise of AI in Sitecore Development
Another fascinating aspect of the Content SDK is its deep integration with AI-assisted development. The repository now includes guidance files for Claude, GitHub Copilot, and other AI tools. This is more than just a novelty; it’s a serious productivity booster. These guidance files instruct your AI assistant on Sitecore-specific conventions, ensuring that the code it generates adheres to best practices.
I’ve been experimenting with this, and the results are impressive. When I ask my AI assistant to create a new component, it knows to:
    - Use the correct naming conventions.
- Create the necessary props interface.
- Use the Sitecore field components (<Text>,<RichText>, etc.).
- Handle missing fields gracefully.
This is a huge time-saver, ensuring that even junior developers can write high-quality, consistent code.
The Road Ahead
The release of Content SDK 1.2 and the introduction of the App Router mark a pivotal moment for Sitecore XM Cloud. It’s a clear signal that Sitecore is fully committed to modern, composable architecture and is dedicated to delivering a world-class developer experience.
For those of us who have been in the Sitecore trenches for years, this is an exciting time. We’re seeing the platform evolve in ways that will allow us to build faster, more robust, and more engaging digital experiences than ever before. The road ahead is bright, and I, for one, can’t wait to see what we build with these new tools.
References