项目背景
83d.me 是我的新个人站点,用于展示技术经历、产品作品和技术博客。这个站点不仅是一个简单的展示页面,更是一个技术实践的结晶,融合了现代 Web 开发的最佳实践和全面的 SEO 优化策略。
更重要的是,这个站点成功继承了原域名 404.ms 的 SEO 权重,实现了平滑的域名迁移。
技术栈选型
核心框架
Next.js 14.2 + App Router
选择 Next.js 作为核心框架,主要基于以下考虑:
- SEO 友好:服务端渲染 (SSR) 和静态生成 (SSG) 完美支持
- 性能优异:自动代码分割、图片优化、预加载
- 开发体验:热更新、TypeScript 支持、文件系统路由
- 部署便捷:与 Vercel 无缝集成
// 使用 App Router 的文件结构
app/
├── [year]/[month]/[day]/[slug]/ # 动态路由支持 SEO 友好的日期路径
├── articles/ # 文章列表页
├── api/ # API 路由
├── layout.tsx # 全局布局
└── page.tsx # 首页
TypeScript
全站使用 TypeScript,提供类型安全和更好的开发体验:
// 类型定义示例
interface ArticleMeta {
title: string
date: string
slug: string
category: string
tags: string[]
excerpt?: string
pin?: boolean
year: string
month: string
day: string
}
UI 框架
Tailwind CSS 4.1
采用最新的 Tailwind CSS 4.x 版本:
- 工具优先:快速构建响应式界面
- 深色模式:内置 dark mode 支持
- 自定义简单:通过配置文件轻松定制
- 性能优秀:生产环境自动清除未使用的样式
Radix UI
使用 Radix UI 作为基础组件库:
- 无样式组件:完全的样式控制权
- 无障碍访问:WAI-ARIA 标准
- 键盘导航:完整的键盘支持
- 组件丰富:Accordion, Dialog, Dropdown Menu, Tooltip 等 40+ 组件
// 使用 Radix UI 构建的组件
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"
内容管理
Markdown + Gray Matter
采用 Markdown 文件作为内容管理方案:
---
title: "文章标题"
date: "2024-10-08"
tags: ["Next.js", "SEO"]
category: 技术实践
excerpt: "文章摘要"
pin: true
---
文章内容...
Unified 生态系统
使用完整的 Unified 生态处理 Markdown:
- remark:Markdown 解析和转换
- remark-gfm:GitHub Flavored Markdown 支持
- remark-math:数学公式支持 (LaTeX)
- rehype:HTML 处理
- rehype-highlight:代码语法高亮
- rehype-katex:数学公式渲染
- rehype-mermaid:流程图支持
// Markdown 处理管道
const processor = unified()
.use(remarkParse)
.use(remarkGfm)
.use(remarkMath)
.use(remarkRehype)
.use(rehypeKatex)
.use(rehypeHighlight)
.use(rehypeMermaid)
.use(rehypeStringify)
数据存储
Supabase
使用 Supabase 作为后端服务:
- PostgreSQL 数据库:强大的关系型数据库
- 实时订阅:WebSocket 实时更新
- 认证服务:内置用户认证
- API 自动生成:基于数据库 schema 自动生成 RESTful API
// Supabase 客户端配置
import { createClient } from '@supabase/supabase-js'
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
当前用于存储:
- 文章评分数据
- 用户反馈
- 访问统计
多语言支持
实现了完整的国际化支持,覆盖 5 种语言:
- 🇨🇳 简体中文 (zh)
- 🇺🇸 英语 (en)
- 🇪🇸 西班牙语 (es)
- 🇫🇷 法语 (fr)
- 🇯🇵 日语 (ja)
// 语言路由结构
app/
├── page.tsx # 默认语言(中文)
├── zh/
│ └── page.tsx
├── en/
│ └── page.tsx
├── es/
│ └── page.tsx
├── fr/
│ └── page.tsx
└── ja/
└── page.tsx
SEO 优化实践
完整的 Metadata 配置
为每个页面生成完整的 metadata:
export function generateMetadata(config: SEOConfig): Metadata {
return {
title: fullTitle,
description,
keywords: keywords.join(', '),
authors: [{ name: author }],
creator: author,
publisher: author,
// Open Graph
openGraph: {
title: fullTitle,
description,
url,
siteName: '个人主页 - 资深程序员与产品创造者',
locale: 'zh_CN',
alternateLocale: ['en_US', 'es_ES', 'fr_FR', 'ja_JP'],
images: [{
url: imageUrl,
width: 1200,
height: 630,
}],
type: 'article',
},
// Twitter Card
twitter: {
card: 'summary_large_image',
title: fullTitle,
description,
creator: '@hg_nohair',
images: [imageUrl],
},
// Canonical URL
alternates: {
canonical: url,
languages: {
'zh-CN': `${baseUrl}/zh`,
'en-US': `${baseUrl}/en`,
// ...其他语言
},
},
}
}
JSON-LD 结构化数据
实现了多种 Schema.org 类型的结构化数据:
1. Article Schema
{
'@context': 'https://schema.org',
'@type': 'Article',
headline: article.title,
description: article.excerpt,
author: {
'@type': 'Person',
name: '83年生人',
},
datePublished: article.date,
dateModified: article.date,
keywords: article.tags.join(', '),
articleSection: article.category,
}
2. Blog Schema
{
'@context': 'https://schema.org',
'@type': 'Blog',
name: '个人主页 - 资深程序员与产品创造者',
description: '分享技术经验、产品开发和创业故事',
url: `${baseUrl}/articles`,
}
3. Person Schema
{
'@context': 'https://schema.org',
'@type': 'Person',
name: '83年生人',
jobTitle: '资深程序员 & 产品创造者',
description: '83年出生的程序员,曾在Yahoo和阿里巴巴工作',
knowsAbout: [
'Web Development',
'iOS Development',
'Go Programming',
'Swift',
'Product Design',
],
alumniOf: [
{ '@type': 'Organization', name: 'Yahoo' },
{ '@type': 'Organization', name: 'Alibaba' },
],
}
4. SoftwareApplication Schema(产品页面)
{
'@context': 'https://schema.org',
'@type': 'SoftwareApplication',
name: product.name,
description: product.description,
applicationCategory: 'DeveloperApplication',
operatingSystem: 'Cross-platform',
aggregateRating: {
'@type': 'AggregateRating',
ratingValue: 4.5,
ratingCount: 100,
},
}
5. Breadcrumb Schema
{
'@context': 'https://schema.org',
'@type': 'BreadcrumbList',
itemListElement: [
{
'@type': 'ListItem',
position: 1,
name: '首页',
item: 'https://83d.me',
},
{
'@type': 'ListItem',
position: 2,
name: '文章',
item: 'https://83d.me/articles',
},
],
}
动态 Sitemap
自动生成包含所有内容的 sitemap:
export default function sitemap(): MetadataRoute.Sitemap {
const baseUrl = 'https://83d.me'
const articles = getAllArticlesMeta()
const articleUrls = articles.map((article) => ({
url: `${baseUrl}/${article.year}/${article.month}/${article.day}/${article.slug}`,
lastModified: new Date(article.date),
changeFrequency: 'monthly' as const,
priority: article.pin ? 0.9 : 0.7,
}))
return [
{
url: baseUrl,
lastModified: new Date(),
changeFrequency: 'daily',
priority: 1,
},
{
url: `${baseUrl}/articles`,
lastModified: new Date(),
changeFrequency: 'daily',
priority: 0.8,
},
...articleUrls,
]
}
Robots.txt
优化爬虫抓取策略:
User-agent: *
Allow: /
Sitemap: https://83d.me/sitemap.xml
# 阻止抓取 API 路由
Disallow: /api/
Disallow: /quote-card
评分系统与 SEO 整合
实现了文章评分功能,并整合到 SEO 中:
// 评分数据自动添加到 Schema.org
export function generateArticleWithRatingJsonLd(
article: ArticleMeta,
rating?: { value: number; count: number }
) {
const baseJsonLd = generateArticleJsonLd(article)
if (rating && rating.value > 0) {
return {
...baseJsonLd,
aggregateRating: {
'@type': 'AggregateRating',
ratingValue: rating.value,
ratingCount: rating.count,
bestRating: 5,
worstRating: 1,
},
}
}
return baseJsonLd
}
从 404.ms 到 83d.me:SEO 权重迁移
为什么要迁移域名?
- 品牌简洁:83d.me 更短,更好记
- 个人标识:83 代表我的出生年份,更有个人特色
- 技术挑战:实践完整的 SEO 迁移流程
迁移策略
1. 301 永久重定向(最关键!)
在 GoDaddy 上配置了从 404.ms 到 83d.me 的 301 重定向:
# 概念示意(实际使用 GoDaddy 域名转发)
server {
server_name 404.ms www.404.ms;
return 301 https://83d.me$request_uri;
}
重点:
- ✅ 使用 301 永久重定向(不是 302 临时)
- ✅ 保留完整路径:
404.ms/2024/01/01/article → 83d.me/2024/01/01/article - ✅ 保留查询参数:
?tag=tech&page=2 - ✅ 支持 HTTPS
2. Canonical 标签
在新站点所有页面添加 canonical 标签:
export const metadata: Metadata = {
alternates: {
canonical: `https://83d.me${pathname}`,
},
}
3. Google Search Console 地址变更
完整的迁移流程:
-
添加新域名
- 在 Google Search Console 添加 83d.me
- 验证所有权(DNS TXT 记录)
-
提交 Sitemap
- 提交
https://83d.me/sitemap.xml - 确保所有重要页面都包含在内
- 提交
-
使用地址变更工具
- 在旧站点 (404.ms) 的 Search Console
- 设置 → 地址变更
- 选择新站点:83d.me
- Google 会自动验证:
- ✅ 301 重定向配置正确
- ✅ 新站点可访问
- ✅ Sitemap 已提交
-
监控迁移进度
- 查看索引状态
- 监控流量变化
- 检查排名波动
4. 更新外部链接
主动更新可控的外部链接:
- ✅ Twitter/X 个人资料
- ✅ GitHub 个人资料
- ✅ 产品页面的开发者链接
- ✅ 第三方平台(知乎、掘金等)
5. 保持旧域名
重要: 保持 404.ms 的 301 重定向至少 12 个月:
- 让搜索引擎有足够时间更新索引
- 确保所有反向链接正常工作
- 避免流量突然下降
迁移效果预期
| 时间点 | 预期效果 |
|---|---|
| 1-2 周 | Google 发现重定向 |
| 1 个月 | 部分流量转移(约 50%) |
| 3 个月 | 大部分权重迁移(60-80%) |
| 6 个月 | 基本完全迁移(80-95%) |
| 12 个月 | 完全稳定,可考虑停用旧域名 |
验证方法
# 测试 301 重定向
curl -I https://83d.me
# 应该看到:
# HTTP/2 301
# Location: https://83d.me/
# 测试路径保留
curl -I https://83d.me/2024/10/08/article-slug
# 应该看到:
# HTTP/2 301
# Location: https://83d.me/2024/10/08/article-slug
性能优化
图片优化
使用 CDN 代理加速图片加载:

代码分割
Next.js 自动进行代码分割:
// 动态导入减少初始加载
const DynamicComponent = dynamic(() => import('@/components/HeavyComponent'), {
loading: () => <LoadingSpinner />,
ssr: false,
})
字体优化
使用 Geist 字体并优化加载:
import { GeistSans } from 'geist/font/sans'
import { GeistMono } from 'geist/font/mono'
export default function RootLayout({ children }) {
return (
<html className={`${GeistSans.variable} ${GeistMono.variable}`}>
{children}
</html>
)
}
部署与监控
Vercel 部署
- 自动部署:Git push 自动触发构建
- 预览部署:每个 PR 都有独立的预览链接
- 边缘网络:全球 CDN 加速
- Analytics:内置访问分析
环境变量
# .env.local
NEXT_PUBLIC_SITE_URL=https://83d.me
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_key
监控指标
定期检查的 SEO 指标:
| 指标 | 工具 | 检查频率 |
|---|---|---|
| 索引页面数 | Google Search Console | 每周 |
| 搜索排名 | Ahrefs / SEMrush | 每周 |
| 页面加载速度 | PageSpeed Insights | 每月 |
| Core Web Vitals | Search Console | 每月 |
| 反向链接 | Ahrefs | 每月 |
开发工作流
文件结构
83d/
├── app/ # Next.js App Router
│ ├── [year]/[month]/[day]/[slug]/
│ ├── api/
│ ├── articles/
│ └── layout.tsx
├── components/ # React 组件
│ ├── ui/ # Radix UI 封装
│ └── sections/ # 页面区块
├── content/ # Markdown 文章
│ └── articles/
├── lib/ # 工具函数
│ ├── markdown.ts # Markdown 处理
│ ├── seo.ts # SEO 工具
│ └── supabase.ts # Supabase 客户端
├── docs/ # 文档
│ ├── SEO_GUIDE.md
│ ├── SEO_MIGRATION_GUIDE.md
│ └── SUPABASE_SETUP.md
└── public/ # 静态资源
Git 工作流
- 从 main 分支创建特性分支
- 开发并本地测试
- 构建验证:
yarn build - 提交并推送
- 通过 PR 合并到 main
- 自动部署到 Vercel
文章发布流程
- 在
content/articles/创建.md文件 - 填写完整的 frontmatter
- 编写文章内容
- 本地预览:
yarn dev - 检查 SEO metadata
- 提交并推送
- 自动部署并生成 sitemap
最佳实践总结
SEO 方面
- ✅ 每个页面都有唯一的 title 和 description
- ✅ 使用语义化的 URL 结构(日期 + slug)
- ✅ 添加完整的结构化数据(JSON-LD)
- ✅ 提供多语言版本
- ✅ 优化图片 alt 属性
- ✅ 内部链接优化
- ✅ 移动端友好(响应式设计)
- ✅ 快速加载(Core Web Vitals)
技术方面
- ✅ TypeScript 类型安全
- ✅ 组件化开发
- ✅ 代码分割
- ✅ SSR/SSG 混合渲染
- ✅ 环境变量管理
- ✅ 错误边界
- ✅ 无障碍访问(A11y)
内容方面
- ✅ 定期更新内容
- ✅ 提供有价值的原创内容
- ✅ 文章结构清晰(使用标题层级)
- ✅ 代码示例完整
- ✅ 添加相关链接
未来规划
功能增强
- 全文搜索功能
- 评论系统(Giscus)
- 文章系列支持
- RSS 订阅
- 阅读时间估算
- 相关文章推荐
- 标签云
- 归档页面
SEO 优化
- 添加 FAQ Schema
- 优化 Core Web Vitals
- 增加视频内容的 VideoObject Schema
- A/B 测试标题和描述
- 建立更多高质量反向链接
技术升级
- 升级到 Next.js 15
- 实现 ISR(增量静态再生)
- 添加 PWA 支持
- 集成 Web Analytics(Plausible)
- 实现文章草稿系统
总结
83d.me 站点是一个完整的现代 Web 应用实践案例,它不仅展示了技术能力,更重要的是实现了:
- 优秀的用户体验:快速加载、响应式设计、暗黑模式
- 完整的 SEO 优化:从 metadata 到结构化数据,从 sitemap 到域名迁移
- 可维护的代码结构:TypeScript、组件化、模块化
- 平滑的域名迁移:通过 301 重定向完整继承 404.ms 的 SEO 权重
这个项目证明了:好的技术选型 + 完整的 SEO 策略 + 持续的内容更新 = 成功的个人站点。
如果你也在构建个人站点,希望这些实践经验能对你有所帮助!