Rhetro: AI Podcast Application
A cutting-edge AI podcast application that simplifies content creation. It converts text into high-quality speech and generates eye-catching thumbnails using advanced AI models. Perfect for both seasoned podcasters and beginners, Rhetro streamlines the production process, letting you focus on delivering engaging content.
- Next.js 14 (App Router)
- TailwindCSS
- Shadcn UI
- Google TTS
- Gemini
- Clerk
- Convex
- Sentry
- Databuddy (analytics)
- Convert your written content into high-quality, natural-sounding speech, making podcast production faster and more efficient.
- Generate visually appealing and professional-looking thumbnails for your podcast with the help of advanced AI models, ensuring your podcast stands out.
rhetro.mp4
Rhetro is split between a Next.js frontend and a Convex backend-as-a-service. There is no custom server β all server-side logic runs as Convex functions (queries, mutations, actions, HTTP routes).
Browser βββΊ Next.js (App Router) βββΊ Convex (DB + Storage + Actions) βββΊ Google APIs (TTS / Gemini)
β β²
β β
βββ Clerk (auth + hosted UI) βββΊ svix webhook βββΊ Convex /clerk
Frontend β app/
- Route groups:
(auth)for/signin,/signup;(root)for the authenticated shell (create,discover,podcasts,profile). middleware.tsprotects every non-public route via Clerk.- Root layout wires up
ConvexClerkProvider(Convex client authenticated with Clerk JWTs),AudioProvider, and Databuddy analytics.
Backend β convex/
schema.tsβpodcasts(indexes onauthorId,views; search indexes on author/title/description),users(index onclerkId), andpodcastViews(unique viewer tracking).podcasts.ts,users.tsβ CRUD, search, unique view counting, top-creator queries. Mutations that write data require auth; delete is owner-only.files.tsβ issues pre-signed upload URLs for Convex Storage (authenticated only).googleTTS.tsβ Convex action calling Google Cloud TTS for MP3 synthesis.gemini.tsβ Convex action calling Geminigemini-3-pro-image-previewfor thumbnails.http.tsβPOST /clerkHTTP route that verifies svix signatures and mirrors Clerkuser.created/updated/deletedevents into theuserstable.auth.config.tsβ trusts the Clerk JWT issuer (CLERK_JWT_ISSUER_DOMAIN) soctx.auth.getUserIdentity()works inside queries/mutations.
Observability β Sentry is wired through next.config.mjs (withSentryConfig) plus sentry.{client,server,edge}.config.ts and instrumentation.ts.
| Component | Hosted on |
|---|---|
| Next.js app | Vercel |
| Convex backend | Convex Cloud |
| Auth | Clerk (hosted) |
| File storage | Convex Storage |
| AI inference | Google Generative Language API |
| Error tracking | Sentry |
| Analytics | Databuddy |
Pushing to main deploys the Next.js app to Vercel. The Convex backend is deployed separately with npx convex deploy (typically wired into the same CI step).
Two processes need to run side-by-side: the Next.js dev server and the Convex dev server.
npm install
npx convex dev # in one terminal β pushes convex/ to your dev deployment, regenerates _generated/
npm run dev # in another terminal β starts Next.js on http://localhost:3000Copy .env.example to .env.local and fill in:
| Variable | Source |
|---|---|
CONVEX_DEPLOYMENT |
Set automatically by npx convex dev (CLI-only, used to push code) |
NEXT_PUBLIC_CONVEX_URL |
Convex deployment URL β used by the browser to open the WebSocket |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY |
Clerk dashboard |
CLERK_SECRET_KEY |
Clerk dashboard |
CLERK_WEBHOOK_SECRET |
Clerk webhook endpoint pointing at <convex-url>/clerk |
NEXT_PUBLIC_CLERK_SIGN_IN_URL |
/signin |
NEXT_PUBLIC_CLERK_SIGN_UP_URL |
/signup |
Set these in the Convex dashboard (Environment Variables), not only in .env.local β Convex functions run on Convex Cloud:
| Variable | Source |
|---|---|
GOOGLE_GENERATIVE_AI_API_KEY |
Google AI Studio / Cloud β used by TTS + Gemini actions |
CLERK_WEBHOOK_SECRET |
Clerk webhook signing secret |
CLERK_JWT_ISSUER_DOMAIN |
Clerk Frontend API URL, e.g. https://your-instance.clerk.accounts.dev |