# Tootaio Studio 网站（Nuxt 4）

Tootaio Studio 的官方网站代码仓库，基于 Nuxt 4、@nuxt/content、@nuxt/ui 与 i18n 构建，采用 TypeScript 与 ESM 配置。项目默认使用 pnpm 进行依赖与脚本管理。

- 在线地址：`https://tootaio.com`
- 技术要点：内容与 UI 分离（YAML 内容 + JSON 翻译）、类型安全的内容加载、内置 SEO 与 CSP 头部策略

---

## 特性概览

- Nuxt 4 与 Vue 3 `<script setup lang="ts">`，全量 TypeScript 化
- @nuxt/content 管理结构化 YAML 内容，zod 校验 schema，类型安全
- @nuxt/ui 负责 UI 组件与样式，支持暗色模式与主题定制
- @nuxtjs/i18n 多语言（英文、简中），消息分包按需加载
- @nuxtjs/seo 统一 SEO 元信息配置（OG/Twitter/keywords）
- Nitro routeRules 内置严格 CSP、缓存与安全响应头
- 运行时配置集成 WhatsApp 咨询（公开变量）

---

## 快速开始

### 先决条件

- Node.js 18.20+ 或 20+
- pnpm 8+

### 安装依赖

```bash
pnpm i
```

安装后会自动执行 `nuxt prepare`（见 `package.json:postinstall`）。

### 配置环境变量

```bash
cp .env.example .env
```

必须设置：

- `NUXT_PUBLIC_WHATSAPP_NUMBER`：用于页面内“立刻咨询”按钮，走 WhatsApp H5 链接。

注：`nuxt.config.ts` 提供默认占位值，生产环境应以 `.env` 覆盖。

### 本地开发

```bash
pnpm dev
```

访问 `http://localhost:3000`，支持热更新（HMR）与暗色模式切换。

---

## 常用脚本

- 开发：`pnpm dev`
- 构建：`pnpm build`（产物在 `.output/`）
- 预览：`pnpm preview`（以生产模式本地运行）
- 静态生成：`pnpm generate`（SSG 场景）
- 代码检查：`pnpm exec eslint .`

---

## 目录结构

- `app/`：Nuxt 应用源码
  - `pages/`：页面组件（如 `app/pages/index.vue`, `app/pages/webDev.vue`）
  - `layouts/`：布局（默认头部含语言与主题切换）
  - `assets/css/main.css`：主题与样式（集成 `@nuxt/ui` 与 `tailwindcss`）
  - `composables/`：组合式函数（如 `LocalizedCollection.ts`, `NavLinks.ts`）
  - `schemas/`：zod 定义（如 `pricingPlanSchema.ts`, `buttonSchema.ts`）
- `content/`：YAML 内容（按语言区分 `en-US/`, `zh-CN/`）
- `i18n/locales/<locale>/`：UI 文案 JSON 包（按页面拆分，如 `common.json`, `index.json`）
- `public/`：静态资源（如 `favicon.ico`, `og-image-1.png`, `_robots.txt`）
- 根配置：`nuxt.config.ts`, `content.config.ts`, `eslint.config.mjs`
- 文档：`docs/`（工程审计、路线等）

---

## 内容与多语言

### 内容模型（@nuxt/content）

项目在 `content.config.ts` 中用 zod 定义了页面内容的 schema，并建立集合与源文件的对应关系：

- `index_en` ↔ `content/en-US/index.yml`
- `index_zh` ↔ `content/zh-CN/index.yml`
- `webDev_en` ↔ `content/en-US/webDev.yml`
- `webDev_zh` ↔ `content/zh-CN/webDev.yml`

在页面中通过类型安全的加载器获取内容：

```ts
// 示例：在页面/组件中获取本地化内容
const { data: page } = await useLocalizedCollection('index')
```

上述加载器会根据当前语言自动选择集合，并在缺失时回退到英文。

### UI 文案（@nuxtjs/i18n）

- 语言：`en`（en-US）、`zh-CN`
- 加载策略：`strategy: "no_prefix"`
- 文案文件：`i18n/locales/<locale>/*.json`

示例 key：`index.featuredProjects.viewDemo`, `common.button.submit`。

新增页面或模块时，请同步维护中英文版本的 YAML 与 JSON，保持 key 一致。

---

## UI 与主题

- 组件库：`@nuxt/ui`（`UPage*`, `UHeader`, `UButton`, `UTabs`, `UModal` 等）
- 主题：`app/assets/css/main.css` 中可定制字体与主色（项目默认霓虹红 `--color-primary`）
- 暗色模式：内置 `UColorModeButton`，图标与样式随模式自适应
- 图标：`@iconify-json/mdi` 与 `skill-icons` 系列（通过 `UIcon` 使用）

---

## SEO 与安全

- SEO：`@nuxtjs/seo` 统一设置标题、描述、OG、Twitter 等元信息（见 `nuxt.config.ts` 中 `DEFAULT_SEO`）
- 站点地址：`site.url = https://tootaio.com`
- 安全头：在 `routeRules` 配置了 CSP、`X-Content-Type-Options`, `Referrer-Policy` 等；静态资源（`/_nuxt/**`）设置了长期缓存
- 图片白名单：`img-src` 允许 `self` 与 `https://img.tootaio.com` 与 `data:`

---

## 运行时配置与外部集成

- 环境变量：`NUXT_PUBLIC_WHATSAPP_NUMBER`（公开变量，用于发起 WhatsApp 咨询）
- 组合式函数：`useWhatsAppMsgSender()` 会根据该号码构造 WhatsApp H5 链接并 `window.open`
- 示例入口：`app/components/webDev/ContactSalesModal.vue` 在提交后拼接多语言消息并发起咨询

---

## 代码规范与校验

- 风格：TypeScript、2 空格缩进、ESM 配置、组合式函数使用 PascalCase
- ESLint：`@nuxt/eslint` 预设，配置见 `eslint.config.mjs`
- 手动检查：`pnpm exec eslint .`

---

## 测试（当前状态）

- 暂未配置自动化测试
- 建议：单测使用 Vitest，E2E 使用 Playwright
- 在此之前请进行本地验证：
  - `pnpm dev` 运行并切换语言
  - 校验 `content/*.yml` 是否符合 `content.config.ts` 中的 schema
  - `pnpm build` 与 `pnpm preview` 能否成功

---

## 提交与协作

- 提交规范：Conventional Commits（含 scope），如：`feat(content): ...`, `refactor(ui): ...`
- 分支命名：`feat/<desc>`、`fix/<desc>`
- PR 说明：改动目的 / 关联 Issue / UI 截图 / 测试步骤
- 内容改动请确保中英文同步更新（YAML 与 i18n JSON）

---

## 部署建议

- 服务器渲染（默认）：`pnpm build` 生成 `.output/` 后按 Nuxt/Nitro 的 Node 运行方式部署
- 静态站点：`pnpm generate` 进行 SSG（请根据实际路由策略评估可行性）
- 常见平台：Vercel / Netlify / 任意 Node 主机（注意保留 `routeRules` 与响应头设置）

---

## 参考文件

- 配置：`nuxt.config.ts:1`、`content.config.ts:1`
- 页面：`app/pages/index.vue:1`、`app/pages/webDev.vue:1`
- 主题：`app/assets/css/main.css:1`
- 多语言：`i18n/locales/en-US/common.json:1`、`i18n/locales/zh-CN/common.json:1`
- 环境：`.env.example:1`（复制为 `.env` 并填写）

---

## 许可

如无单独说明，本仓库内容归 Tootaio Studio 所有。
