魔法施展中...

83d.me 站点技术栈与 SEO 实践全解析

5 分钟
...

项目背景

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 权重迁移

为什么要迁移域名?

  1. 品牌简洁:83d.me 更短,更好记
  2. 个人标识:83 代表我的出生年份,更有个人特色
  3. 技术挑战:实践完整的 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 地址变更

完整的迁移流程:

  1. 添加新域名

    • 在 Google Search Console 添加 83d.me
    • 验证所有权(DNS TXT 记录)
  2. 提交 Sitemap

    • 提交 https://83d.me/sitemap.xml
    • 确保所有重要页面都包含在内
  3. 使用地址变更工具

    • 在旧站点 (404.ms) 的 Search Console
    • 设置 → 地址变更
    • 选择新站点:83d.me
    • Google 会自动验证:
      • ✅ 301 重定向配置正确
      • ✅ 新站点可访问
      • ✅ Sitemap 已提交
  4. 监控迁移进度

    • 查看索引状态
    • 监控流量变化
    • 检查排名波动

4. 更新外部链接

主动更新可控的外部链接:

  • ✅ Twitter/X 个人资料
  • ✅ GitHub 个人资料
  • ✅ LinkedIn
  • ✅ 产品页面的开发者链接
  • ✅ 第三方平台(知乎、掘金等)

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 代理加速图片加载:

![图片描述](https://cdnproxy.some.im/gh/username/repo/image.png)

代码分割

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 工作流

  1. 从 main 分支创建特性分支
  2. 开发并本地测试
  3. 构建验证:yarn build
  4. 提交并推送
  5. 通过 PR 合并到 main
  6. 自动部署到 Vercel

文章发布流程

  1. content/articles/ 创建 .md 文件
  2. 填写完整的 frontmatter
  3. 编写文章内容
  4. 本地预览:yarn dev
  5. 检查 SEO metadata
  6. 提交并推送
  7. 自动部署并生成 sitemap

最佳实践总结

SEO 方面

  1. 每个页面都有唯一的 title 和 description
  2. 使用语义化的 URL 结构(日期 + slug)
  3. 添加完整的结构化数据(JSON-LD)
  4. 提供多语言版本
  5. 优化图片 alt 属性
  6. 内部链接优化
  7. 移动端友好(响应式设计)
  8. 快速加载(Core Web Vitals)

技术方面

  1. TypeScript 类型安全
  2. 组件化开发
  3. 代码分割
  4. SSR/SSG 混合渲染
  5. 环境变量管理
  6. 错误边界
  7. 无障碍访问(A11y)

内容方面

  1. 定期更新内容
  2. 提供有价值的原创内容
  3. 文章结构清晰(使用标题层级)
  4. 代码示例完整
  5. 添加相关链接

未来规划

功能增强

  • 全文搜索功能
  • 评论系统(Giscus)
  • 文章系列支持
  • RSS 订阅
  • 阅读时间估算
  • 相关文章推荐
  • 标签云
  • 归档页面

SEO 优化

  • 添加 FAQ Schema
  • 优化 Core Web Vitals
  • 增加视频内容的 VideoObject Schema
  • A/B 测试标题和描述
  • 建立更多高质量反向链接

技术升级

  • 升级到 Next.js 15
  • 实现 ISR(增量静态再生)
  • 添加 PWA 支持
  • 集成 Web Analytics(Plausible)
  • 实现文章草稿系统

总结

83d.me 站点是一个完整的现代 Web 应用实践案例,它不仅展示了技术能力,更重要的是实现了:

  1. 优秀的用户体验:快速加载、响应式设计、暗黑模式
  2. 完整的 SEO 优化:从 metadata 到结构化数据,从 sitemap 到域名迁移
  3. 可维护的代码结构:TypeScript、组件化、模块化
  4. 平滑的域名迁移:通过 301 重定向完整继承 404.ms 的 SEO 权重

这个项目证明了:好的技术选型 + 完整的 SEO 策略 + 持续的内容更新 = 成功的个人站点

如果你也在构建个人站点,希望这些实践经验能对你有所帮助!


参考资源

相关文章

📮 订阅更新
每周收到最新文章推送,不错过精彩内容

💡 我们尊重您的隐私,不会将邮箱用于其他用途

加载中...