An interactive presentation framework built with Next.js, React, and impress.js that supports dynamic content loading from JSON files.
- 🎯 Dynamic Content: Edit presentations via JSON (no code required)
- 🎨 5 Built-in Themes: Purple, Blue, Green, Red, Orange
- 🌀 3D Transitions: Smooth impress.js animations
- ⚡ Hot Reload: Instant preview in development mode
- 📱 Responsive Design: Works on all screen sizes
- 🔒 Type-Safe: TypeScript validation for content structure
- 🚀 Static Generation: Optimal performance with Next.js
-
Install dependencies:
pnpm install
-
Edit content in
data/slides-content.json:{ "title": "Your Presentation", "slides": [ { "slideNumber": 1, "title": "Welcome", "description": "Your content here", "metadata": { "theme": "purple" } } ] } -
Run development server:
pnpm dev
-
Open browser: http://localhost:3000 🎉
All presentation content lives in data/slides-content.json:
{
"slideNumber": 1,
"title": "Your Title",
"subtitle": "Optional subtitle",
"description": "Main description text",
"bulletPoints": ["Point 1", "Point 2", "Point 3"],
"metadata": { "theme": "blue" }
}| Theme | Use Case | Colors |
|---|---|---|
purple |
Default, tech, creativity | Purple gradient |
blue |
Trust, professional, corporate | Blue gradient |
green |
Growth, nature, sustainability | Green gradient |
red |
Energy, passion, urgency | Red gradient |
orange |
Creativity, warmth, enthusiasm | Orange gradient |
📖 See docs/dynamic-content-guide.md for:
- Content schema reference
- Theme examples
- Best practices
- Troubleshooting
- Advanced usage
- Arrow Keys / Spacebar: Navigate slides
- Home: First slide
- End: Overview of all slides
- Swipe: Touch navigation (mobile)
slidies/
├── data/
│ └── slides-content.json # ✏️ Edit your content here
├── app/
│ ├── types/
│ │ └── slide-content.ts # TypeScript interfaces
│ ├── components/
│ │ ├── slides/
│ │ │ └── generic-slide.tsx # Slide component
│ │ ├── ImpressRoot.tsx # Main presentation logic
│ │ └── ImpressClient.tsx # impress.js wrapper
│ └── page.tsx # Entry point
├── docs/
│ ├── dynamic-content-guide.md # Complete documentation
│ └── story-5-slides-simplification.md
└── public/ # Static assets
- Framework: Next.js 15 (React 19)
- Language: TypeScript
- Styling: Tailwind CSS 4
- Animations: impress.js (via react-impressjs)
- Package Manager: pnpm
# Development
pnpm dev
# Production build
pnpm build
pnpm start
# Type checking
pnpm lintSee docs/dynamic-content-guide.md#adding-new-themes
Edit getSlideData() in app/components/ImpressRoot.tsx:
case "slide-1":
return { x: 0, y: 0, z: 0, scale: 0.5, rotateX: 0, rotateY: 0, rotateZ: 0 };Important: The project uses dual scaling:
- Impress.js scale:
0.5(controls 3D slide positioning) - Content scale:
0.5via CSS transform (ensures content fits in 750px container)
Both scales work together to prevent content overflow while maintaining readability.
To change how content fits within slides, edit generic-slide.tsx:
<div style={{ transform: 'scale(0.5)', transformOrigin: 'center' }}>- Increase value (e.g.,
0.6) for larger text - Decrease value (e.g.,
0.4) for more compact slides - Always test across all slides to ensure no content cropping
Create different JSON files in data/ and change the import in ImpressRoot.tsx.
Open source - feel free to use and modify!
Built with Next.js, React, and impress.js