项目技术选型

层面 选型 说明
框架 Next.js 14(App Router) SSG 支持完善,next/image 性能优化内置
样式 Tailwind CSS 在 tailwind.config.js 中集中定义字号、间距等设计 token,无需 CSS Variables
富文本 MDX(next-mdx-remote) 在 Markdown 中嵌入 React 组件,用户可直接在 GitHub 上编辑
图片处理 Sharp(GitHub Action 中运行) 自动压缩、WebP 转换、多尺寸生成
字体 next/font(Google Fonts) 零布局偏移,自动本地化
部署 Vercel 边缘 CDN,next/image 原生支持,免费 tier 足够个人学术网站
CI/CD GitHub Actions 图片处理 + 自动部署触发

输出模式output: 'export'(纯静态 HTML)。构建结果是一堆静态文件,部署在 Vercel 上,不需要服务器持续运行,也不需要数据库。

域名:Vercel 默认提供 project-name.vercel.app,后期可绑定自定义域名(如 cindykao.com),不影响任何技术实现,可随时决定。


项目目录结构

/
├── app/                        # Next.js App Router 页面
│   ├── layout.tsx              # 根布局 — 字体、导航栏、元数据
│   ├── page.tsx                # 根路由重定向 → /about
│   ├── globals.css             # 全局 CSS(Tailwind 基础 + 自定义类)
│   ├── about/
│   ├── news/
│   │   └── all/                # /news/all — 完整新闻存档
│   ├── portfolio/
│   ├── projects/[id]/          # 动态项目详情页
│   ├── publications/
│   ├── team/
│   ├── courses/
│   └── opportunities/
│
├── components/
│   ├── layout/
│   │   └── Navbar.tsx          # 固定顶部导航栏,含深色模式切换
│   ├── about/
│   │   ├── ResearchSection.tsx
│   │   ├── OurApproachSection.tsx
│   │   └── ContactSection.tsx
│   ├── news/
│   │   └── NewsGrid.tsx        # /news 和 /news/all 共用的网格组件
│   ├── portfolio/
│   │   ├── PortfolioHero.tsx
│   │   ├── DirectionBanner.tsx
│   │   └── ProjectCard.tsx
│   ├── projects/
│   │   └── MediaGrid.tsx       # 图片 + 视频两列网格
│   ├── publications/
│   │   └── PublicationCard.tsx
│   ├── team/
│   │   └── TeamSection.tsx
│   ├── courses/
│   │   └── CourseBlock.tsx
│   └── ui/
│       ├── InlineLink.tsx      # 样式化链接 — 内部或外部
│       ├── Strong.tsx          # 加粗 + 深色文字
│       ├── Corresponding.tsx   # 通讯作者上标 *
│       └── Skeleton.tsx        # 加载骨架屏
│
├── content/                    # ← 用户可编辑文件
│   ├── site.ts                 # 网站标题、描述、favicon 说明
│   ├── about.tsx               # 个人简介、研究方向、研究方法、联系方式
│   ├── news.tsx                # 新闻条目数组
│   ├── portfolio.tsx           # Hero、简介、研究方向 + 论文
│   ├── publications.tsx        # 按年份分组的发表列表
│   ├── projectDetails.tsx      # 项目详情页内容(按 slug 区分)
│   ├── team.tsx                # 团队简介 + 成员分组
│   ├── courses.tsx             # 课程列表
│   └── opportunities.tsx       # 招募信息正文 + 要点列表
│
├── lib/
│   └── projectRoutes.ts        # Slug 生成 + 项目查找工具函数
│
├── public/
│   ├── images/                 # 静态图片(已加入 gitignore — 单独上传)
│   ├── papers/                 # 自托管 PDF(已加入 gitignore — 单独上传)
│   │   └── .gitkeep
│   └── favicon.ico             # 替换此文件可更改浏览器标签图标
│
└── docs/
    ├── en/                     # 英文用户指南(每页一份)
    └── zh/                     # 中文用户指南(每页一份)

路由架构

静态路由(构建时生成)

| URL | 文件 | 说明 |
|---|---|---|
| `/` | `app/page.tsx` | 重定向到 `/about` |
| `/about` | `app/about/page.tsx` | |
| `/news` | `app/news/page.tsx` | 显示前 8 条 |
| `/news/all` | `app/news/all/page.tsx` | 显示全部 |
| `/portfolio` | `app/portfolio/page.tsx` | |
| `/publications` | `app/publications/page.tsx` | |
| `/team` | `app/team/page.tsx` | |
| `/courses` | `app/courses/page.tsx` | |
| `/opportunities` | `app/opportunities/page.tsx` | |

动态路由

| URL 模式 | 文件 | 生成方式 |
|---|---|---|
| `/projects/[id]` | `app/projects/[id]/page.tsx` | `generateStaticParams()` 读取 `content/about.tsx` 中所有项目标题并转换为 slug |

Slug 生成规则lib/projectRoutes.ts):

标准化 → 转小写 → 将非字母数字字符替换为 - → 去除首尾 -

示例:"Project Alpha"project-alpha"Soft Robot (2024)"soft-robot-2024

激活状态:导航栏在 /portfolio 和任意 /projects/* 路由下均将"Portfolio"标记为激活。


内容编辑系统