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):
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 >
);
}
@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:
< 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-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:
@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-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:
< 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 >
Other Popular Themes
Nord
GitHub Dark
Solarized Dark
@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;
}
@theme inline {
--nxs-code-bg: #0d1117 ;
--nxs-code-border: #30363d ;
--nxs-code-text: #c9d1d9;
--sh-keyword: #ff7b72;
--sh-string: #a5d6ff;
--sh-property: #79c0ff ;
--sh-class: #ffa657;
--sh-entity: #d2a8ff;
--sh-tag: #7ee787 ;
--sh-identifier: #c9d1d9;
--sh-literal: #79c0ff ;
--sh-comment: #8b949e ;
--sh-sign: #c9d1d9;
}
@theme inline {
--nxs-code-bg: #002b36 ;
--nxs-code-border: #073642 ;
--nxs-code-text: #839496 ;
--sh-keyword: #859900 ;
--sh-string: #2aa198 ;
--sh-property: #268bd2 ;
--sh-class: #b58900;
--sh-entity: #268bd2 ;
--sh-tag: #859900 ;
--sh-identifier: #839496 ;
--sh-literal: #d33682;
--sh-comment: #586e75 ;
--sh-sign: #839496 ;
}
Multiple Decks with Different Styles
Create multiple themed decks using className and basePath:
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
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 >
);
}
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:
< 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
Use CSS variables for consistency
Define your theme colors as CSS variables so they can be easily changed and reused across components.
Test light and dark modes
If your app supports theme switching, test your slides in both light and dark modes to ensure readability.
Keep syntax themes readable
Choose syntax colors with sufficient contrast. Test code blocks with various language constructs.
Scope custom styles with className
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