一个使用 Next.js 与 React 构建的简单无头 CMS(Headless CMS)
本项目是一个轻量、全栈的内容管理系统,用于管理博客文章、资讯或其他动态内容。系统采用现代化的无头架构:将内容管理的后端与前端展示分离,从而实现更快、更灵活、可扩展的内容交付。
- 认证:安全的用户登录与内容管理。
- 内容管理:通过友好的仪表盘创建、编辑、发布与删除内容。
- Next.js 前端:基于 Next.js,利用 SSR/SSG 提升性能与 SEO。
- React 组件化 UI:可复用的组件,带来直观的编辑/浏览体验。
- API 驱动:前端通过 RESTful API 获取数据,便于整合多种内容源。
- Markdown 支持:以 Markdown 写作,简单但强大。
- 前端:Next.js、React、Tailwind CSS(或你选择的 CSS 框架)、React Hook Form
- 后端:Node.js、Express、MongoDB(或你选择的数据库)、JWT(认证)
- 部署:Vercel(Next.js)、Railway/Render/Heroku(后端 API)或类似服务
以下指令与结构适用于典型的前后端分离(apps/frontend 与 apps/backend)。若你的项目结构不同,请按需调整。
# 克隆仓库
git clone <your-repo-url> cms
cd cms
# 可选:使用 pnpm(推荐)或 npm/yarn
# 这里示例使用 pnpm
corepack enable || npm i -g pnpm
# 安装前端依赖
cd apps/frontend && pnpm install && cd -
# 安装后端依赖
cd apps/backend && pnpm install && cd -创建并填写以下环境变量文件(示例):
-
前端:
apps/frontend/.env.localNEXT_PUBLIC_API_BASE_URL=http://localhost:4000
-
后端:
apps/backend/.envPORT=4000 NODE_ENV=development MONGODB_URI=mongodb://localhost:27017/cms JWT_SECRET=change_me_to_a_long_random_string CORS_ORIGIN=http://localhost:3000
# 启动后端(开发)
cd apps/backend
pnpm dev
# 后端默认运行在 http://localhost:4000
# 另开一个终端,启动前端
cd apps/frontend
pnpm dev
# 前端默认运行在 http://localhost:3000前端 apps/frontend/package.json 常见脚本:
pnpm dev:启动 Next.js 开发服务器pnpm build:生产构建pnpm start:以生产模式启动pnpm lint:代码检查
后端 apps/backend/package.json 常见脚本:
pnpm dev:使用 nodemon 启动开发服务器pnpm build:编译 TypeScript(若使用 TS)pnpm start:以生产模式启动(已构建)pnpm lint:代码检查
cms/
├─ apps/
│ ├─ frontend/ # Next.js 前端
│ │ ├─ app/ or pages/ # 路由与页面
│ │ ├─ components/ # UI 组件
│ │ ├─ lib/ # 工具方法/SDK
│ │ ├─ styles/ # 样式(Tailwind/全局样式)
│ │ ├─ public/ # 静态资源
│ │ └─ ...
│ └─ backend/ # Express 后端
│ ├─ src/
│ │ ├─ api/ # 路由与控制器(如 /auth /posts)
│ │ ├─ models/ # 数据模型(MongoDB/Mongoose)
│ │ ├─ middlewares/ # 中间件(认证、日志、错误处理)
│ │ ├─ services/ # 业务逻辑
│ │ ├─ utils/ # 工具函数
│ │ └─ server.ts # 应用入口
│ └─ ...
├─ docs/ # 文档(可选)
└─ README.md
POST /auth/login:用户登录,返回 JWTGET /posts:获取文章列表(公开或需权限,按需配置)POST /posts:创建文章(需认证)PUT /posts/:id:更新文章(需认证)DELETE /posts/:id:删除文章(需认证)
认证方式:在请求头中携带 Authorization: Bearer <token>。
- 使用
fetch或react-query/SWR从NEXT_PUBLIC_API_BASE_URL拉取数据。 - Next.js 可按需选择
fetch(SSR/SSG)或客户端请求。
// 示例:服务端获取(Next.js 14 app 路由)
export async function getPosts() {
const base = process.env.NEXT_PUBLIC_API_BASE_URL;
const res = await fetch(`${base}/posts`, { cache: 'no-store' });
if (!res.ok) throw new Error('Failed to fetch posts');
return res.json();
}- 前端使用
react-markdown或@mdx-js/react渲染内容。 - 后端可存储 Markdown 原文与解析后的摘要,满足不同展示场景。
- 连接 Git 仓库,一键导入。
- 配置环境变量:
NEXT_PUBLIC_API_BASE_URL指向线上 API。 - 选择 Next.js 构建预设并完成部署。
- 配置环境变量:
PORT、MONGODB_URI、JWT_SECRET、CORS_ORIGIN。 - 绑定持久化数据库(MongoDB Atlas 等)。
- 设置启动命令(如
pnpm start)。
- 使用强随机的
JWT_SECRET。 - 为管理端路由启用鉴权与基于角色的访问控制(RBAC)。
- 对关键接口启用速率限制与日志审计。
- 遵循 OWASP 常见安全实践(输入校验、CSRF、XSS 防护等)。
- 启动后端连接 MongoDB 失败?
- 检查
MONGODB_URI是否可达,且 IP 白名单已配置(若使用 Atlas)。
- 检查
- 前端无法调用 API?
- 确认
NEXT_PUBLIC_API_BASE_URL是否正确,后端CORS_ORIGIN是否允许前端域名。
- 确认
- SEO 表现欠佳?
- 使用 Next.js 的
metadata/Head、结构化数据、站点地图与静态化策略。
- 使用 Next.js 的
欢迎提交 Issue 与 PR。提交前请:
- 保持代码风格一致(ESLint/Prettier)。
- 为关键逻辑补充单元测试。
- 更新相关文档。
选择合适的许可证(如 MIT/Apache-2.0),并在仓库根目录添加 LICENSE 文件。
提示:本 README 为通用模板,你可以根据具体项目的目录结构、脚本与功能进行调整与细化。