A modern full-stack Next.js 15 platform with CMS, auth, and Stripe integration - built to manage and sell online math courses with videos, quizzes, LaTeX, and interactive graphs.
- Full Authentication with BetterAuth - secure login, registration, and email verification powered by Resend.
- Admin CMS Dashboard - manage courses, lessons, and media directly through an integrated headless Payload CMS interface.
- Stripe Payments - sell courses with one-time payments using Stripe Checkout.
- Hybrid Lesson Delivery (SSR + SSG) - free lessons are pre-rendered for speed and SEO, while paid lessons use server-side rendering for secure, on-demand access.
- Caching & Revalidation β lesson and enrollment data are cached for performance and automatically refreshed via Payload CMS hooks or Stripe webhook when content or access changes.
- Protected media β paid lesson images restricted to enrolled users, with auto-generated blur placeholders and optional AWS S3 / Cloudflare R2 storage
- Mux Video Integration β video uploads through CMS and streaming, with signed URLs ensuring only enrolled users can access paid video lessons.
- LaTeX and Interactive Desmos Graphs β Lessons feature interactive graphs and clean LaTeX formatting, with settings like larger math font or colored symbols
git clone https://github.com/maciekt07/nextjs-math-course cd nextjs-math-coursenpm installCreate a .env file in the root directory. Use .env.example as a template. Environment variables are fully typed and validated for both dev and build.
Both PostgreSQL (for main app data) and MongoDB (for Payload CMS) run via Docker Compose
docker compose up -dTip
View Database with Drizzle Studio
npm run db:studionpm run db:pushnpm run stripe:webhookUse these Stripe test card details to simulate a successful payment:
- Card Number:
4242 4242 4242 4242 - Expiration Date: Any future date
- CVC: Any 3-digit code
Development mode:
npm run devProduction preview:
npm run previewThe application should now be running at http://localhost:3000
Once the app is running, you can access the CMS at:
-
Create your admin account on first visit
-
Use the panel to manage courses, lessons, and media
You can add interactive Desmos graphs directly in markdown lessons:
::desmos{url="https://www.desmos.com/calculator/your-graph-id"}
Note
By default, the embedded version displays only the graph. If you set noEmbed=true, it will open the full Desmos calculator with all its tools and controls.
::desmos{url="https://www.desmos.com/calculator/your-graph-id" noEmbed=true}You can include math expressions in your lessons using standard Markdown + LaTeX syntax:
Inline math: $E = mc^2$ Block math: $$ f'(x) = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h} $$For more details, see the Markdown + LaTeX documentation
You can highlight important content or tips using custom callout blocks like note, tip, important, warning, etc.
:::note This is a note ::: :::tip{title="Remember"} This is a tip with a custom title :::
- Go to the Lessons collection in the CMS.
- In the top-right, open Filters β Add Filter.
- Select course β equals β your course.
- Use drag-and-drop to reorder the filtered lessons.
In paid lessons, math formulas are rendered lazily on the client as it scrolls into view, preventing main-thread blocking and avoiding FPS drops on long pages with many formulas. Free lessons are fully SSGed, which requires no special optimization and also benefits SEO.
Illustrations used in this project are from Storyset, modified for personal use.
