A modern, AI-powered presentation generator that transforms documents into professional slides with real-time collaboration features.
Slideo is a full-stack application that combines the power of AI with modern web technologies to create stunning presentations. Users can upload documents (PDF, DOCX, TXT, MD), and the system will automatically generate professional slides with customizable themes and layouts.
- AI-Powered Slide Generation: Transform documents into professional presentations
- Real-time Collaboration: WebSocket-based live editing and chat
- Multi-format Support: Upload PDF, DOCX, TXT, and Markdown files
- Theme Customization: Professional themes with color scheme options and logo-based color extraction
- Export Options: Download presentations in multiple formats with 1:1 canvas-to-PPTX fidelity
- Professional Templates: 8+ curated Fabric.js templates for business presentations
- Responsive Design: Works seamlessly across all devices
- Modern Frontend: Next.js 14 with TypeScript and Tailwind CSS
- Real-time Backend: Python FastAPI with WebSocket support
- Authentication: Supabase-powered user management
- File Processing: Advanced document parsing and content extraction
- AI Integration: LLM-powered content analysis and slide generation
- Theme Engine: Advanced color palette extraction from logos and images with file upload and clipboard paste support
- Canvas-to-PPTX Export: Direct Fabric.js canvas export for pixel-perfect PowerPoint generation
slideflip/
βββ app/ # Next.js frontend application
βββ backend/ # Python FastAPI backend
βββ components/ # React components
βββ hooks/ # Custom React hooks
βββ lib/ # Utility libraries
βββ services/ # API services
βββ types/ # TypeScript type definitions
Slideo comes with 8+ professionally designed templates built with Fabric.js for pixel-perfect rendering:
- Hero Title: Bold opening slides with layered design and CTA buttons
- Professional Gradient: Modern gradient backgrounds with glass morphism effects
- Three Column KPIs: Clean metric displays with descriptive text
- Feature Comparison: Two-column analysis with checkmarks and action buttons
- Financial Consultant: Comprehensive financial analysis for earnings calls and financial reports
- Timeline: Horizontal project phases with milestone tracking
- Modern Cards: Three-column card layout with colored headers
- Data Visualization: Charts and metrics for analytics presentations
- Quote & Testimonial: Dark-themed inspirational content with attribution
All templates feature:
- 16:9 aspect ratio for standard presentations
- Professional color schemes optimized for business use
- Fabric.js rendering for 1:1 PowerPoint export fidelity
- Responsive design that works across all devices
- Framework: Next.js 14 with App Router
- Language: TypeScript
- Styling: Tailwind CSS + shadcn/ui
- Authentication: Supabase Auth
- Real-time: WebSocket connections
- Deployment: Vercel
- Framework: FastAPI (Python)
- WebSocket: WebSocket support for real-time communication
- File Processing: Multiple format support (PDF, DOCX, TXT, MD)
- AI Integration: LLM-powered content analysis
- Database: File-based storage with structured data
- Deployment: Docker-ready
- Node.js 18+
- Python 3.11+
- Supabase account
- Git
git clone <repository-url>
cd slideflip# Install dependencies
npm installIssue: Thumbnails across the application were experiencing overflow issues due to hardcoded scaling values that didn't account for different content sizes and container dimensions.
Solution: Implemented responsive scaling system across all thumbnail components:
- Dynamic Scale Calculation: Scale is now calculated based on container width using
Math.max(0.35, Math.min(0.75, containerWidth / 500)) - Responsive Width/Height: Width and height are dynamically calculated as
100 / scaleto prevent overflow - Window Resize Handling: Added resize observers to recalculate scaling when window size changes
- Smooth Transitions: Added fade-in effects and opacity transitions for better UX
- Overflow Protection: Added
overflow-hiddenand max-width/height constraints
Files Fixed:
app/presentations/page.tsx- Main presentations gridapp/presentations/[id]/page.tsx- Individual presentation viewapp/page.tsx- Home page presentations and templatesapp/templates/page.tsx- Templates gridcomponents/test-response-handler.tsx- Test component previews
Benefits:
- β No more thumbnail overflow issues
- β Consistent scaling across different screen sizes
- β Better responsive behavior
- β Improved user experience with smooth transitions
- β Maintains aspect ratios while preventing content overflow
The Content Planning step now renders the proposed plan using Markdown and uses a formatted WYSIWYG editor for changes (no raw Markdown or preview pane during editing).
Install the required packages (already listed in package.json):
npm install react-markdown remark-gfm marked turndownNo additional configuration is required.
cd backend
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Set up environment variables
cp .env.example .env
# Edit .env with your credentials and keys
# Start the backend server
python main.pyThe application uses Supabase for authentication and data storage. You'll need to:
- Create a Supabase project at supabase.com
- Get your project URL and anon key from the project settings
- Add them to your
.env.localfile:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_keyIf you encounter the error "infinite recursion detected in policy for relation 'workspace_members'" when uploading templates, run the SQL script in scripts/fix-workspace-members-recursion.sql in your Supabase SQL editor. This fixes RLS policy issues that can cause template uploads to fail.
Run the following migrations in order in your Supabase SQL editor:
001_create_slide_templates.sql- Creates the base slide templates table011_workspace_members_invitations.sql- Creates workspace collaboration system014_fix_slide_templates_and_workspace_members.sql- Fixes RLS recursion issues cd backend
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
python main.py
Quick start from project root:
```bash
# one-command start from repo root
npm run backend:start
The backend now supports server-side text extraction from PDF and DOCX uploads using pdfminer.six and python-docx.
- Ensure you have the virtual environment activated (
source venv/bin/activate). - Dependencies are included in
backend/requirements.txtand are installed with the step above. - The WebSocket upload flow automatically extracts text for
.pdfand.docxfiles via the backend. - The REST endpoint
POST /api/parse-documentswill mark PDFs/DOCX as βUploaded for server-side parsingβ and rely on the WebSocket pipeline for full extraction.
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- API Documentation: http://localhost:8000/docs
- Frontend README - Complete frontend guide
- Component Architecture
- Authentication Setup
- Real-time Features
- Backend README - Complete backend guide
- API Documentation
- WebSocket Communication
- File Processing
- Frontend Integration
- LLM Integration
- Content Storage
- Slide Generation
- HTML Features
- Implementation Summary
- pptxgenjs Documentation - Complete guide for PowerPoint generation
- Fabric.js Documentation - Complete guide for canvas-based slide editing and rendering
All variables are demonstrated in .env.example at the repo root. Copy it to .env (root) for the frontend and to backend/.env for the Python backend.
# Supabase client (required)
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
# Backend URLs used by the app
# For local development:
NEXT_PUBLIC_BACKEND_URL=http://localhost:8000
NEXT_PUBLIC_BACKEND_WS_URL=ws://localhost:8000
# For production (using deployed Google Cloud Run backend):
# NEXT_PUBLIC_BACKEND_URL=https://slideflip-backend-167734449742.us-central1.run.app
# NEXT_PUBLIC_BACKEND_WS_URL=wss://slideflip-backend-167734449742.us-central1.run.app
# AI keys
OPENAI_API_KEY=your_openai_api_key # required for AI features
TAVILY_API_KEY= # optional, research API for /api/research
# LDAP (optional; enable if using corporate directory)
LDAP_URL=ldap://your-ldap-server:389
LDAP_BASE_DN=dc=yourcompany,dc=com
LDAP_BIND_DN=cn=admin,dc=yourcompany,dc=com
LDAP_BIND_PASSWORD=your-admin-password
LDAP_USER_SEARCH_BASE=ou=users,dc=yourcompany,dc=com
LDAP_USER_SEARCH_FILTER=(uid={username})
LDAP_GROUP_SEARCH_BASE=ou=groups,dc=yourcompany,dc=com
LDAP_GROUP_SEARCH_FILTER=(member={userDn})
# Node scripts (do not expose to browsers)
SUPABASE_SERVICE_ROLE_KEY=If AI generation is unavailable (for example, OPENAI_API_KEY is missing or rate-limited), the Preview step will automatically load a local fallback slide so you can proceed through the flow:
- Fallback endpoint:
GET /api/fallback-slidereadstemplates/imported-02.htmland returns it asslideHtml. - If both AI and the fallback fail, the UI shows a placeholder image (
cat-slide-placeholder).
You can replace the fallback HTML by editing templates/imported-02.html.
This project uses Supabase Auth with Google as an OAuth provider. Configure it once for production and local development.
- Google Cloud Console β Credentials β Your Web OAuth client
- Authorized redirect URIs (exactly one for Supabase):
https://wyelvtfmvjturmxhoqfd.supabase.co/auth/v1/callback
- Authorized JavaScript origins (where your app is served from):
http://localhost:3000orhttp://localhost:3001(match your local port)- Your production origin (for example
https://slideflip.vercel.app)
Why: Google redirects back to Supabase, not directly to your app. Supabase finishes the OAuth handshake and then redirects the browser to your app using the URL you pass as redirectTo in code.
- Supabase β Authentication β URL configuration
- Site URL: your production site (e.g.,
https://slideflip.vercel.app). For localβonly testing, you can temporarily set this tohttp://localhost:3001. - Redirect URLs (allowlist): add the origins and callback routes you will use in development and production, for example:
http://localhost:3000http://localhost:3000/auth/callbackhttp://localhost:3001http://localhost:3001/auth/callbackhttps://slideflip.vercel.apphttps://slideflip.vercel.app/auth/callback
- App behavior (already implemented)
- The app initiates OAuth with
redirectTo: ${window.location.origin}/auth/callback. - The route handler at
app/auth/callback/route.tsexchanges the code for a session and then redirects to/(or thenextparam if present).
Troubleshooting
- If logging in on localhost sends you to production, your localhost URL is likely missing from Supabase βRedirect URLs,β so Supabase falls back to the Site URL.
- After changing Google or Supabase settings, wait 1β2 minutes, sign out, and retry. Clearing cookies for localhost and your prod domain can also help.
# Host/port and operational flags
HOST=0.0.0.0
PORT=8000
DEBUG=True
# Security
SECRET_KEY=your_secret_key
# Storage and limits
UPLOAD_DIR=uploads
MAX_FILE_SIZE=52428800
# AI key (backend will also read OPENAI_API_KEY if present here)
OPENAI_API_KEY=your_openai_api_keynpm run test
npm run test:integration
npm run test:e2ecd backend
python -m pytest tests/- Connect your GitHub repository to Vercel
- Configure environment variables in Vercel dashboard
- Deploy automatically on push to main branch
The app uses pptxgenjs for PPTX export in the browser. Some versions of this library include conditional imports of Node built-ins like node:fs and node:https inside the ESM bundle, which can cause bundlers to error when creating client chunks. To prevent this, the Next.js config stubs these modules for the browser build via aliases in next.config.ts:
// next.config.ts (excerpt)
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.alias = {
...(config.resolve.alias || {}),
'node:fs': false,
'node:https': false,
fs: false,
https: false,
'image-size': false,
path: false,
os: false,
'node:path': false,
};
// Optional compatibility fallbacks
// @ts-ignore
config.resolve.fallback = { ...(config.resolve.fallback || {}), fs: false, https: false, path: false, os: false };
}
return config;
}This ensures successful builds on Vercel while keeping runtime behavior unchanged in the browser.
cd backend
source venv/bin/activate
python main.pyThe backend is deployed to Google Cloud Run at: https://slideflip-backend-167734449742.us-central1.run.app
To deploy updates:
cd backend
gcloud builds submit --config cloudbuild.yaml .Configuration:
- Docker: Uses
backend/Dockerfilefor containerization - Cloud Build: Automated deployment via
backend/cloudbuild.yaml - Environment: Production variables set via Google Secret Manager
- Secrets: OpenAI API key stored securely in Secret Manager
- Resources: 2GB memory, 4 CPU, auto-scaling 1-2 instances
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]-
Documentation: Added comprehensive pptxgenjs documentation in
docs/pptxgenjs/covering installation, usage, features, and API reference -
Scripts: Added utility scripts in
scripts/directory for HTML to Markdown conversion -
Templates: Added weekly schedule template and YouTube description template
-
Build fix: added missing
lib/fabric-to-slide.tsand correctedlib/index.tsimports for Next.js bundling on Vercel. -
Invite acceptance flow: wrapped
useSearchParamsin a Suspense boundary for/invite/acceptto satisfy Next.js requirements and ensure production builds succeed. -
Rebranded visible UI text: from "SlideFlip" to "Slideo" across pages and templates; PPTX metadata now uses "Slideo" and "Slideo AI".
-
Added reusable card style
card-contrastinapp/globals.cssfor high-emphasis cards with thin white borders on dark backgrounds. Apply it viaclassName="card-contrast"alongsidevariant="glass"onCardcomponents. -
Updated
card-contrastto use a hairline0.5pxborder for a more refined outline on high-DPI displays. -
Added
builder-backgroundutility (Supabase-like pointillism) with a slightly lighter dark base. Applied to the builder root container inapp/build/page.tsx. -
Theme step UX: the Template selection and Color Palette sections are now collapsible using shadcn/ui
Accordion. This makes the page easier to scan while preserving all functionality.- New component:
components/ui/accordion.tsx - Updated:
components/builder/theme-step.tsx
- New component:
-
Templates now support Fabric.js/PptxGenJS JSON in Supabase:
- Added migration
009_update_slide_templates_for_fabric.sqlto addslide_json JSONBtoslide_templates. - API
app/api/examples/listnow prefersslide_templateswithslide_jsonand falls back to legacy HTML examples. - Template cards in
ThemeStepcan preview either HTML or Fabric JSON. - Seed examples:
templates/fabric/hero-title-01.json,templates/fabric/three-column-kpis-01.json. - Upsert endpoint:
POST /api/templates/upsert-fabricwith body{ id, name, description?, theme?, aspect_ratio?, tags? }readstemplates/fabric/{id}.jsonand stores it asslide_json.
- Added migration
curl -s -X POST http://localhost:3000/api/templates/upsert-fabric \
-H 'Content-Type: application/json' \
-d '{"id":"hero-title-01","name":"Hero Title"}'
curl -s -X POST http://localhost:3000/api/templates/upsert-fabric \
-H 'Content-Type: application/json' \
-d '{"id":"three-column-kpis-01","name":"Three Column KPIs"}'
# New: Professional Gradient template
curl -s -X POST http://localhost:3000/api/templates/upsert-fabric \
-H 'Content-Type: application/json' \
-d '{"id":"professional-gradient-01","name":"Professional Gradient"}'
# Note: `id` refers to the JSON filename under templates/fabric; the DB row id remains a UUID.Bulk import all Fabric templates found in templates/fabric at once:
curl -s -X POST http://localhost:3000/api/import-fabric-templates- Visit
/test-fabricto load all templates from/api/examples/listand preview them. - The page renders Fabric JSON on a canvas and shows the raw JSON for quick inspection.
- Sidebar includes "My Templates" entry linking to
/templates. - New page:
/templateslists templates fromslide_templateswith Fabric and HTML previews.
public/slideo-waitlist.pngβ static image used on the Waitlist page (QR/preview).- Landing page CTAs updated: all "Get Started" buttons now navigate to
'/auth/login'so users are prompted to sign in before creating content. - Landing page bottom CTA alignment: "View Examples" button height now matches "Start Free Trial" for a uniform appearance.
- Added a new route
'/waitlist'accessible from the sidebar as "Waitlist QR Code". Users can scan a QR or submit an email to join the waitlist. Emails are stored in Supabase tablewaitlist_emails(see migration004_create_waitlist_emails.sql). - The waitlist page shows both a dynamic QR that points to the current
/waitlistURL and a static QR image atpublic/slideo-waitlist.pngif you want to reuse a branded code offline.
- Install dependency for QR rendering in the frontend:
npm install react-qr-code- Apply Supabase migration to create the table:
-- supabase/migrations/004_create_waitlist_emails.sql
CREATE TABLE IF NOT EXISTS waitlist_emails (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
email TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_waitlist_unique_email ON waitlist_emails(email);- Usage
- Navigate to
Waitlist QR Codein the sidebar or go tohttp://localhost:3000/waitlist. - Scan the QR to open the page on mobile or submit an email in the form. Entries appear in the
waitlist_emailstable in Supabase.
-
Frontend Changes:
- Create feature branch
- Add components in
components/ - Update types in
types/ - Test with
npm run test
-
Backend Changes:
- Add API endpoints in
main.py - Create services in
src/services/ - Add models in
src/models/ - Test with pytest
- Add API endpoints in
-
Integration:
- Update WebSocket messages
- Test real-time features
- Verify API communication
- Frontend: ESLint + Prettier
- Backend: Black + isort
- TypeScript: Strict mode enabled
- Python: Type hints required
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow the existing code style
- Add tests for new features
- Update documentation
- Ensure all tests pass
- Test both frontend and backend integration
- Authentication Problems: Check Supabase configuration
- WebSocket Issues: Verify backend is running
- Build Errors: Clear node_modules and reinstall
- Import Errors: Check Python environment
- File Upload Issues: Verify upload directory permissions
- WebSocket Connection: Check firewall settings
- CORS Errors: Verify backend CORS configuration
- WebSocket Connection: Check WebSocket URL
- API Communication: Verify environment variables
- Code splitting and lazy loading
- Image optimization with Next.js
- Bundle analysis and optimization
- Caching strategies
- Async file processing
- Connection pooling
- Memory-efficient file handling
- Configurable concurrent processing
- Supabase authentication
- Environment variable protection
- Input validation
- XSS prevention
- File type validation
- File size limits
- Filename sanitization
- Error message sanitization
- Vercel Analytics
- Error tracking
- Performance monitoring
- User analytics
- Health check endpoints
- Connection statistics
- Processing metrics
- Error logging
This project is licensed under the MIT License - see the LICENSE file for details.
- Next.js for the amazing React framework
- Supabase for authentication and real-time features
- Tailwind CSS for utility-first styling
- shadcn/ui for beautiful components
- FastAPI for the high-performance Python API
- Documentation: Check the README files in each directory
- Issues: Create an issue on GitHub
- Discussions: Use GitHub Discussions for questions
- Email: Contact the development team
Made with β€οΈ by the Slideo Team