Skip to main content
The nextjs-slides library inherits your app’s theme through CSS variables. You can customize fonts, colors, and syntax highlighting to match your brand or create multiple themed decks.

Theme Inheritance

Slides automatically use your app’s CSS variables:
  • --foreground - Primary text color
  • --background - Background color
  • --muted-foreground - Secondary/dimmed text
  • --primary - Primary brand color
  • --primary-foreground - Text on primary backgrounds
  • --border - Border color
  • --muted - Muted background color
No configuration needed - slides inherit your existing theme system.

Custom Fonts

Using Geist Fonts

Install and configure Geist fonts (optional):
Terminal
npm install geist
app/layout.tsx
import { GeistSans } from 'geist/font/sans';
import { GeistMono } from 'geist/font/mono';
import { GeistPixelSquare } from 'geist/font/pixel';

export default function RootLayout({ children }) {
  return (
    <html
      lang="en"
      className={`${GeistSans.variable} ${GeistMono.variable} ${GeistPixelSquare.variable}`}
    >
      <body className={GeistSans.className}>{children}</body>
    </html>
  );
}
globals.css
@theme inline {
  --font-sans: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif;
  --font-mono: var(--font-geist-mono), ui-monospace, monospace;
  --font-pixel:
    var(--font-geist-pixel-square), var(--font-geist-sans), ui-sans-serif,
    system-ui, sans-serif;
}
Use the pixel font on specific slides:
slides.tsx
<Slide key="end">
  <SlideHeaderBadge>nextjs-slides</SlideHeaderBadge>
  <SlideTitle className="font-pixel">
    That's the slide system.
  </SlideTitle>
  <SlideSubtitle>
    Compose these primitives to build any presentation
  </SlideSubtitle>
</Slide>

Using Custom Fonts

Load any Google Font or custom font:
app/slides-alt/layout.tsx
import { Playfair_Display, JetBrains_Mono } from 'next/font/google';
import { SlideDeck } from 'nextjs-slides';
import { slides } from './slides';
import './slides-alt.css';

const playfair = Playfair_Display({ 
  subsets: ['latin'],
  variable: '--font-playfair-display',
});

const jetbrains = JetBrains_Mono({ 
  subsets: ['latin'],
  variable: '--font-jetbrains-mono',
});

export default function SlidesAltLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className={`${playfair.variable} ${jetbrains.variable}`}>
      <SlideDeck
        slides={slides}
        basePath="/slides-alt"
        exitUrl="/"
        className="slides-alt-deck"
      >
        {children}
      </SlideDeck>
    </div>
  );
}
slides-alt.css
.slides-alt-deck {
  font-family: var(--font-playfair-display), ui-serif, Georgia, serif;
}

.slides-alt-deck .nxs-code-block,
.slides-alt-deck pre,
.slides-alt-deck code {
  font-family: var(--font-jetbrains-mono), ui-monospace, monospace;
}

Code Block Styling

Vercel-Inspired Theme (Default)

The default theme uses Vercel-inspired colors. Override these variables to customize:
globals.css
@theme inline {
  /* Code block container */
  --nxs-code-bg: #000;
  --nxs-code-border: #333;
  --nxs-code-text: #fff;
  
  /* Syntax highlighting */
  --sh-keyword: #ff79c6;      /* if, const, function, return */
  --sh-string: #a8ff60;       /* "strings" and 'strings' */
  --sh-property: #fff;        /* object.property */
  --sh-entity: #fff;          /* functionName() */
  --sh-class: #fff;           /* ClassName */
  --sh-tag: #ff79c6;          /* <div>, <Component> */
  --sh-identifier: #fff;      /* variable names */
  --sh-literal: #a8ff60;      /* true, false, null, numbers */
  --sh-comment: #6272a4;      /* // comments */
  --sh-sign: #fff;            /* =, {}, [], () */
}

Dracula-Inspired Theme

Here’s the alternate deck’s Dracula-inspired palette:
slides-alt.css
.slides-alt-deck {
  --nxs-code-bg: #282a36;
  --nxs-code-border: #44475a;
  --nxs-code-text: #f8f8f2;
  --sh-keyword: #ff79c6;
  --sh-string: #f1fa8c;
  --sh-property: #50fa7b;
  --sh-class: #bd93f9;
  --sh-entity: #8be9fd;
  --sh-tag: #ff79c6;
  --sh-identifier: #f8f8f2;
  --sh-literal: #bd93f9;
  --sh-comment: #6272a4;
  --sh-sign: #f8f8f2;
}
Example slide with custom syntax theme:
slides.tsx
<Slide key="code" align="left">
  <SlideBadge>SlideCode</SlideBadge>
  <SlideTitle>Custom syntax highlighting</SlideTitle>
  <SlideSubtitle>
    Dracula-inspired theme: purple, cyan, green, orange
  </SlideSubtitle>
  <SlideCode title="example.tsx">{`function Greeting({ name }: Props) {
  return (
    <div className="greeting">
      <h1>Hello, {name}!</h1>
      <button onClick={() => alert('Hi')}>
        Say hi
      </button>
    </div>
  );
}`}</SlideCode>
  <SlideNote>Syntax colors overridden in slides-alt.css</SlideNote>
</Slide>
@theme inline {
  --nxs-code-bg: #2e3440;
  --nxs-code-border: #3b4252;
  --nxs-code-text: #d8dee9;
  --sh-keyword: #81a1c1;
  --sh-string: #a3be8c;
  --sh-property: #88c0d0;
  --sh-class: #8fbcbb;
  --sh-entity: #88c0d0;
  --sh-tag: #81a1c1;
  --sh-identifier: #d8dee9;
  --sh-literal: #b48ead;
  --sh-comment: #616e88;
  --sh-sign: #d8dee9;
}

Multiple Decks with Different Styles

Create multiple themed decks using className and basePath:
1

Create the alternate deck files

app/
  slides/              # Main deck
    layout.tsx
    [page]/page.tsx
    slides.tsx
  slides-alt/          # Alternate deck
    layout.tsx
    [page]/page.tsx
    slides.tsx
    slides-alt.css     # Custom styles
2

Configure the alternate layout

app/slides-alt/layout.tsx
import { SlideDeck } from 'nextjs-slides';
import { slides } from './slides';
import './slides-alt.css';

export default function SlidesAltLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <SlideDeck
      slides={slides}
      basePath="/slides-alt"
      exitUrl="/"
      className="slides-alt-deck"
    >
      {children}
    </SlideDeck>
  );
}
3

Add scoped styles

app/slides-alt/slides-alt.css
.slides-alt-deck {
  font-family: var(--font-playfair-display), ui-serif, Georgia, serif;
}

.slides-alt-deck .nxs-code-block,
.slides-alt-deck pre,
.slides-alt-deck code {
  font-family: var(--font-jetbrains-mono), ui-monospace, monospace;
}

.slides-alt-deck {
  --nxs-code-bg: #282a36;
  --nxs-code-border: #44475a;
  --nxs-code-text: #f8f8f2;
  --sh-keyword: #ff79c6;
  --sh-string: #f1fa8c;
  --sh-property: #50fa7b;
  --sh-class: #bd93f9;
  --sh-entity: #8be9fd;
  --sh-tag: #ff79c6;
  --sh-identifier: #f8f8f2;
  --sh-literal: #bd93f9;
  --sh-comment: #6272a4;
  --sh-sign: #f8f8f2;
}
Keep SlideDeck as the direct child of the layout (no wrapper div) so the exit animation works correctly.

Complete Styling Example

Here’s a complete example with custom fonts and syntax theme:
app/slides-alt/slides.tsx
import {
  Slide,
  SlideBadge,
  SlideCode,
  SlideLink,
  SlideList,
  SlideListItem,
  SlideNote,
  SlideSplitLayout,
  SlideStatement,
  SlideStatementList,
  SlideSubtitle,
  SlideTitle,
} from 'nextjs-slides';

export const slides: React.ReactNode[] = [
  <Slide key="title" align="left">
    <SlideBadge>Alternate Deck</SlideBadge>
    <SlideTitle>Different fonts & syntax theme</SlideTitle>
    <SlideSubtitle>
      Playfair Display · JetBrains Mono · Dracula-inspired palette
    </SlideSubtitle>
  </Slide>,

  <Slide key="typography" align="left">
    <SlideBadge>Typography</SlideBadge>
    <SlideTitle>Serif headings, monospace code</SlideTitle>
    <SlideSubtitle>
      This deck uses Playfair Display for titles and JetBrains Mono for code
      blocks
    </SlideSubtitle>
    <SlideNote>
      Fonts and syntax theme applied via deck className in slides-alt.css
    </SlideNote>
  </Slide>,

  <Slide key="code" align="left">
    <SlideBadge>SlideCode</SlideBadge>
    <SlideTitle>Custom syntax highlighting</SlideTitle>
    <SlideSubtitle>
      Dracula-inspired theme: purple, cyan, green, orange
    </SlideSubtitle>
    <SlideCode title="example.tsx">{`function Greeting({ name }: Props) {
  return (
    <div className="greeting">
      <h1>Hello, {name}!</h1>
      <button onClick={() => alert('Hi')}>
        Say hi
      </button>
    </div>
  );
}`}</SlideCode>
    <SlideNote>Syntax colors overridden in slides-alt.css</SlideNote>
  </Slide>,

  <SlideSplitLayout
    key="split"
    left={
      <>
        <SlideBadge>Split layout</SlideBadge>
        <SlideTitle>Same primitives</SlideTitle>
        <SlideSubtitle>
          SlideSplitLayout, SlideStatement — all work the same
        </SlideSubtitle>
      </>
    }
    right={
      <SlideStatementList>
        <SlideStatement
          title="Fonts"
          description="Playfair Display + JetBrains Mono"
        />
        <SlideStatement title="Syntax" description="Dracula-inspired palette" />
        <SlideStatement
          title="Routing"
          description="Separate /slides-alt route"
        />
      </SlideStatementList>
    }
  />,

  <Slide key="end">
    <SlideTitle>That's the alternate deck</SlideTitle>
    <SlideSubtitle>Compose your own fonts and themes</SlideSubtitle>
    <SlideList>
      <SlideListItem>Override --sh-* for syntax colors</SlideListItem>
      <SlideListItem>Override --nxs-code-* for block styling</SlideListItem>
      <SlideListItem>Use font-* classes or CSS variables</SlideListItem>
    </SlideList>
    <SlideLink href="/" className="inline-block" variant="ghost">
      ← Back to home
    </SlideLink>
  </Slide>,
];

Customizing Individual Slides

You can apply custom styles to individual slides using className:
slides.tsx
<Slide key="special" className="bg-gradient-to-br from-purple-900 to-blue-900">
  <SlideTitle className="text-white">Special Slide</SlideTitle>
  <SlideSubtitle className="text-purple-200">
    This slide has a custom gradient background
  </SlideSubtitle>
</Slide>

Best Practices

Define your theme colors as CSS variables so they can be easily changed and reused across components.
If your app supports theme switching, test your slides in both light and dark modes to ensure readability.
Choose syntax colors with sufficient contrast. Test code blocks with various language constructs.
When creating multiple decks, use the deck’s className prop to scope your custom styles and avoid conflicts.

Next Steps

Basic Presentation

Learn the fundamentals of creating slides

Code Slides

Master syntax-highlighted code blocks

Components Reference

Explore all available components

Configuration

SlideDeck props and configuration

Build docs developers (and LLMs) love