skills /nextjs-mdx-presentation
Next.js Referenced

nextjs-mdx-presentation

Build MDX-driven presentation systems in Next.js where AI outputs .mdx files that compose prebuilt slide components. Includes deck engine, slide components (TitleSlide, ContentSlide, TwoColumn, etc.), Framer Motion transitions, presenter mode with speaker notes, theme system, keyboard controls, and PDF export. Use for creating presentation frameworks or generating slide decks.

Next.js MDX Presentation System

Build presentation systems where MDX is the API: AI outputs .mdx files that compose prebuilt slide components. This creates a lightweight, controllable deck engine optimized for Next.js App Router.

⚠️ MUST READ FIRST

Before implementing anything, read CRITICAL-PATTERNS.md - Contains non-negotiable patterns for:

  • Full-screen slides (NO small cards!)
  • Maximized images (NO tiny charts with borders!)
  • Circular gradient overlays
  • Three required themes (Corporate, Academic, Minimal)
  • Color contrast rules

Common mistakes that make presentations look unprofessional:

  • Using max-w-6xl aspect-[16/9] instead of full screen
  • Adding borders/shadows to images
  • White text on white backgrounds
  • Missing circular overlays

When to Use This Skill

  • User asks to build a presentation system or slide framework
  • User wants to create slide decks programmatically
  • User needs presenter tools (speaker notes, preview, timer)
  • User requests themed presentations with consistent styling
  • User mentions frameworks like Reveal.js, Spectacle, or MDX Deck

Core Concept

MDX as API: The AI (or author) writes MDX that imports and composes slide components. The deck engine handles navigation, transitions, and presentation features.

hljs mdx
--- title: "My Presentation" theme: "theme-academic" --- import { TitleSlide, ContentSlide } from "@/components/slides" <TitleSlide title="Welcome" subtitle="An MDX-powered deck" /> --- <ContentSlide title="Key Points"> - Point one - Point two </ContentSlide>

Architecture Overview

/app/presentations/[slug]/page.tsx # Audience view /app/presentations/presenter/[slug]/ # Presenter console /components /deck # Engine: DeckProvider, DeckViewport, Keyboard, Steps /slides # Components: TitleSlide, ContentSlide, TwoColumn, etc. /lib mdx-deck.ts # Parse MDX, split slides by `---`, compile with rehype /content/decks/<slug>/index.mdx # Deck files

Prerequisites

hljs bash
# Required node >= 18.0.0 npm >= 9.0.0 # Will be installed during setup next >= 15.0.0 react >= 19.0.0

Required packages:

hljs bash
npm i framer-motion next-mdx-remote gray-matter npm i -D rehype-slug rehype-autolink-headings rehype-pretty-code remark-gfm shiki

Quick Start Workflow

1. Create Core Infrastructure

Deck Provider (components/deck/DeckProvider.tsx):

  • Manages slide index state
  • Syncs with ?slide=n URL param
  • Provides next(), prev(), set(n) navigation

Deck Viewport (components/deck/DeckViewport.tsx):

  • Renders slides in aspect-ratio container (16:9, 4:3, 9:16)
  • Animates transitions with Framer Motion
  • Uses AnimatePresence for smooth slide changes

Keyboard Controls (components/deck/Keyboard.tsx):

  • Arrow keys, Space, Home, End navigation
  • Respect reduced-motion preference

2. Create Slide Components

Build atomic slide layouts as React components:

  • TitleSlide: Hero slide with title/subtitle
  • ContentSlide: Title + body content
  • TwoColumn: Left/right split layout
  • ImageSlide: Full image with caption
  • QuoteSlide: Centered blockquote

See references/components-guide.md for detailed component patterns.

3. MDX Compilation Pipeline

lib/mdx-deck.ts:

  1. Load deck file from content/decks/<slug>/index.mdx
  2. Parse frontmatter (title, author, theme, aspect)
  3. Split content by \n---\n delimiter
  4. Compile each slide section with next-mdx-remote
  5. Apply rehype plugins (syntax highlighting, slugs, links)
  6. Return { meta, slides } object

4. Deck Route

hljs tsx
// app/presentations/[slug]/page.tsx export default async function DeckPage({ params }) { const { meta, slides } = await loadDeck(params.slug) return ( <div className={meta.theme}> <DeckProvider count={slides.length}> <ProgressBar /> <DeckViewport slides={slides} aspect={meta.aspect} /> <Keyboard /> </DeckProvider> </div> ) }

Essential Features

Steps/Appear Animation

Reveal content incrementally within a slide:

hljs tsx
<Steps> <Step index={1}>First point appears</Step> <Step index={2}>Then second</Step> </Steps>

Track step progress in useDeck() hook, animate with Framer Motion.

Presenter Mode

Presenter console (/presentations/presenter/[slug]):

  • Grid layout: current slide (large) + next slide (preview)
  • Speaker notes area with <Notes> portal
  • Timer and slide counter

Notes component: Uses React portal to render notes in presenter view while hiding in audience view.

Theme System

Body classes from frontmatter:

hljs yaml
theme: "theme-academic" # or theme-corporate, theme-minimal

CSS variables (globals.css):

hljs css
.theme-academic { --font-head: "Merriweather", serif; --accent: 210 50% 40%; }

See references/theming-guide.md for complete theme documentation.

Print/PDF Export

Print stylesheet:

hljs css
@media print { @page { size: 1280px 720px; margin: 0; } .progress-bar { display: none !important; } * { animation: none !important; } }

Users print to PDF via browser. Optional: create /print/[slug] route with paginated layout.

Component API for MDX Authors

Export components in components/mdx-slide-components.tsx:

hljs tsx
export const components = { TitleSlide, ContentSlide, TwoColumn, ImageSlide, QuoteSlide, Steps, Step, Notes }

These become available in MDX:

hljs mdx
<TitleSlide title="..." subtitle="..." /> <ContentSlide title="...">Content here</ContentSlide> <TwoColumn left={<>Left</>} right={<>Right</>} /> <ImageSlide src="..." caption="..." /> <QuoteSlide author="...">Quote text</QuoteSlide>

Deep Linking & Navigation

  • URL format: /presentations/my-deck?slide=3
  • Keyboard: ←/→ (prev/next), Space (next), Home (first), End (last)
  • Progress bar: Visual indicator with click-to-jump
  • Optional mini-map: Thumbnail navigation grid

Accessibility

  • role="presentation" on deck container
  • Focus management: trap focus within current slide
  • Keyboard navigation without mouse dependency
  • Respect prefers-reduced-motion for transitions
  • ARIA labels on controls

AI Output Contract

When AI generates a deck, it should produce:

hljs mdx
--- title: "Presentation Title" author: "Author Name" date: "2025-10-27" theme: "theme-academic" aspect: "16:9" --- import { TitleSlide, ContentSlide, ... } from "@/components/slides" import { Steps, Step, Notes } from "@/components/deck" <TitleSlide title="..." subtitle="..." /> <Notes>Speaker notes for this slide</Notes> --- <ContentSlide title="..."> <Steps> <Step index={1}>First point</Step> <Step index={2}>Second point</Step> </Steps> </ContentSlide> --- [Additional slides separated by ---]

Progressive Implementation Strategy

Phase 1 (MVP):

  1. Deck provider with navigation state
  2. Basic slide components (Title, Content)
  3. MDX compilation pipeline
  4. Keyboard controls

Phase 2: 5. Framer Motion transitions 6. Steps/Appear incremental reveal 7. Theme system (3 presets) 8. Progress bar

Phase 3: 9. Presenter mode with notes 10. Print/PDF support 11. Advanced components (TwoColumn, Image, Quote) 12. Mini-map navigation

Bundled Resources

References (references/)

Load these when implementing specific features or needing detailed guidance:

  • setup-guide.md - Complete setup instructions, dependency configuration, and project structure
  • components-guide.md - Detailed component patterns and API documentation for all slide types
  • theming-guide.md - Theme system, CSS variables, and customization patterns

Assets (assets/)

Copy-paste ready templates and boilerplate:

  • deck-template/ - Complete working example deck with all slide types and features
  • component-templates/ - Boilerplate code for creating custom slide components

Scripts (scripts/)

Automation utilities:

  • init-presentation.sh - Automated project setup script

Common Patterns

Multi-step reveal:

hljs tsx
const [step, setStep] = useState(0) // Advance step on navigation, animate items with index <= step

Synchronized views:

hljs tsx
// BroadcastChannel or WebSocket to sync presenter + audience windows

Custom transitions:

hljs tsx
// Override AnimatePresence variants per slide type const variants = { enter: { opacity: 0, scale: 0.95 }, center: { opacity: 1, scale: 1 }, exit: { opacity: 0, scale: 1.05 } }

Validation Checklist

  • Decks load from content/decks/<slug>/index.mdx
  • Slides split by --- delimiter
  • ?slide=n deep linking works
  • Keyboard navigation (arrows, space, home, end)
  • Framer Motion transitions respect reduced-motion
  • Steps/Appear reveal items incrementally
  • Presenter mode shows current + next + notes
  • Syntax highlighting with rehype-pretty-code
  • Themes switch via frontmatter
  • Aspect ratios enforced (16:9, 4:3, 9:16)
  • Print/PDF renders one slide per page
  • Basic a11y: focus management, ARIA roles

Tips for AI-Generated Decks

  1. Consistent structure: Always use frontmatter, imports, and --- delimiters
  2. Semantic components: Choose slide types that match content (TitleSlide for covers, ContentSlide for bullets, etc.)
  3. Step through reveals: Use <Steps> for progressive disclosure of complex ideas
  4. Speaker notes: Add <Notes> with context, timing, or talking points
  5. Theme selection: Match theme to content (academic for research, corporate for business, minimal for tech talks)

Troubleshooting

Slides not splitting: Ensure delimiter is exactly \n---\n (newline, three hyphens, newline)

Components not found: Verify exports in mdx-slide-components.tsx and imports in MDX

Transitions janky: Check prefers-reduced-motion, ensure AnimatePresence wraps slides

Theme not applying: Confirm body class matches CSS variable definitions

Print broken: Test @media print styles, verify @page size matches aspect ratio

Related Categories