Step-by-step guide for create and implementing your header using Partial Design + Next.js (Headless).

PART 1: Create Header via Partial Design (SXA)
1. Go to Presentation β Partial Designs
Navigate:
/sitecore/content/YourSite/Presentation/Partial Designs
- Create a new Partial Design:
Header
2. Add Header Rendering
Open the Header Partial Design:
- Click Edit
- Add rendering:
- Your custom Header Rendering (or SXA Navigation + Image components)
Place it in a placeholder like:
headless-header
If using Image component:
- Click the component
- Click Edit Component Properties
- Select image field or media item
3. Assign Data Source
For your header rendering:
- Set Data Source to:
/sitecore/content/YourSite/Data/Header/Main Header
π‘ This keeps your header reusable and centralized.
4. Create a Page Design
Go to:
/sitecore/content/YourSite/Presentation/Page Designs
- Create: Default Page Design
5. Attach Partial Design to Page Design
Inside Page Design:
- Add your Header Partial Design
- Also add:
- Footer (optional)
- Main content partial
Now your structure becomes:
Page Design
βββ Header (Partial Design)
βββ Main Content
βββ Footer
6. Assign Page Design to Pages
Go to your page (e.g., Home):
- Open Experience Editor
- Assign:
π Default Page Design
Now header is global across all pages using that design.
7: Save & Publish
Click:
- β Save
- β Publish
PART 2: Headless Layout Output
When using Layout Service:
/sitecore/api/layout/render/jss?item=/&sc_lang=en
Youβll now see:
{
"route": {
"placeholders": {
"header": [
{
"componentName": "Header",
"fields": {
"logo": {...},
"navigationLinks": [...]
}
}
]
}
}
}Partial Design content is merged automatically into layout output.
PART 3: Next.js Implementation
1. Header Component
const Header = ({ fields }) => {
return (
<header className="header">
<img src={fields.logo?.value?.src} alt="logo" />
<nav>
{fields.navigationLinks?.map((item, i) => (
<a key={i} href={item.url}>
{item.title}
</a>
))}
</nav>
</header>
);
};2. Register Component
import Header from './components/Header';
export const components = {
Header,
}; 3. Render Header Placeholder
In your main layout:
<Placeholder name="header" rendering={rendering} />4. PartialDesignDynamicPlaceholder Component
In SXA Headless:
- Partial Designs use dynamic placeholders
- Sitecore injects a system component:
PartialDesignDynamicPlaceholder
But your Next.js app doesnβt have this component registered
Create this file:
/src/components/PartialDesignDynamicPlaceholder.tsx
Add this code:
const PartialDesignDynamicPlaceholder = ({ rendering }: any) => {
if (!rendering?.placeholders) return null;
return Object.keys(rendering.placeholders).map((name) => (
<Placeholder key={name} name={name} rendering={rendering} />
));
};Register Component (VERY IMPORTANT)
Open:
/src/lib/componentFactory.ts
Add:
import PartialDesignDynamicPlaceholder from '../components/PartialDesignDynamicPlaceholder';
export const components = {
PartialDesignDynamicPlaceholder,
};Name must EXACTLY match:
PartialDesignDynamicPlaceholder
Next.js + Sitecore JSS Project Structure
Hereβs a real-world folder structure π
/src
βββ components
β βββ Header.tsx
β βββ Footer.tsx
β
βββ lib
β βββ componentFactory.ts
β
βββ Layout.tsx
βββ pages
β βββ [[...path]].tsx
β
βββ styles
β βββ global.css
Header Component
// src/components/Header.tsx
import Link from 'next/link';
const Header = ({ rendering }) => {
const fields = rendering?.fields;
return (
<header className="header">
<div className="logo">
<img src={fields?.logo?.value?.src} />
</div>
<nav>
{fields?.navigationLinks?.map((item, i) => (
<Link key={i} href={item.url}>
{item.title}
</Link>
))}
</nav>
</header>
);
};
export default Header;Layout File
// src/Layout.tsx
import { Placeholder } from '@sitecore-jss/sitecore-jss-nextjs';
const Layout = ({ layoutData }) => {
const { route } = layoutData;
return (
<>
<Placeholder name="headless-header" rendering={route} />
<Placeholder name="main" rendering={route} />
<Placeholder name="headless-footer" rendering={route} />
</>
);
};
export default Layout;Verify Layout Placeholder
Make sure your layout has:
<Placeholder name="headless-header" rendering={route} />
<Placeholder name="headless-footer" rendering={route} />Restart Next.js App
npm run dev
or
yarn dev
or
jss start:connected
WHAT THIS COMPONENT DOES
It dynamically renders nested placeholders like:
"placeholders": {
"headless-footer": [
{
"componentName": "Container",
"placeholders": {
"container-1": [...]
}
}
]
}HOW THIS WORKS (IMPORTANT)
Without Partial Design:
- Header added manually to each page
With Partial Design:
- Header injected automatically via Page Design
- Fully reusable and maintainable
KEY BENEFITS
β One place to manage header
β No duplication
β Clean Helix architecture
β Works perfectly with Headless + Next.js
β Easy personalization later
PRO TIP (Very Important)
If you're using SXA Headless:
- Always use:
- Partial Design for global UI (Header/Footer)
- Page Design for structure
- Data folder for content
FINAL ARCHITECTURE
Data
βββ Header Content
Presentation
βββ Partial Designs
β βββ Header
β
βββ Page Designs
β βββ Default
β
βββ Renderings
βββ Header Component
FINAL FLOW (SIMPLE)
- Create Header β Partial Design
- Attach to Page Design
- Assign Page Design to pages
- Layout Service exposes header
- Next.js renders <Placeholder name="header" />
Common Mistakes (Avoid These)
- Not assigning Page Design
- Missing placeholder (header) in layout
- Component not registered in factory
- Wrong datasource path
Happy Coding!
