MDX Notes
Wrap your MDX pages in consistent shells — headers, sidebars, footers. Learn how to build, nest, and conditionally swap layouts based on frontmatter.
Layouts wrap your MDX content in a consistent page structure. Think headers, footers, sidebars, nav — all applied automatically so you don't repeat yourself in every file.
How Layouts Work
A layout is just a React component. Your compiled MDX content gets passed in as children, and any frontmatter data comes along as props.
// Basic layout concept
// Your MDX content becomes the children of the layout component
<Layout {...frontmatterProps}>
<YourMDXContent />
</Layout>That's it. Nothing magical.
Creating Layout Components
Basic Layout
// layouts/BaseLayout.jsx
import React from 'react';
import Header from '../components/Header';
import Footer from '../components/Footer';
import SEO from '../components/SEO';
export default function BaseLayout({ children, title, description, author }) {
return (
<div className="base-layout">
<SEO title={title} description={description} />
<Header />
<main className="content-wrapper">
<article className="prose prose-lg max-w-4xl mx-auto py-8">
{title && <h1 className="page-title">{title}</h1>}
{author && (
<p className="text-gray-600 text-sm">By {author}</p>
)}
{children}
</article>
</main>
<Footer />
</div>
);
}Using a Layout via Export
In your MDX file, set the layout with a default export:
Using a Layout via Configuration
With frameworks like Next.js, you can set layouts globally instead of per-file:
Nested Layouts
You can stack layouts. A base layout handles the global shell, while a docs layout adds a sidebar. They compose together.
// layouts/DocsLayout.jsx
import React from 'react';
import BaseLayout from './BaseLayout';
import Sidebar from '../components/Sidebar';
import TableOfContents from '../components/TableOfContents';
import Breadcrumbs from '../components/Breadcrumbs';
export default function DocsLayout({ children, title, description, toc }) {
return (
<BaseLayout title={title} description={description}>
<div className="docs-container flex gap-8">
{/* Left Sidebar - Navigation */}
<aside className="w-64 shrink-0 hidden lg:block">
<Sidebar />
</aside>
{/* Main Content */}
<div className="flex-1 min-w-0">
<Breadcrumbs />
<div className="docs-content">
{children}
</div>
</div>
{/* Right Sidebar - Table of Contents */}
<aside className="w-56 shrink-0 hidden xl:block">
<TableOfContents items={toc} />
</aside>
</div>
</BaseLayout>
);
}Layout Props and Frontmatter
Frontmatter data flows straight into your layout as props. You can control layout behavior from the MDX file itself:
Your content here receives the layout specified in frontmatter...Then you resolve which layout to use:
Conditional Layouts Based on Frontmatter
You can pick layouts dynamically based on what's in the frontmatter:
// Conditional layout with feature flags
export default function SmartLayout({ children, ...props }) {
const { sidebar = true, toc = true, fullWidth = false, theme } = props;
return (
<div className={`layout ${theme === 'dark' ? 'dark' : ''}`}>
<div className={`flex ${fullWidth ? 'max-w-full' : 'max-w-7xl mx-auto'}`}>
{sidebar && <Sidebar />}
<main className="flex-1 px-6 py-8">
{children}
</main>
{toc && <TableOfContents />}
</div>
</div>
);
}Layout Composition Patterns
Higher-Order Layout Pattern
A factory function that spits out configured layouts:
// createLayout.js - Layout factory
export function createLayout(options = {}) {
const {
showHeader = true,
showFooter = true,
showSidebar = false,
maxWidth = '4xl',
padding = '8',
} = options;
return function ComposedLayout({ children, ...props }) {
return (
<div className="min-h-screen flex flex-col">
{showHeader && <Header {...props} />}
<div className="flex flex-1">
{showSidebar && <Sidebar {...props} />}
<main className={`flex-1 max-w-${maxWidth} mx-auto p-${padding}`}>
{children}
</main>
</div>
{showFooter && <Footer />}
</div>
);
};
}
// Usage
const DocsLayout = createLayout({ showSidebar: true, maxWidth: '6xl' });
const BlogLayout = createLayout({ maxWidth: '3xl', padding: '12' });
const LandingLayout = createLayout({ showSidebar: false, showFooter: true, maxWidth: 'full' });Slot-Based Layout Pattern
Let MDX pages inject content into specific regions:
Passing Data to Layouts
Via Context Providers
// layouts/DataLayout.jsx
import { createContext, useContext } from 'react';
const LayoutContext = createContext({});
export function useLayoutData() {
return useContext(LayoutContext);
}
export default function DataLayout({ children, ...frontmatter }) {
const layoutData = {
...frontmatter,
breadcrumbs: generateBreadcrumbs(frontmatter.slug),
navigation: getNavigation(frontmatter.section),
editUrl: `https://github.com/repo/edit/main/docs/${frontmatter.slug}.mdx`,
};
return (
<LayoutContext.Provider value={layoutData}>
<div className="data-layout">
<NavigationBar items={layoutData.navigation} />
<main>{children}</main>
<EditLink url={layoutData.editUrl} />
</div>
</LayoutContext.Provider>
);
}Via Compilation Step
Common Layout Patterns
Documentation Layout
Landing Page Layout
export default function LandingLayout({ children, hero, cta }) {
return (
<div className="landing-layout">
<NavBar transparent />
{hero && <HeroSection {...hero} />}
<div className="landing-content">{children}</div>
{cta && <CTASection {...cta} />}
<Footer variant="marketing" />
</div>
);
}Performance Tips
| Technique | Benefit |
|---|---|
| Memoize layout components | Prevents re-renders when only content changes |
| Use CSS Grid for layout structure | Hardware-accelerated, no JS layout shifts |
| Lazy load sidebar/TOC | Reduces initial bundle for mobile users |
| Static generation of layouts | Zero runtime layout computation |
Best Practice: Keep layouts focused on structure, not content logic. Move data fetching to page-level getStaticProps or loaders, and pass results as props. This keeps layouts pure and reusable.Layouts are the skeleton of any MDX-driven site. Get composition and conditional rendering right, and adding new page types becomes trivial.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for MDX Layouts.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this MDX Tutorial topic.
Search Terms
mdx-tutorial, mdx tutorial, mdx, tutorial, advanced, layouts, mdx layouts
Related MDX Tutorial Topics