Run multiple slide decks in the same app with different URLs, fonts, and themes. Use basePath, exitUrl, and className to configure each deck independently.
Basic Setup
Create separate slide layouts for each deck:
app/
slides/
layout.tsx ← Main deck
[page]/page.tsx
slides-alt/
layout.tsx ← Alternate deck
[page]/page.tsx
Each layout gets its own SlideDeck instance with different configuration.
basePath
The basePath prop tells SlideDeck which URL prefix to use for slide navigation:
app/slides-alt/layout.tsx
import { SlideDeck } from 'nextjs-slides' ;
import { alternateSlides } from './slides' ;
export default function SlidesAltLayout ({
children ,
} : {
children : React . ReactNode ;
}) {
return (
< SlideDeck slides = { alternateSlides } basePath = "/slides-alt" >
{ children }
</ SlideDeck >
);
}
Now keyboard navigation goes to /slides-alt/1, /slides-alt/2, etc.
The default basePath is "/slides". Override it when your slides live at a different route.
exitUrl
Add an exit button (×) in the top-right corner that navigates to a specific URL:
< SlideDeck
slides = { slides }
basePath = "/slides-alt"
exitUrl = "/"
>
{ children }
</ SlideDeck >
The exit button triggers a ViewTransition with the deck-unveil animation:
::view-transition-old( .deck-unveil ) {
animation : nxs-deck-unveil 300 ms ease-out both ;
}
@keyframes nxs-deck-unveil {
to {
opacity : 0 ;
transform : scale ( 1.03 );
}
}
Keep SlideDeck as the direct child of the layout. Wrapping it in a <div> prevents the exit animation from working.
className for Scoped Styles
Use className to apply scoped font families and syntax themes to each deck:
app/slides-alt/layout.tsx
< SlideDeck
slides = { alternateSlides }
basePath = "/slides-alt"
exitUrl = "/"
className = "slides-alt-deck"
>
{ children }
</ SlideDeck >
Then override CSS variables in your global stylesheet:
/* Alternate deck: Playfair display font + Dracula theme */
.slides-alt-deck {
font-family : 'Playfair Display' , serif ;
/* Dracula syntax theme */
--nxs-code-bg : #282a36 ;
--nxs-code-border : #44475a ;
--nxs-code-text : #f8f8f2 ;
--sh-keyword : #ff79c6 ;
--sh-string : #f1fa8c ;
--sh-property : #8be9fd ;
--sh-class : #bd93f9 ;
--sh-entity : #50fa7b ;
--sh-tag : #50fa7b ;
--sh-identifier : #f8f8f2 ;
--sh-literal : #bd93f9 ;
--sh-comment : #6272a4 ;
--sh-sign : #f8f8f2 ;
}
Complete Example
Here’s a full setup for a second deck with Playfair + Dracula:
app/slides-alt/layout.tsx
app/slides-alt/[page]/page.tsx
app/slides-alt/slides.tsx
import { SlideDeck } from 'nextjs-slides' ;
import { alternateSlides } from './slides' ;
export default function SlidesAltLayout ({
children ,
} : {
children : React . ReactNode ;
}) {
return (
< SlideDeck
slides = { alternateSlides }
basePath = "/slides-alt"
exitUrl = "/"
className = "slides-alt-deck"
>
{ children }
</ SlideDeck >
);
}
Font Integration
For custom fonts via next/font or geist:
import { Playfair_Display } from 'next/font/google' ;
import { GeistSans } from 'geist/font/sans' ;
const playfair = Playfair_Display ({ subsets: [ 'latin' ], variable: '--font-playfair' });
export default function RootLayout ({ children } : { children : React . ReactNode }) {
return (
< html lang = "en" className = { ` ${ GeistSans . variable } ${ playfair . variable } ` } >
< body className = { GeistSans . className } > { children } </ body >
</ html >
);
}
.slides-alt-deck {
font-family : var ( --font-playfair ), serif ;
}
Props Summary
Prop Type Default Description basePathstring"/slides"URL prefix for slide routes exitUrlstring— URL for exit button (×). Shows in top-right when set. classNamestring— Additional class for the deck container
Use Cases
Conference talks : Host multiple presentations at /talks/keynote, /talks/workshop, etc.
Theme demos : Showcase different design systems or syntax themes side-by-side.
Multi-language : Separate decks for different languages with different font stacks.
A/B testing : Compare presentation styles with different layouts and themes.