Next.jsReactSaaS启动器

nextjs-saas-starter — Next.js SaaS模板

作者 mailtrap

Mailtrap 官方维护的 Next.js SaaS 脚手架,以 Mailtrap 作为邮件层,集成 Supabase 认证与 Stripe 订阅计费,面向学习与个人项目。

看看你的网站会是什么样

浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。

3 个预览视图
桌面端首页1 / 3
桌面端截图首屏预览

由服务器浏览器实际访问页面后截取。

全部页面与视图 3

截图用于了解视觉与布局,交互效果请以实际项目为准。

采集于 2026-10-07查看来源

值得关注的模板亮点

从已有项目资料中,快速了解它的特点。

01

由 Mailtrap 官方维护,邮件层与 Mailtrap 的发送、模板、webhook 直接打通

02

集成 Supabase 认证与 Postgres,并提供本地 Docker 启动与迁移脚本

03

集成 Stripe 订阅计费,包含 Checkout 升级与 changePlan() 降级处理

04

提供 /admin/emails 邮件事件查看页,按 ADMIN_EMAILS 控制访问

05

附带 Stripe 与 Mailtrap 的本地 webhook 转发和测试脚本,无需 ngrok

06

采用 MIT 许可,允许免费使用、修改、商用和分发该版本代码

模板详细介绍

这是一个空白起步的 Next.js SaaS 脚手架,由 Mailtrap 官方维护。它把邮件、认证和订阅计费三块常见基础设施预先接好:邮件层使用 Mailtrap,认证与数据库使用 Supabase,订阅与支付使用 Stripe。仓库自带本地开发所需的脚本,例如通过 Docker 启动 Supabase Auth 与 Postgres、应用数据库迁移、生成 .env.local,并提供 Stripe 与 Mailtrap 的本地 webhook 转发与测试方式。

邮件流程分为两类:Supabase 的 Send Email Hook 把魔法链接、密码重置、邮箱变更等认证邮件交给 Mailtrap 发送;应用自身事件(欢迎邮件、团队邀请、账单相关通知)通过 src/lib/mailtrap 中的 sendEmail() 发送。计费方面,升级走 Stripe Checkout,降级通过 changePlan() 取消或更新现有订阅。项目还包含一个 /admin/emails 页面,用 ADMIN_EMAILS 中列出的邮箱访问,用于查看邮件事件。

作者在 README 中明确说明,这套脚手架面向学习者、独立开发者和初级开发者,并非生产级的多租户 SaaS。使用前需要准备 Node.js、pnpm、Docker Desktop、Stripe CLI 以及 Mailtrap 账号,并自行填写 Supabase、Stripe、Mailtrap 的密钥与 8 个邮件模板 UUID。本地开发默认把邮件投递到 Mailtrap 的 Email Testing 收件箱,而不是真实收件人邮箱。

Next.jsSaaS启动器

适合你的项目吗?

适用场景

  • 学习 Next.js 中认证、订阅计费与事务邮件如何组合成一个 SaaS 骨架
  • 个人或独立开发者快速搭建带登录、付费方案和邮件通知的产品原型
  • 需要把 Supabase Auth 的认证邮件改由 Mailtrap 发送的项目
  • 希望用 Stripe Checkout 与订阅变更逻辑起步的计费功能验证

适合人群

  • 学习者和初级开发者,用于理解 SaaS 基础模块的接线方式
  • 独立开发者做个人项目或早期原型,而非直接上线生产
  • 需要 Mailtrap 邮件层与 Supabase、Stripe 组合示例的团队

上手与定制指南

结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。

  1. 1

    需要 Node.js 20+、pnpm 10+、Docker Desktop、Stripe CLI 以及 Mailtrap 账号

  2. 2

    先运行 pnpm db:setup 启动本地 Supabase 并生成 .env.local,再补齐 Mailtrap、Stripe 与 ADMIN_EMAILS 等变量

  3. 3

    NEXT_PUBLIC_APP_URL 同时决定开发端口、Supabase 回调地址和 Send Email Hook 地址,改端口后需执行 pnpm sync:env 并重启数据库

  4. 4

    本地计费同步需另开终端运行 stripe listen 转发到 /api/webhooks/stripe,并把签名密钥写入 STRIPE_WEBHOOK_SECRET

  5. 5

    本地开发建议保持 MAILTRAP_SANDBOX=true,邮件会进入 Mailtrap Email Testing 收件箱;部署前改为 false

查看仓库使用说明

授权与来源资料

使用条件与限制

免费使用 · 保留许可声明

本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。

使用时需要遵守

  • 允许免费使用、修改、商用和分发该版本代码。
  • 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
  • 代码按现状提供;担保与责任限制以原许可证及适用法律为准。

额外费用与待核对事项

  • 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
  • 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
  • 项目定位为学习与原型用途,作者明确声明并非生产级多租户 SaaS,不应直接用于生产环境。
  • 使用邮件功能需注册 Mailtrap 账号,并提供 API token、Email Testing 收件箱及托管模板。
  • 本地计费 webhook 调试需安装 Stripe CLI,并配置 Stripe 密钥与价格 ID。
  • 本地启动 Supabase Auth 与 Postgres 依赖 Docker Desktop。
  • 本地开发默认邮件只进入 Mailtrap 测试收件箱而非真实邮箱,部署生产前必须将 MAILTRAP_SANDBOX 设为 false。
  • 需自行填写 Mailtrap API token、沙箱收件箱 ID、发件地址以及 8 个邮件模板 UUID。
  • 需自行配置 Stripe 密钥、webhook 签名密钥以及 Pro 与 Team 两个价格 ID。
  • 访问 /admin/emails 管理页需在 ADMIN_EMAILS 中填入自己的邮箱。
  • 若不用 Docker,需在 supabase.com 创建云项目、执行迁移 SQL 并配置 API 密钥与回调地址。
查看原文依据

Permission is hereby granted, free of charge

许可证原文

For learners, indie hackers, and juniors — not production-grade multi-tenant SaaS.

README 原文

[Mailtrap](https://mailtrap.io) account (API token + Email Testing inbox + hosted templates)

README 原文

- [Stripe CLI](https://stripe.com/docs/stripe-cli) (for local billing webhooks)

README 原文

- [Docker Desktop](https://docs.docker.com/get-docker/) (for local Supabase)

README 原文

Emails appear in your **Mailtrap Email Testing inbox**, not the recipient's real mailbox. Set `MAILTRAP_SANDBOX=false` before production deploy.

README 原文

1. **Mailtrap** — API token, sandbox inbox ID, from address, 8 template UUIDs

README 原文

2. **Stripe** — secret key, webhook secret (from Stripe CLI below), Pro + Team price IDs

README 原文

3. **Admin** — your email in `ADMIN_EMAILS` (for `/admin/emails`)

README 原文

Create a project at [supabase.com](https://supabase.com), run SQL from `supabase/migrations/`, copy API keys into `.env.local`, and configure:

README 原文
https://github.com/mailtrap/nextjs-saas-starter/blob/main/LICENSEhttps://github.com/mailtrap/nextjs-saas-starter/blob/main/README.md

DeepSeek 根据仓库许可证和 README 整理 ·2026-10-07。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。

项目核对记录与介绍依据

模板资料

来源平台
GitHub
资料与维护参考分
资料较完整 · 88 / 100
技术栈
Next.js · React
网站类型
SaaS · 启动器
这个分数如何计算

本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。

这个项目需要核对什么

记录的仓库更新时间
2026-09-29
截图检查日期
2026-10-07

已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。

目录记录的主要技术栈是 Next.js。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。

查看具体选型方法 →

介绍的制作与核对状态

介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。

审核声明: [email protected] · 2026-10-08

查看当时使用的来源资料

SHA-256: aa788be0ee61e95dcdda2735114b5d76555c9336ca7aca6b6de98020dd56cc63

2026-10-07T19:06:08.818Z

来源文件 / 仓库
# nextjs-saas-starter

Blank-slate Next.js SaaS scaffolding with **Mailtrap** as the email layer, **Supabase** auth, and **Stripe** billing.

For learners, indie hackers, and juniors — not production-grade multi-tenant SaaS.

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fmailtrap%2Fnextjs-saas-starter&env=NEXT_PUBLIC_APP_URL,NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY,DATABASE_URL,SEND_EMAIL_HOOK_SECRET,STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET,STRIPE_PRICE_PRO,STRIPE_PRICE_TEAM,MAILTRAP_API_TOKEN,MAILTRAP_WEBHOOK_SECRET,MAILTRAP_FROM_EMAIL,MAILTRAP_FROM_NAME,MAILTRAP_TPL_WELCOME,MAILTRAP_TPL_MAGIC_LINK,MAILTRAP_TPL_RESET_PASSWORD,MAILTRAP_TPL_TEAM_INVITE,MAILTRAP_TPL_PAYMENT_RECEIPT,MAILTRAP_TPL_DUNNING,MAILTRAP_TPL_CANCELLATION,MAILTRAP_TPL_PLAN_CHANGE,ADMIN_EMAILS&project-name=nextjs-saas-starter)

## Prerequisites

- [Node.js](https://nodejs.org) 20+
- [pnpm](https://pnpm.io) 10+
- [Docker Desktop](https://docs.docker.com/get-docker/) (for local Supabase)
- [Stripe CLI](https://stripe.com/docs/stripe-cli) (for local billing webhooks)
- [Mailtrap](https://mailtrap.io) account (API token + Email Testing inbox + hosted templates)

## Quick start (local)

```bash
git clone https://github.com/mailtrap/nextjs-saas-starter.git
cd nextjs-saas-starter
pnpm install
pnpm db:setup          # Docker: Supabase Auth + Postgres + schema → writes .env.local
```

Copy remaining values from [`.env.example`](.env.example) into `.env.local`:

1. **Mailtrap** — API token, sandbox inbox ID, from address, 8 template UUIDs
2. **Stripe** — secret key, webhook secret (from Stripe CLI below), Pro + Team price IDs
3. **Admin** — your email in `ADMIN_EMAILS` (for `/admin/emails`)

Optional Stripe test products/prices:

```bash
stripe fixtures stripe-fixtures.json --api-key "$STRIPE_SECRET_KEY"
```

Start the app (port comes from `NEXT_PUBLIC_APP_URL`):

```bash
pnpm dev
```

Open the URL in `.env.local` (default `http://127.0.0.1:3000`).

### Port / URL configuration

`NEXT_PUBLIC_APP_URL` is the single source of truth for:

- Next.js dev port (`pnpm dev`)
- Supabase `site_url` and auth redirects
- Send Email Hook URI (Docker → host app)

If port 3000 is taken, set e.g. `NEXT_PUBLIC_APP_URL=http://127.0.0.1:3001`, then:

```bash
pnpm sync:env
pnpm db:stop && pnpm db:start
pnpm dev
```

### What `pnpm db:setup` does

1. Starts **only** Supabase Auth + Postgres (not Storage, Studio, Realtime, etc.)
2. Applies [`supabase/migrations/`](supabase/migrations/) (source of truth for schema)
3. Writes Supabase credentials into `.env.local`
4. Syncs auth hook URL and redirect URLs from `NEXT_PUBLIC_APP_URL`

**Stop Docker:** `pnpm db:stop` · **Reset database:** `pnpm db:reset` · **Restart:** `pnpm db:start`

### Cloud Supabase instead of Docker

Create a project at [supabase.com](https://supabase.com), run SQL from `supabase/migrations/`, copy API keys into `.env.local`, and configure:

- Auth → URL → your `NEXT_PUBLIC_APP_URL`
- Auth → Hooks → Send Email → `https://YOUR_APP/api/auth/send-email`

## Local webhooks

### Stripe (required for billing sync)

In a second terminal (use the port from `NEXT_PUBLIC_APP_URL`):

```bash
stripe listen --forward-to localhost:3001/api/webhooks/stripe --api-key "$STRIPE_SECRET_KEY"
```

Copy the webhook signing secret into `STRIPE_WEBHOOK_SECRET` in `.env.local`.

### Mailtrap (optional locally — no ngrok needed)

Set `MAILTRAP_WEBHOOK_SECRET` in `.env.local`, then simulate an event:

```bash
pnpm webhook:test:mailtrap
```

Refresh `/admin/emails` to see the test event. In production, point Mailtrap webhooks at `https://YOUR_APP/api/webhooks/mailtrap`.

## Env vars

| Group | What you need |
|-------|----------------|
| **App** | `NEXT_PUBLIC_APP_URL` — dev port, redirects, Supabase hook (`pnpm sync:env` after changes) |
| **Supabase** | 4 vars — auto-filled by `pnpm db:setup` locally |
| **Stripe** | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_PRICE_PRO`, `STRIPE_PRICE_TEAM` |
| **Mailtrap** | API token, sandbox flag + inbox ID, from address, 8 template UUIDs, webhook secret |
| **Auth hook** | `SEND_EMAIL_HOOK_SECRET` — auto-filled locally |
| **Admin** | `ADMIN_EMAILS` — comma-separated emails for `/admin/emails` |

Full list: [`.env.example`](.env.example)

### Mailtrap sandbox (recommended for local dev)

```bash
MAILTRAP_SANDBOX=true
MAILTRAP_ACCOUNT_ID=12345           # optional, silences SDK warning
MAILTRAP_TEST_INBOX_ID=123456       # Email Testing → inbox settings
MAILTRAP_WEBHOOK_SECRET=your-secret # local: any string; match in Mailtrap dashboard for prod
```

Emails appear in your **Mailtrap Email Testing inbox**, not the recipient's real mailbox. Set `MAILTRAP_SANDBOX=false` before production deploy.

## Architecture

```
src/app/          → routes (marketing, auth, dashboard, API webhooks)
src/actions/      → Server Actions (auth, billing, org, settings)
src/lib/mailtrap  → sendEmail(), webhook signature verify
src/config/emails → typed template UUID map
src/db/           → Drizzle schema (profiles, orgs, subscriptions, email events)
```

**Email flows:** Supabase Send Email Hook → Mailtrap (magic link, password reset, email change). App events → `sendEmail()` (welcome, invites, billing).

**Billing:** Stripe Checkout for upgrades; downgrades cancel or update the existing subscription via `changePlan()`.

## Where to add your product logic

1. Create `src/features/your-feature/` — see [`src/features/README.md`](src/features/README.md)
2. Add a route under `src/app/dashboard/your-feature/page.tsx` (or another app route)
3. Call `sendEmail()` from `@/lib/mailtrap` for new transactional emails

## Scripts

```bash
pnpm db:setup              # first-time local setup (Docker + migrations + .env.local)
pnpm db:start              # start Supabase + reset + sync env
pnpm db:stop               # stop Docker Supabase
pnpm db:reset              # re-apply supabase/migrations
pnpm sync:env              # sync Supabase auth URLs from NEXT_PUBLIC_APP_URL
pnpm dev                   # Next.js dev server (port from NEXT_PUBLIC_APP_URL)
pnpm build && pnpm start   # production build
pnpm lint
pnpm typecheck
pnpm test                  # unit tests (vitest)
pnpm test:e2e              # Playwright
pnpm webhook:test:mailtrap # local Mailtrap webhook test (no ngrok)
pnpm lighthouse            # Lighthouse CI
```

Schema changes: edit `supabase/migrations/`, then `pnpm db:reset`. The `drizzle/` folder mirrors schema for Drizzle ORM queries; `db:generate` / `db:push` are optional and not used by default setup.

## Post-deploy checklist

1. Run `supabase/migrations/` SQL on production Postgres (or link hosted Supabase)
2. Set all env vars from `.env.example`
3. Stripe → Webhooks → `https://YOUR_APP/api/webhooks/stripe`
4. Mailtrap → Webhooks → `https://YOUR_APP/api/webhooks/mailtrap`
5. Supabase → Auth → Hooks → Send Email → `https://YOUR_APP/api/auth/send-email`
6. Paste Mailtrap template UUIDs and verify sending domain
7. Set `ADMIN_EMAILS` for admin access

## License

MIT
反馈内容错误

看看同类模板

对比同技术栈与用途的模板,找到更适合的视觉与内容结构。