TLDW turns long-form YouTube videos into a structured learning workspace. Paste a URL and the app generates highlight reels, timestamped AI answers, and a place to capture your own notes so you can absorb an hour-long video in minutes.
The project is a Next.js 15 + React 19 application that wraps Google Gemini 2.5 models and Supadata transcripts with a polished UX. Supabase provides authentication, persistence, rate limiting, and profile preferences. The experience is optimized for fast iteration using Turbopack, Tailwind CSS v4, and shadcn/ui components.
- AI highlight reels with Smart (quality) and Fast (speed) generation modes, Play All playback, and theme-based re-generation.
- Gemini-powered quick preview, structured summary, suggested questions, and memorable quotes surfaced in parallel.
- AI chat grounded in the transcript with structured JSON responses, timestamp citations, and fallbacks when Gemini rate-limits.
- Transcript viewer that stays in sync with the YouTube player; click any sentence to jump or capture the quote.
- Personal notes workspace with transcript, chat, and takeaway sources plus an /all-notes dashboard for cross-video review.
- Authenticated library pages for saved analyses, favorites, generation limits, and Supabase-backed profile preferences.
- Aggressive caching of previous analyses, background refresh tasks, and rate limits for anonymous vs. signed-in users.
- Security middleware that enforces CSP headers, CSRF protection, body-size caps, and Supabase-backed rate limiting.
- Frontend stack: Next.js 15 App Router, React 19, TypeScript, Tailwind CSS v4, shadcn/ui, lucide-react, sonner toasts.
- Backend runtime: Next.js serverless route handlers with withSecurity middleware for CSRF, input validation (Zod), and rate caps.
- AI pipeline: lib/ai-processing.ts and lib/gemini-client.ts orchestrate Gemini 2.5 models with structured output schemas, cascading fallbacks, and transcript chunking.
- Transcript & metadata: Supadata API delivers transcripts; lightweight YouTube oEmbed calls pull thumbnails and titles.
- Persistence: Supabase stores video_analyses, user_videos (history + favorites), user_notes, profiles (topic generation mode, profile data), and rate_limits.
- Authentication: Supabase Auth with session refresh in middleware.ts; AuthModal drives sign-up prompts when limits are hit.
- Security: Global middleware adds CSP/HSTS headers, CSRF tokens for stateful requests, hashed IP identifiers for anonymous rate limiting, and request body size guards.
- / – Landing page with branded URL input, mode selector, and auth modal triggers when rate limits are reached.
- /analyze/[videoId] – Primary workspace: YouTube player, highlight reels, theme selector, summary/chat/transcript/notes tabs, suggestions, and note-saving flows.
- /my-videos – Auth-required library of previously analyzed videos with search, favorites, and quick resume.
- /all-notes – Auth-required notebook that aggregates notes across videos with filtering, sorting, markdown rendering, and deletion.
- /settings – Profile screen for updating name, password, viewing usage stats, and persisting preferred topic generation mode.
- Video ingestion: /api/video-info, /api/transcript, /api/check-video-cache, /api/video-analysis, /api/save-analysis, /api/update-video-analysis, /api/link-video.
- AI generation: /api/generate-topics, /api/generate-summary, /api/quick-preview, /api/suggested-questions, /api/top-quotes.
- Conversational tools: /api/chat (Gemini chat with citations) and /api/check-limit for pre-flight rate checks.
- User data: /api/notes, /api/notes/all, /api/toggle-favorite.
- Security utilities: /api/csrf-token and the shared withSecurity middleware (allowed methods, rate limits, CSRF validation).
- Node.js 18+ (Next.js 15 requires 18.18 or newer)
- npm (repo uses package-lock.json), though pnpm or yarn also work
- Supabase project (Auth + Postgres) and API keys for Supadata & Google Gemini
Create .env.local in the repo root:
| GEMINI_API_KEY | yes | Google Gemini API key (2.5 models) |
| SUPADATA_API_KEY | yes | Supadata transcript API key |
| NEXT_PUBLIC_SUPABASE_URL | yes | Supabase project URL |
| NEXT_PUBLIC_SUPABASE_ANON_KEY | yes | Supabase anonymous key |
| CSRF_SALT | yes | Long random string used to sign CSRF tokens |
| NEXT_PUBLIC_APP_URL | optional | Canonical app URL (defaults to http://localhost:3000) |
| YOUTUBE_API_KEY | optional | Enables additional metadata when available |
| UNLIMITED_VIDEO_USERS | optional | Comma-separated emails or user IDs allowed to bypass daily limits |
Generate a unique CSRF_SALT (e.g., openssl rand -base64 32). UNLIMITED_VIDEO_USERS entries are normalized to lowercase.
- Run SQL migrations in supabase/migrations/ using the Supabase SQL editor or CLI.
- Ensure the following tables exist (structure documented in CLAUDE.md): video_analyses, user_videos, user_notes, profiles, and rate_limits.
- Add the Postgres function upsert_video_analysis_with_user_link that stores analyses and links them to a user in user_videos (the production project contains the reference implementation—export it or recreate it before local testing).
- Enable email OTP/auth providers required by your login flow and configure redirect URLs to match NEXT_PUBLIC_APP_URL.
The dev server reaches out to Gemini and Supadata directly, so make sure those API keys have local allowlists if your project settings restrict origins.
- All state-changing requests must go through csrfFetch so that withSecurity can validate the token.
- Rate limiting records are stored in the rate_limits table; clear it when resetting dev limits.
- Topic generation mode (smart vs fast) is persisted per-profile and synced via useModePreference.
- middleware.ts refreshes Supabase sessions and adds security headers—keep it enabled when deploying to Vercel.
- Detailed architecture notes, prompts, and database expectations live in CLAUDE.md; review it before larger changes.
Issues and PRs are welcome. This repo uses the Anthropic Claude Code Action for automated pull-request reviews guided by CLAUDE.md. Please run npm run lint and double-check Supabase migrations before opening a PR.
Distributed under the GNU Affero General Public License v3.0.
.png)

