跳转到内容

VitePress 博客 SEO 优化与性能提升指南 2026

VitePress SEO Guide

VitePress 基于 Vite + Vue 3,天生就拥有极快的构建速度和优秀的首屏性能。但「快」不等于「SEO 好」——一个 VitePress 博客想要在 Google / Bing 搜索中获得高排名,还需要在结构化数据、Sitemap、Core Web Vitals、社交分享等方面做系统优化。

本文以本站 y-m.top(VitePress 2.0-alpha + pnpm)的真实配置为例,分享从 0 到 1 完成 VitePress SEO 优化的全部实践。文中的每一行配置代码都来自本站仓库,可以直接参考使用。


VitePress 的 SEO 基础能力

框架原生 SEO 优势

VitePress 在 SEO 方面有几个天然优势:

特性说明对 SEO 的影响
SSG 预渲染构建时生成完整 HTML✅ 搜索引擎爬虫无需执行 JS 即可获取内容
cleanUrlsURL 无 .html 后缀✅ URL 更简洁,搜索引擎友好
metaChunk将 meta 信息提取为独立 chunk✅ 减小主 HTML 体积,加快解析
lastUpdated自动记录文件修改时间✅ 可用于 article:modified_time
sitemap内置 sitemap.xml 生成✅ 自动生成站点地图
transformPageData构建时动态修改页面元数据✅ 可批量注入 canonical / og / json-ld
head 配置全局 head 标签注入✅ 统一管理 meta 标签

全局 head 配置

.vitepress/configs/head.ts 中配置全局 head 标签:

ts
// .vitepress/configs/head.ts
import type { HeadConfig } from 'vitepress'

export const head: HeadConfig[] = [
  // 浏览器 UI 配置
  ['meta', { name: 'theme-color', content: '#ffffff' }],
  ['meta', { name: 'msapplication-TileColor', content: '#da532c' }],
  ['meta', { name: 'format-detection', content: 'telephone=no' }],

  // 网站图标
  ['link', { rel: 'icon', type: 'image/png', href: '/favicon-96x96.png', sizes: '96x96' }],
  ['link', { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' }],
  ['link', { rel: 'shortcut icon', href: '/favicon.ico' }],
  ['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }],
  ['link', { rel: 'manifest', href: '/site.webmanifest' }],

  // 站点基本信息
  ['meta', { name: 'author', content: '你的站点名' }],
  ['meta', { name: 'copyright', content: '你的站点名' }],

  // Open Graph 全局默认
  ['meta', { property: 'og:type', content: 'website' }],
  ['meta', { property: 'og:locale', content: 'zh-Hans' }],
  ['meta', { property: 'og:site_name', content: '你的站点名' }],

  // Twitter Card
  ['meta', { name: 'twitter:card', content: 'summary_large_image' }],

  // Robots 指令
  ['meta', { name: 'robots', content: 'index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1' }],
]

📌 robots meta 详解

  • index, follow:允许索引并跟踪链接
  • max-snippet:-1:不限制摘要长度
  • max-image-preview:large:允许大图预览(影响搜索结果展示)
  • max-video-preview:-1:不限制视频预览

frontmatter 最佳实践

每篇文章的 frontmatter 是 SEO 的第一道关卡:

yaml
---
title: 文章标题 2026:包含核心关键词的完整标题
description: 150-160 字符的描述文本,包含主关键词和辅助关键词,自然语句。
keywords:
  - 关键词1
  - 关键词2
  - 关键词3
head:
  - - meta
    - property: og:image
      content: https://example.com/og-image.jpg
  - - meta
    - name: twitter:image
      content: https://example.com/og-image.jpg
---

frontmatter SEO 检查清单

✅ title 包含核心关键词,建议 30-60 字符
✅ description 150-160 字符(Google 搜索结果摘要上限)
✅ keywords 写 5-8 个相关关键词(Google 已不参考,但 Bing 仍使用)
✅ og:image 每篇都配独立封面图(1200×630px 最佳)
✅ twitter:image 与 og:image 可共用同一张图
✅ title 格式:核心关键词 + 副标题(用「:」或「|」分隔)

结构化数据(JSON-LD)

结构化数据能让搜索引擎理解页面内容类型,从而在搜索结果中展示富摘要(Rich Snippets),大幅提升点击率(CTR)。

本站实践:transformPageData 自动注入

本站通过 transformPageData 在构建时自动为每个页面注入 JSON-LD:

ts
// .vitepress/configs/transformPageData.ts
import type { UserConfig } from 'vitepress'

const baseUrl = 'https://y-m.top'
const defaultOgImage = '/logo/y-m-top-og.webp'

export const transformPageData: UserConfig['transformPageData'] = (pageData) => {
  pageData.frontmatter.head ??= []

  // 1. 生成 canonical URL
  let DynamicUrl = `${baseUrl}/${pageData.relativePath}`.replace(/\.md$/, '')
  if (DynamicUrl.endsWith('/index')) {
    DynamicUrl = DynamicUrl.slice(0, -5)
  }

  const title = pageData.frontmatter?.hero?.name || pageData.title || '站点名'
  const description = pageData.frontmatter?.hero?.tagline || pageData.description || ''
  const modified_time = pageData.lastUpdated
    ? new Date(pageData.lastUpdated).toISOString()
    : new Date().toISOString()

  // 2. 获取 og:image(优先 frontmatter 中的,回退默认)
  const ogImageEntry = pageData.frontmatter.head.find(
    (item: any) => item[0] === 'meta' && item[1]?.property === 'og:image'
  )
  const ogImage = ogImageEntry?.[1]?.content || defaultOgImage

  // 3. 根据页面类型生成不同的 JSON-LD
  const isHome = pageData.relativePath === 'index.md'
  const jsonLd = isHome
    ? {
        '@context': 'https://schema.org',
        '@type': 'WebSite',        // 首页用 WebSite 类型
        url: baseUrl + '/',
        inLanguage: 'zh-Hans',
        author: { '@type': 'Person', name: 'y-m.top', url: baseUrl },
        publisher: {
          '@type': 'Organization',
          name: 'y-m.top',
          logo: { '@type': 'ImageObject', url: baseUrl + '/logo/y-m-top-og.webp' }
        },
        description: description,
        name: title
      }
    : {
        '@context': 'https://schema.org',
        '@type': 'BlogPosting',    // 文章页用 BlogPosting 类型
        headline: title,
        inLanguage: 'zh-Hans',
        author: { '@type': 'Person', name: 'y-m.top', url: baseUrl },
        publisher: {
          '@type': 'Organization',
          name: 'y-m.top',
          logo: { '@type': 'ImageObject', url: baseUrl + '/logo/y-m-top-og.webp' }
        },
        mainEntityOfPage: DynamicUrl,
        description: description,
        url: DynamicUrl,
        image: ogImage
      }

  // 4. 批量注入 head 标签
  pageData.frontmatter.head.push(
    ['link', { rel: 'canonical', href: DynamicUrl }],
    ['meta', { property: 'og:title', content: title }],
    ['meta', { property: 'og:url', content: DynamicUrl }],
    ['meta', { property: 'og:image', content: ogImage }],
    ['meta', { property: 'og:description', content: description }],
    ['meta', { name: 'twitter:title', content: title }],
    ['meta', { name: 'twitter:image', content: ogImage }],
    ['meta', { name: 'twitter:description', content: description }],
    ['meta', { property: 'article:published_time', content: '2020-07-21T08:17:36.000Z' }],
    ['meta', { property: 'article:modified_time', content: modified_time }],
    ['script', { type: 'application/ld+json' }, JSON.stringify(jsonLd)]
  )
}

常用 Schema 类型选择

Schema 类型适用场景富摘要效果
WebSite首页站点名称 + 搜索框
BlogPosting博客文章标题 + 作者 + 发布日期 + 封面图
TechArticle技术教程同 BlogPosting,更适合技术内容
FAQPageFAQ 页面折叠式问答展示
BreadcrumbList面包屑导航搜索结果中显示路径
HowTo教程步骤分步展示
Article通用文章标题 + 日期 + 图片

FAQPage 结构化数据示例

如果你的文章底部有 FAQ 折叠块,可以额外注入 FAQPage Schema:

ts
// 在文章 <script setup> 中动态注入
import { onMounted } from 'vue'

onMounted(() => {
  const script = document.createElement('script')
  script.type = 'application/ld+json'
  script.text = JSON.stringify({
    "@context": "https://schema.org",
    "@type": "FAQPage",
    "mainEntity": [
      {
        "@type": "Question",
        "name": "VitePress 需要装 SEO 插件吗?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "VitePress 原生支持 SSG、Sitemap 和 head 配置,基本 SEO 不需要额外插件。结构化数据可通过 transformPageData 自动注入。"
        }
      }
    ]
  })
  document.head.appendChild(script)
})

⚠️ 注意:FAQPage 的内容必须与页面可见的 FAQ 文本完全一致,否则可能被 Google 判定为作弊。


Sitemap 与 Robots

VitePress 内置 Sitemap

VitePress 2.0 内置了 sitemap 生成功能,只需一行配置:

ts
// .vitepress/config.mts
export default defineConfig({
  sitemap: {
    hostname: 'https://y-m.top'
  }
})

构建完成后,dist/sitemap.xml 会自动生成。配合 cleanUrls: true,所有 URL 都是无 .html 后缀的干净链接。

IndexNow 自动提交

Sitemap 生成后,搜索引擎需要主动去抓取。本站通过 buildEnd 钩子在每次构建完成后自动向 IndexNow 提交所有 URL:

ts
// .vitepress/configs/buildEnd.ts
import path from 'node:path'
import fs from 'node:fs'
import type { SiteConfig } from 'vitepress'

export async function buildEnd(siteConfig: SiteConfig) {
  try {
    const sitemapPath = path.resolve(siteConfig.outDir, 'sitemap.xml')

    // 轮询等待 sitemap.xml 生成(最多等 5 秒)
    let retryCount = 0
    while (!fs.existsSync(sitemapPath) && retryCount < 10) {
      await new Promise(resolve => setTimeout(resolve, 500))
      retryCount++
    }

    if (!fs.existsSync(sitemapPath)) {
      console.warn('\n⚠️ 未找到 sitemap.xml, 退出了 IndexNow 提交')
      return
    }

    // 从 sitemap.xml 中提取所有 URL
    const sitemapContent = fs.readFileSync(sitemapPath, 'utf-8')
    const urls = [...sitemapContent.matchAll(/<loc>(.*?)<\/loc>/g)].map(m => m[1])

    // 向 IndexNow API 提交
    const key = 'your-indexnow-key'
    const data = JSON.stringify({
      host: 'y-m.top',
      key: key,
      keyLocation: `https://y-m.top/${key}.txt`,
      urlList: urls
    })

    const res = await fetch('https://api.indexnow.org/indexnow', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json; charset=utf-8' },
      body: data
    })

    if (res.ok) {
      console.log(`\n🎉 成功将 ${urls.length} 个链接提交至 IndexNow!`)
    } else {
      console.error(`\n❌ 提交 IndexNow 失败: ${res.status} ${res.statusText}`)
    }
  } catch (error) {
    console.error('\n❌ 提交 IndexNow 时引发错误:', error)
  }
}

IndexNow 支持的搜索引擎

搜索引擎支持 IndexNow备注
Bing即时索引,效果最明显
Yandex俄罗斯搜索引擎
Seznam捷克搜索引擎
Google不支持 IndexNow,需通过 GSC 提交 Sitemap
百度需在百度搜索资源平台手动提交

💡 IndexNow 的密钥需要是一个 8-32 位的十六进制字符串,同时在站点根目录放一个 密钥.txt 文件用于验证。

robots.txt 配置

public/robots.txt 中配置:

txt
User-agent: *
Allow: /
Disallow: /tw/          # 如果繁体镜像不想被索引

Sitemap: https://y-m.top/sitemap.xml

如果你不希望繁体镜像页面被搜索引擎收录(避免重复内容惩罚),可以通过 robots.txt 或 meta robots 标签禁止爬取。

搜索引擎站长平台提交

平台提交方式链接
Google Search ConsoleSitemap + URL 检查search.google.com/search-console
Bing Webmaster ToolsSitemap + IndexNowbing.com/webmasters
百度搜索资源平台Sitemap + 主动推送ziyuan.baidu.com
搜狗站长平台Sitemap 提交zhanzhang.sogou.com

Core Web Vitals 性能优化

Core Web Vitals 是 Google 排名的重要信号,三个核心指标:

三大指标解读

指标全称含义良好阈值评分权重
LCPLargest Contentful Paint最大内容绘制时间≤ 2.5s最重要
CLSCumulative Layout Shift累积布局偏移≤ 0.1视觉稳定性
INPInteraction to Next Paint交互到下一次绘制≤ 200ms替代旧 FID 指标

LCP 优化策略

LCP 元素通常是首屏的大图或大标题。优化方向:

1. 图片优化

ts
// VitePress 中使用 Vite 的资源处理能力
// .vitepress/config.mts
export default defineConfig({
  vite: {
    assetsInclude: ['**/*.webp', '**/*.svg', '**/*.gif', '**/*.png', '**/*.jpg', '**/*.jpeg'],
  }
})
优化手段效果实施难度
使用 WebP 格式代替 JPG/PNG体积减少 25-35%
设置 loading="lazy" 非首屏图片减少首屏加载量
首屏图片设置 fetchpriority="high"优先加载 LCP 图片
图片设置 width/height 属性避免 CLS 偏移
使用 CDN 分发图片减少网络延迟⭐⭐
使用 <picture> 响应式图片按设备加载不同尺寸⭐⭐

首屏图片优先加载示例

html
<img
  src="/cover.webp"
  alt="封面图"
  width="1200"
  height="630"
  loading="eager"
  fetchpriority="high"
/>

2. 字体加载优化

css
/* 通过 font-display: swap 避免字体加载阻塞渲染 */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom.woff2') format('woff2');
  font-display: swap;  /* 关键:先用系统字体渲染,字体加载后替换 */
}

3. 关键 CSS 内联

VitePress 默认将关键 CSS 内联到 HTML <head> 中,无需额外配置。metaChunk: true 可以将 meta 信息提取为独立 chunk,进一步减小主 HTML 体积。

CLS 优化策略

CLS(累积布局偏移)通常由以下原因导致:

原因解决方案
图片无尺寸属性添加 widthheight
字体加载导致文字跳动使用 font-display: swap + size-adjust
广告/嵌入内容高度变化预留占位空间 min-height
动态插入内容在已渲染内容上方插入时使用 transform

INP 优化策略

INP 替代了旧的 FID 指标,衡量页面的整体交互响应速度:

优化方向:
1. 减少 JavaScript 执行时间
   - 代码分割(Code Splitting)
   - 延迟加载非关键 JS(defer / async)
   - Tree Shaking 去除无用代码

2. 拆分长任务(Long Task)
   - 使用 requestIdleCallback / scheduler.postTask
   - 将大任务拆分为 < 50ms 的小任务

3. 减少第三方脚本
   - 延迟加载分析脚本
   - 使用 Partytown 将第三方 JS 移入 Web Worker

性能检测工具

工具用途推荐度
PageSpeed Insights线上检测 LCP/CLS/INP + 优化建议⭐⭐⭐⭐⭐
LighthouseChrome DevTools 内置,本地检测⭐⭐⭐⭐⭐
Core Web Vitals ReportGSC 中的真实用户数据⭐⭐⭐⭐
Web Vitals Chrome 扩展实时查看当前页面指标⭐⭐⭐⭐
CrUX DashboardChrome 用户体验报告数据可视化⭐⭐⭐

Open Graph 与社交分享

OG 标签完整配置

Open Graph 协议决定了链接在微信 / Twitter / Facebook / Telegram 等社交平台上的预览卡片样式:

OG 标签作用示例值
og:type内容类型website / article
og:title分享标题文章标题
og:description分享描述150 字以内摘要
og:image分享封面图1200×630px
og:url页面 canonical URLhttps://y-m.top/xxx
og:site_name站点名称你的博客名
og:locale语言区域zh-Hans
twitter:cardTwitter 卡片类型summary_large_image
twitter:imageTwitter 封面图同 og:image

本站通过 transformPageData 自动注入所有 OG 标签,无需手动在每篇文章中重复配置。

OG 图片设计规范

📐 尺寸:1200 × 630 px(推荐)
📐 比例:1.91:1
📐 格式:JPG / PNG / WebP
📐 文件大小:≤ 300KB
📐 安全区域:中心 1200×630,边缘留 80px 安全区

设计建议:
- 使用品牌色作为背景
- 标题文字 ≥ 42px,确保移动端可读
- 添加站点 Logo(左下角或右下角)
- 使用 Unsplash 免费图片作为封面(本站实践)

社交预览测试工具

工具用途
Meta Sharing DebuggerFacebook / WhatsApp 预览
Twitter Card ValidatorTwitter 卡片预览
OpenGraph.xyz多平台预览
微信文件传输助手发送链接查看微信内预览效果

内链策略

内链是 SEO 中最容易被忽视的部分,良好的内链结构能帮助搜索引擎理解站点架构,传递页面权重。

相关文章推荐

在每篇文章末尾添加「延伸阅读」区块,手动推荐 5-7 篇相关文章:

markdown
## 延伸阅读

- [流媒体观影终极指南](/streaming/2026-ultimate-core-guide)
- [Netflix 国内观看指南 2026](/streaming/netflix-guide)
- [优质机场推荐与选购指南](/serve/airport/summary)

内链锚文本最佳实践

✅ 好的锚文本:
- 「Netflix 国内观看指南 2026」→ 包含关键词 + 年份
- 「优质机场推荐」→ 简洁描述目标页面内容

❌ 差的锚文本:
- 「点击这里」→ 无信息量
- 「这篇文章」→ 搜索引擎无法理解目标页面主题

面包屑导航

VitePress 默认侧边栏提供了层级导航。如果需要额外的面包屑结构化数据:

ts
// 面包屑 BreadcrumbList JSON-LD
const breadcrumbJsonLd = {
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "首页",
      "item": "https://y-m.top/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "技术笔记",
      "item": "https://y-m.top/notes/"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "VitePress",
      "item": "https://y-m.top/notes/vitepress/"
    }
  ]
}

内链密度建议

指标建议值说明
每篇内链数量5-8 个过少不够,过多像垃圾站
内链锚文本多样性≥ 3 种不要所有链接都用相同锚文本
相关性只链接主题相关的文章
深度链接比例≥ 60%链接到具体文章而非分类页

站点分析集成

三大分析工具对比

工具隐私友好免费国内可用特点
Google Analytics 4⚠️ 一般❌ 需代理功能最全,生态最好
Umami✅ 优秀✅ 自建轻量、隐私友好、Cookieless
Plausible✅ 优秀💰 付费开源、简洁、GDPR 合规
百度统计⚠️ 一般国内访问无障碍
Cloudflare Web Analytics✅ 优秀免费、隐私友好、无脚本

GA4 配置(本站实践)

本站使用 Google Analytics 4,在 head.ts 中全局注入:

ts
// .vitepress/configs/head.ts
export const head: HeadConfig[] = [
  // ... 其他配置
  [
    'script',
    { async: '', src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX' }
  ],
  [
    'script',
    {},
    `window.dataLayer = window.dataLayer || [];
     function gtag(){dataLayer.push(arguments);}
     gtag('js', new Date());
     gtag('config', 'G-XXXXXXXXXX');`
  ]
]

⚠️ GA4 在国内部分网络环境下可能加载缓慢。如果你的读者主要在国内,建议同时接入 Umami 或百度统计作为补充。

Umami 自建方案

bash
# Docker 一键部署 Umami
docker run -d \
  --name umami \
  -p 3000:3000 \
  -e DATABASE_URL=postgresql://umami:umami@db:5432/umami \
  -e HASH_SALT=your-random-salt \
  ghcr.io/umami-software/umami:latest

# 在 VitePress head 中添加追踪代码
# <script async src="https://umami.your-domain.com/script.js" data-website-id="xxx"></script>

PWA 与离线访问

VitePress PWA 插件

使用 vite-plugin-pwa 为 VitePress 添加 PWA 能力:

ts
// .vitepress/config.mts
import { VitePWA } from 'vite-plugin-pwa'

export default defineConfig({
  vite: {
    plugins: [
      VitePWA({
        registerType: 'autoUpdate',
        includeAssets: ['favicon.svg', 'favicon.ico', 'robots.txt'],
        manifest: {
          name: '你的站点名',
          short_name: '简称',
          description: '站点描述',
          theme_color: '#ffffff',
          icons: [
            {
              src: 'pwa-192x192.png',
              sizes: '192x192',
              type: 'image/png'
            },
            {
              src: 'pwa-512x512.png',
              sizes: '512x512',
              type: 'image/png'
            }
          ]
        },
        workbox: {
          // 预缓存 VitePress 构建产物
          globPatterns: ['**/*.{css,js,html,svg,png,ico,txt,woff2}'],
          // 运行时缓存策略
          runtimeCaching: [
            {
              urlPattern: /^https:\/\/images\.unsplash\.com\/.*/i,
              handler: 'CacheFirst',
              options: {
                cacheName: 'unsplash-images',
                expiration: {
                  maxEntries: 100,
                  maxAgeSeconds: 60 * 60 * 24 * 30  // 30 天
                }
              }
            }
          ]
        }
      })
    ]
  }
})

PWA 缓存策略选择

策略适用场景说明
CacheFirst静态资源(CSS/JS/字体/图标)优先缓存,缓存不存在才请求
NetworkFirstHTML 页面优先网络,离线时回退缓存
StaleWhileRevalidate图片/API 数据先返回缓存,同时后台更新
NetworkOnly分析请求不缓存,始终请求网络
CacheOnly离线页面只用缓存

💡 VitePress 的 HTML 页面建议用 NetworkFirst——保证用户看到最新内容,同时离线时也能访问缓存版本。


Google Search Console 监测

配置流程

  1. 添加站点属性

    • 访问 Google Search Console
    • 添加域名属性(推荐)或 URL 前缀属性
    • 通过 DNS TXT 记录验证
  2. 提交 Sitemap

    • 在 GSC 左侧菜单 → Sitemaps
    • 输入 sitemap.xml 并提交
    • 等待 Google 处理(通常 1-3 天)
  3. 请求索引

    • 对于新发布的重要文章,使用 URL 检查工具
    • 点击「请求编入索引」
    • 加速首次收录

关键指标监测

指标位置含义
索引覆盖率索引 → 网页已被 Google 索引的页面数
搜索表现搜索结果 → 搜索分析展示次数 / 点击次数 / CTR / 平均排名
Core Web Vitals体验 → 核心网页指标LCP / CLS / INP 真实用户数据
移动设备易用性体验 → 移动设备易用性移动端友好度报告
链接报告链接 → 外部链接 / 内部链接反向链接和内链统计

常见索引问题排查

问题 1:页面未被索引
→ 检查 robots.txt 是否屏蔽
→ 检查 meta robots 是否为 noindex
→ 检查 canonical URL 是否正确
→ 在 GSC 中手动请求索引

问题 2:索引后排名低
→ 检查 title/description 是否包含目标关键词
→ 检查内容质量(字数、深度、原创性)
→ 检查内链数量和质量
→ 检查 Core Web Vitals 是否达标

问题 3:页面从索引中被移除
→ 检查服务器是否经常不可用(503 错误)
→ 检查是否被标记为重复内容
→ 检查是否被 Manual Action 处罚

本站优化实践复盘

y-m.top 的 SEO 配置架构

本站的 VitePress 配置采用了模块化拆分,便于维护:

.vitepress/
├── config.mts              # 主配置入口
├── configs/
│   ├── head.ts             # 全局 head 标签
│   ├── transformPageData.ts # 动态 meta + JSON-LD 注入
│   ├── buildEnd.ts         # 构建后 IndexNow 提交
│   ├── nav.ts              # 导航栏
│   ├── sidebar.ts          # 侧边栏
│   ├── search.ts           # 搜索配置
│   ├── markdown.ts         # Markdown 插件
│   └── socialLinks.ts      # 社交链接
└── theme/                  # 自定义主题

关键配置汇总

ts
// .vitepress/config.mts 中的 SEO 相关配置
export default defineConfig({
  head,                        // 全局 meta 标签
  sitemap: {                   // 站点地图
    hostname: 'https://y-m.top'
  },
  transformPageData,           // 自动注入 canonical/og/json-ld
  buildEnd,                    // 构建后 IndexNow 提交
  cleanUrls: true,             // 干净 URL
  metaChunk: true,             // meta 独立 chunk
  lastUpdated: true,           // 记录更新时间
  srcDir: 'content',           // 源文件目录
})

繁体镜像的 SEO 处理

本站有简体 / 繁体双版本,为了避免重复内容问题:

处理方式说明
URL 分离简体 /streaming/xxx,繁体 /tw/streaming/xxx
hreflang 标签告诉搜索引擎两个版本的关系
robots.txt可选:禁止爬取 /tw/ 目录
OpenCC 转换使用 opencc-js 自动转换简→繁
ts
// 简体→繁体自动转换(本站实践)
import * as OpenCC from 'opencc-js'
const converter = OpenCC.Converter({ from: 'cn', to: 'tw', _config: 's2t' })

// 在 locales 中配置繁体版本
locales: {
  root: { label: '简体中文', lang: 'zh-Hans', ... },
  tw: {
    label: '繁體中文',
    lang: 'zh-Hant',
    link: '/tw/',
    title: converter('简体标题'),
    description: converter('简体描述'),
    ...
  }
}

优化效果数据

经过以上优化,本站在 SEO 方面的表现:

指标优化前优化后提升幅度
Google 索引页面数~50400+8 倍
Lighthouse SEO 评分75100+25
Lighthouse 性能评分8296+14
LCP(首屏绘制)3.2s1.1s-66%
CLS(布局偏移)0.150.02-87%
Bing 收录速度数周24h 内IndexNow 效果

SEO 优化检查清单

将上述所有要点整理为一份可操作的检查清单:

基础配置

□ 配置 sitemap.hostname
□ 开启 cleanUrls: true
□ 开启 lastUpdated: true
□ 开启 metaChunk: true
□ 配置全局 head 标签(favicon / robots / og 默认值)
□ 配置 public/robots.txt
□ 配置 public/站点验证文件(Google / Bing / 百度)

每篇文章

□ title 包含核心关键词(30-60 字符)
□ description 150-160 字符
□ keywords 5-8 个相关关键词
□ og:image 独立封面图(1200×630px)
□ jsonLD 结构化数据(TechArticle / BlogPosting)
□ 文章末尾 5-7 个内链(延伸阅读)
□ 图片设置 width / height / alt 属性
□ 首屏图片设置 fetchpriority="high"

构建与部署

□ transformPageData 自动注入 canonical / og / json-ld
□ buildEnd 钩子自动提交 IndexNow
□ 图片使用 WebP 格式
□ 第三方脚本使用 async / defer
□ PWA Service Worker 缓存策略配置
□ GA4 / Umami 分析代码接入

持续监测

□ 每周检查 Google Search Console 索引状态
□ 每月检查 Core Web Vitals 真实用户数据
□ 定期检查 Lighthouse 性能评分
□ 监控搜索关键词排名变化
□ 检查死链(404 页面)并修复
□ 每月提交一次 Sitemap(确保新页面被收录)

常见问题(FAQ)

Q1:VitePress 需要安装额外的 SEO 插件吗?

不需要。VitePress 2.0 原生提供:
• SSG 预渲染 → 搜索引擎可直接读取 HTML 内容
• 内置 sitemap.xml 生成
• head 配置 → 全局 meta 标签管理
• transformPageData → 构建时动态注入 meta 和 JSON-LD
• cleanUrls → URL 无 .html 后缀

以上能力已覆盖 90% 的 SEO 需求。唯一可能需要插件的是 PWA 功能(vite-plugin-pwa)。

Q2:为什么我的文章在 Google 搜索中显示的标题和 frontmatter 中的不一样?

Google 可能会根据搜索关键词自动重写标题。常见原因:
• title 过长或过短 → Google 认为需要优化
• title 与搜索意图不匹配 → Google 使用 H1 或描述文本
• title 中关键词堆砌 → Google 简化

解决方法:
• 确保 title 简洁明了(30-60 字符)
• title 包含核心关键词
• H1 与 title 保持一致
• 使用 GSC URL 检查工具查看 Google 实际抓取的标题

Q3:VitePress 的 SSG 和 CSR 有什么区别?对 SEO 有什么影响?

SSG(Static Site Generation):
• 构建时预渲染为完整 HTML
• 搜索引擎爬虫无需执行 JS 即可获取内容
• VitePress 默认使用 SSG → SEO 友好 ✅

CSR(Client-Side Rendering):
• 浏览器加载 JS 后才渲染内容
• 部分搜索引擎爬虫不执行 JS → 可能无法索引
• VitePress 不使用纯 CSR

结论:VitePress 的 SSG 模式天然 SEO 友好,无需额外处理。
但注意:<script setup> 中动态生成的内容不会被预渲染到 HTML 中,
仅靠客户端 JS 执行。重要的 SEO 内容(标题、描述)应放在 frontmatter 中。

Q4:如何加速 Google 对新文章的收录?

最快路径:
1. 发布文章后立即触发构建部署
2. buildEnd 钩子自动提交 IndexNow → Bing 即时收录
3. 在 GSC 中使用 URL 检查工具 → 请求编入索引
4. 在已收录的文章中添加新文章的内链
5. 确保新文章在 sitemap.xml 中(VitePress 自动生成)

通常新文章 1-3 天内会被 Google 收录。
如果超过一周仍未收录,检查 robots.txt 和 meta robots 是否有误。

Q5:本站同时有简体和繁体版本,会被 Google 判定为重复内容吗?

风险存在但可规避:

方案 1:禁止繁体索引(简单粗暴)
→ robots.txt 中 Disallow: /tw/
→ 适合只面向简体中文用户

方案 2:使用 hreflang 标签(推荐)
→ 在 head 中添加 hreflang 互指
→ 告诉 Google 两个版本是同一内容的不同语言变体

方案 3:canonical 指向简体版
→ 繁体页面 canonical 指向简体版
→ Google 会只索引简体版,但不影响用户访问繁体

本站目前使用方案 1(robots.txt 禁止 /tw/),因为目标受众主要是简体中文用户。

Q6:Cloudflare Pages / Vercel / Netlify 哪个对 VitePress SEO 更好?

三者都能完美支持 VitePress 部署,SEO 差异不大:

| 平台 | CDN 节点 | 自定义 Header | 预渲染 | 免费额度 |
|------|---------|:--:|:--:|:--:|
| Cloudflare Pages | 全球 300+ | ✅ | ✅ | 无限 |
| Vercel | 全球 100+ | ✅ | ✅ | 100GB/月 |
| Netlify | 全球 100+ | ✅ | ✅ | 100GB/月 |

推荐 Cloudflare Pages:
• 全球边缘节点最多,访问速度最快
• 无限免费请求量
• 原生支持自定义 Header 和重定向规则
• 参考 [VitePress + Cloudflare Pages 搭建指南](/notes/vitepress/build-with-cloudflare)

总结

VitePress 的 SEO 优化不需要复杂的插件体系——框架原生能力已经覆盖了绝大部分需求。以本站 y-m.top 的实践经验来看,做好以下五件事就能达到 95 分以上:

🎯 1. transformPageData 自动注入
   → canonical URL + og 标签 + JSON-LD 结构化数据
   → 一处配置,所有页面自动生效

🎯 2. Sitemap + IndexNow 自动提交
   → sitemap.hostname 配置 + buildEnd 钩子
   → 新文章发布后 Bing 24h 内收录

🎯 3. Core Web Vitals 优化
   → WebP 图片 + fetchpriority + font-display: swap
   → LCP ≤ 2.5s / CLS ≤ 0.1 / INP ≤ 200ms

🎯 4. 内链策略
   → 每篇文章 5-8 个延伸阅读链接
   → 锚文本包含关键词 + 自然语句

🎯 5. Google Search Console 持续监测
   → 提交 Sitemap + 请求索引 + 监控排名
   → 定期检查索引覆盖率和 Core Web Vitals

如果你正在使用 VitePress 搭建博客,希望本文的实践经验能帮你少走弯路。本站的所有配置代码都在仓库中公开,欢迎参考。


延伸阅读



延伸阅读

免责声明

本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。