SEO 与元数据

让 Agent 为每个可索引路由维护唯一 title、meta description、canonical,并成对维护 Open Graph 与 Twitter 卡片字段;与 hreflang、结构化数据及 robots/sitemap 策略一致。

SPA 与 SSR 混合站点需在 SKILL 中说明首屏 HTML 是否含关键元数据;对仅客户端渲染的路由考虑预渲染或动态 meta API。

结构化数据(JSON-LD)仅用于真实可见内容,避免堆砌关键词;多语言站点配置 hreflang 与 x-default,与国内备案域名的规范 URL 一致。

元数据流水线(skill-flow)

  [ 路由 / 构建 确定页面身份 ]
              │
              ▼
   ┌────────────────────┐
   │ HTML head:         │──── title、meta description、canonical
   │ 唯一性与规范化 URL   │      (与最终用户可见 URL 一致)
   └────────────────────┘
              │
              ▼
   ┌────────────────────┐
   │ 社交层:             │──── og:title / og:description / og:url
   │ OG + Twitter 对齐    │      twitter:* 与 OG 同义或显式覆盖
   └────────────────────┘      og:image、twitter:image:绝对 HTTPS
              │
              ▼
   ┌────────────────────┐
   │ 扩展:               │──── JSON-LD(仅对应可见内容)
   │ hreflang / 结构化    │      多语言 alternate 与 x-default
   └────────────────────┘
              │
              ▼
   ┌────────────────────┐
   │ 抓取策略:           │──── robots.txt、sitemap、noindex
   │ staging / 账户 / 参数 │      Search Console 类工具验证
   └────────────────────┘

生产环境应为 og:imagetwitter:image 提供绝对 HTTPS 地址(常见 1200×630),并配 og:image:alt;本仓库 head 未写死图片 URL,避免指向不存在资源。

唯一性与 canonical

  • 标题与描述长度符合搜索引擎展示习惯,避免全站重复。
  • 带查询参数、分页、追踪参数的 URL 明确 canonical 指向主规范地址。
  • 核心 Web 指标与 SEO 分列,不在 SKILL 中混为一谈。

HTML head 中完整的必要 meta 标签示例(含 OG / Twitter Card):

<!-- HTML head 完整示例:SEO + Open Graph + Twitter Card -->
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <!-- 核心 SEO:title 55-65字符,description 150-160字符 -->
  <title>产品名称 - 简洁的价值主张 | 品牌名</title>
  <meta name="description"
    content="不超过160字符的摘要,包含核心关键词,鼓励点击。避免与其他页面重复。" />

  <!-- canonical:消除重复索引(含追踪参数、分页等) -->
  <link rel="canonical" href="https://www.example.com/products/widget" />

  <!-- Open Graph(社交分享)-->
  <meta property="og:type"        content="article" />
  <meta property="og:url"         content="https://www.example.com/products/widget" />
  <meta property="og:title"       content="产品名称 - 价值主张" />
  <meta property="og:description" content="用于社交分享的摘要,可与 meta description 不同。" />
  <meta property="og:image"       content="https://www.example.com/og/widget.jpg" />
  <meta property="og:image:alt"   content="产品图片的文字描述(可访问性)" />
  <meta property="og:image:width" content="1200" />
  <meta property="og:image:height" content="630" />
  <meta property="og:locale"      content="zh_CN" />
  <meta property="og:site_name"   content="品牌名" />

  <!-- Twitter Card -->
  <meta name="twitter:card"        content="summary_large_image" />
  <meta name="twitter:title"       content="产品名称(可比 og:title 更短)" />
  <meta name="twitter:description" content="Twitter 分享摘要。" />
  <meta name="twitter:image"       content="https://www.example.com/og/widget.jpg" />
  <meta name="twitter:image:alt"   content="产品图片描述" />
  <meta name="twitter:site"        content="@yourbrand" />

  <!-- 多语言 hreflang -->
  <link rel="alternate" hreflang="zh-CN"
        href="https://www.example.com/products/widget" />
  <link rel="alternate" hreflang="en"
        href="https://www.example.com/en/products/widget" />
  <link rel="alternate" hreflang="x-default"
        href="https://www.example.com/products/widget" />
</head>

Open Graph 与 Twitter

og:urlcanonical 应一致;twitter:cardsummary_large_image 时需同时提供大图 URL 与合适 alt。

  • 社交分享图尺寸与 alt 文案单独维护,与页面主图不必相同。
  • Twitter 专用标签可在与 OG 冲突时覆盖(例如更短的分享标题)。

结构化数据与 hreflang

JSON-LD 类型与页面实际类型一致(文章、产品、面包屑等);勿为不可见内容生成虚假结构化字段。

JSON-LD 结构化数据示例(Article / Product / BreadcrumbList):

<!-- Article JSON-LD -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "文章标题(<110 字符)",
  "description": "文章摘要,与 meta description 可一致。",
  "author": {
    "@type": "Person",
    "name": "作者姓名",
    "url": "https://www.example.com/authors/jane"
  },
  "publisher": {
    "@type": "Organization",
    "name": "发布机构",
    "logo": {
      "@type": "ImageObject",
      "url": "https://www.example.com/logo.png"
    }
  },
  "datePublished": "2024-01-15T08:00:00+08:00",
  "dateModified": "2024-03-20T12:00:00+08:00",
  "image": "https://www.example.com/articles/hero.jpg",
  "url": "https://www.example.com/articles/my-article"
}
</script>

<!-- Product JSON-LD -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "产品名称",
  "image": "https://www.example.com/products/widget.jpg",
  "description": "产品描述。",
  "sku": "WIDGET-001",
  "offers": {
    "@type": "Offer",
    "price": "299.00",
    "priceCurrency": "CNY",
    "availability": "https://schema.org/InStock",
    "url": "https://www.example.com/products/widget"
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.8",
    "reviewCount": "120"
  }
}
</script>

<!-- BreadcrumbList JSON-LD -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "首页",
      "item": "https://www.example.com/" },
    { "@type": "ListItem", "position": 2, "name": "产品",
      "item": "https://www.example.com/products/" },
    { "@type": "ListItem", "position": 3, "name": "Widget",
      "item": "https://www.example.com/products/widget" }
  ]
}
</script>

robots、sitemap 与 noindex

robots.txt、sitemap 与 noindex 分工明确:staging、账户页与重复参数 URL 默认不索引,并在变更后验证 Search Console 类工具。

robots.txt 配置示例:

# /robots.txt — 生产环境
User-agent: *
Allow: /

# 不允许索引账户内页、重复参数、API 路径
Disallow: /account/
Disallow: /api/
Disallow: /*?ref=     # 追踪参数
Disallow: /*?sort=    # 仅影响排序的参数页
Disallow: /search?q=  # 空搜索结果页

# 声明 sitemap 位置
Sitemap: https://www.example.com/sitemap.xml
Sitemap: https://www.example.com/sitemap-products.xml

sitemap.xml 生成示例(Node.js 脚本,适用于 Next.js / 静态站点):

// scripts/generate-sitemap.mjs
import { writeFileSync } from 'fs';
import { getAllProducts, getAllArticles } from './lib/api.mjs';

const BASE_URL = 'https://www.example.com';

async function generateSitemap() {
  const products = await getAllProducts();
  const articles = await getAllArticles();

  const staticPages = ['/', '/about', '/contact', '/products'];

  const urls = [
    // 静态页面
    ...staticPages.map(path => ({
      loc: `${BASE_URL}${path}`,
      changefreq: 'weekly',
      priority: path === '/' ? '1.0' : '0.8',
      lastmod: new Date().toISOString().split('T')[0],
    })),
    // 动态产品页
    ...products.map(p => ({
      loc: `${BASE_URL}/products/${p.slug}`,
      changefreq: 'daily',
      priority: '0.9',
      lastmod: p.updatedAt,
    })),
    // 文章页
    ...articles.map(a => ({
      loc: `${BASE_URL}/articles/${a.slug}`,
      changefreq: 'monthly',
      priority: '0.7',
      lastmod: a.updatedAt,
    })),
  ];

  const xml = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map(u => `  <url>
    <loc>${u.loc}</loc>
    <lastmod>${u.lastmod}</lastmod>
    <changefreq>${u.changefreq}</changefreq>
    <priority>${u.priority}</priority>
  </url>`).join('\n')}
</urlset>`;

  writeFileSync('./public/sitemap.xml', xml);
  console.log(`Generated sitemap with ${urls.length} URLs`);
}

generateSitemap();

SKILL 片段

---
name: seo-metadata-cn
description: 维护页面 SEO 元数据、canonical、结构化数据与抓取策略
tags: [seo, metadata, structured-data, sitemap]
---
# 基础元数据
1. title 55-65字符,每页唯一,格式:关键词 - 价值主张 | 品牌名
2. meta description 150-160字符,包含核心关键词,避免全站重复
3. canonical 与最终用户 URL 一致,消除参数/分页产生的重复索引

# Open Graph 与 Twitter Card
4. og:url 与 canonical 完全一致
5. og:image 绝对 HTTPS 地址,尺寸 1200×630,配 og:image:alt
6. twitter:card = summary_large_image 时同时提供 twitter:image
7. og:locale 与页面语言对应(zh_CN / en_US)

# 结构化数据(JSON-LD)
8. 类型与实际可见内容对应:Article/Product/BreadcrumbList
9. 不为不可见或合成内容生成 JSON-LD(避免处罚)
10. 每次上线用 Google 富结果测试工具验证

# 多语言与抓取
11. hreflang 成对出现(互相引用),x-default 指向默认语区
12. robots.txt 屏蔽账户内页、API 路径、追踪参数变体
13. staging 环境在 HTTP header 或 meta 加 noindex/nofollow
14. sitemap.xml 仅包含可索引的规范 URL,lastmod 用真实修改时间

# Core Web Vitals 与 CI
15. LCP < 2.5s:优先图片尺寸、preload、CDN
16. CLS < 0.1:图片/广告/字体显式指定宽高,避免布局偏移
17. INP < 200ms:减少长任务,交互处理拆分到空闲帧
18. Lighthouse CI 在 PR 中门禁性能 / SEO / 可访问性分数

元数据清单(seo-page JS)

按渲染形态与开关生成 Agent 可用的 head 检查清单;与上方流水线一致。

渲染形态
必查项

输出


                

返回技能库 更多技能入口