seo-meta-tags

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SEO Meta Tags

SEO元标签

Boilerplate and component library for production-ready metadata across three framework targets.
适用于三个框架目标的生产就绪型元数据模板和组件库。

Decision Tree

决策树

Determine the correct framework path first:
  1. Static HTML site or any-backend project — Read references/html.md
  2. Next.js 13+ App Router — Read references/nextjs.md
  3. Vite + React — Read references/vite.md, React section
  4. Vite + Vue 3 — Read references/vite.md, Vue section
  5. Multiple frameworks at once — Read all relevant reference files
Then determine action type:
  • Creating metadata from scratch? — Read matching reference → copy boilerplate → replace placeholders.
  • Updating existing metadata? — Load file → keep structure → change requested values → verify parity across tag families.
  • Auditing / reviewing metadata? — Run through Quality Gate below → report issues.
  • Migrating between frameworks? — Read source reference → read target reference → map fields.
首先确定正确的框架路径:
  1. 静态HTML站点或任意后端项目 — 阅读references/html.md
  2. Next.js 13+ App Router — 阅读references/nextjs.md
  3. Vite + React — 阅读references/vite.md中的React章节
  4. Vite + Vue 3 — 阅读references/vite.md中的Vue章节
  5. 同时使用多个框架 — 阅读所有相关参考文件
然后确定操作类型:
  • 从零开始创建元数据? — 阅读对应参考文档 → 复制模板 → 替换占位符。
  • 更新现有元数据? — 加载文件 → 保留结构 → 修改指定值 → 确保各元数据家族内容一致。
  • 审核/检查元数据? — 执行下方的质量检查项 → 报告问题。
  • 在框架间迁移? — 阅读源框架参考文档 → 阅读目标框架参考文档 → 映射字段。

Framework Selection

框架选择

FrameworkWhen to useReference
HTMLStatic sites, any backend, SSGsreferences/html.md
Next.jsNext.js 13+ App Router projectsreferences/nextjs.md
ViteVite + React or Vite + Vue appsreferences/vite.md
Read only the reference file that matches the user's target framework.
框架使用场景参考文档
HTML静态站点、任意后端、静态站点生成器references/html.md
Next.jsNext.js 13+ App Router 项目references/nextjs.md
ViteVite + React 或 Vite + Vue 应用references/vite.md
仅阅读与用户目标框架匹配的参考文件。

Metadata Families

元数据家族

Every framework target must keep parity across these families. When modifying one family, verify the others remain consistent.
每个框架目标都必须保持这些元数据家族之间的一致性。修改其中一个家族时,需验证其他家族内容是否一致。

1. Essential / Primary

1. 核心/基础元数据

TagConstraint
<title>
/
title
Under 60 characters
description
150-160 characters
keywords
5-10 terms max, comma-separated
author
Full name
robots
index, follow
by default; include
max-image-preview:large
,
max-snippet:-1
,
max-video-preview:-1
canonical
Absolute URL, must match deployment URL
viewport
width=device-width, initial-scale=1.0
标签约束条件
<title>
/
title
长度不超过60个字符
description
长度为150-160个字符
keywords
最多5-10个术语,用逗号分隔
author
完整姓名
robots
默认值为
index, follow
;需包含
max-image-preview:large
,
max-snippet:-1
,
max-video-preview:-1
canonical
绝对URL,必须与部署URL一致
viewport
width=device-width, initial-scale=1.0

2. Open Graph (
og:*
)

2. Open Graph(
og:*

PropertyNotes
og:type
website
for home/landing;
article
for blog posts;
product
for e-commerce
og:url
Absolute URL
og:title
Can differ from
<title>
for social context
og:description
Can differ from meta description
og:image
Absolute URL, 1200x630px, JPG or PNG, under 1 MB
og:image:width
/
og:image:height
1200
/
630
og:image:alt
Required when image is present
og:site_name
Brand name
og:locale
e.g.
en_US
For
article
type also include:
article:published_time
,
article:modified_time
,
article:author
,
article:tag
.
属性说明
og:type
首页/落地页用
website
;博客文章用
article
;电商页面用
product
og:url
绝对URL
og:title
可与
<title>
不同,适配社交场景
og:description
可与meta description不同
og:image
绝对URL,尺寸1200x630px,格式为JPG或PNG,大小不超过1 MB
og:image:width
/
og:image:height
1200
/
630
og:image:alt
存在图片时必须设置
og:site_name
品牌名称
og:locale
示例:
en_US
对于
article
类型,还需包含:
article:published_time
,
article:modified_time
,
article:author
,
article:tag

3. Twitter Cards (
twitter:*
)

3. Twitter Cards(
twitter:*

PropertyNotes
twitter:card
summary_large_image
(default) or
summary
twitter:site
Organization handle with
@
prefix
twitter:creator
Author handle with
@
prefix
twitter:title
Under 70 characters
twitter:description
Under 200 characters
twitter:image
Same spec as OG image
twitter:image:alt
Required when image is present
属性说明
twitter:card
默认值为
summary_large_image
,或使用
summary
twitter:site
@
前缀的机构账号
twitter:creator
@
前缀的作者账号
twitter:title
长度不超过70个字符
twitter:description
长度不超过200个字符
twitter:image
与Open Graph图片规格一致
twitter:image:alt
存在图片时必须设置

4. Theme Color

4. 主题色

Provide three values:
  • Default:
    <meta name="theme-color" content="...">
    or single value
  • Light:
    media="(prefers-color-scheme: light)"
  • Dark:
    media="(prefers-color-scheme: dark)"
Next.js uses the
themeColor
array in the Metadata object.
提供三个值:
  • 默认值:
    <meta name="theme-color" content="...">
    或单个值
  • 浅色模式:
    media="(prefers-color-scheme: light)"
  • 深色模式:
    media="(prefers-color-scheme: dark)"
Next.js 中需在Metadata对象的
themeColor
数组中配置。

5. Icons and Manifest

5. 图标和清单

AssetSizeFormat
favicon.ico
32x32 or multi-sizeICO
icon-16x16.png
16x16PNG
icon-32x32.png
32x32PNG
apple-touch-icon.png
180x180PNG
site.webmanifest
n/aJSON
资源尺寸格式
favicon.ico
32x32 或多尺寸ICO
icon-16x16.png
16x16PNG
icon-32x32.png
32x32PNG
apple-touch-icon.png
180x180PNG
site.webmanifest
无要求JSON
可通过favicon.ioRealFaviconGenerator生成。

6. Structured Data (JSON-LD)

6. 结构化数据(JSON-LD)

Emit a
<script type="application/ld+json">
block (HTML/Vite) or use a separate Script component in Next.js. Required keys:
json
{
	"@context": "https://schema.org",
	"@type": "WebSite",
	"name": "",
	"description": "",
	"url": "",
	"image": { "@type": "ImageObject", "url": "", "width": 1200, "height": 630 },
	"author": { "@type": "Person", "name": "" },
	"publisher": {
		"@type": "Organization",
		"name": "",
		"logo": { "@type": "ImageObject", "url": "" }
	}
}
Common
@type
values:
WebSite
,
Article
,
Organization
,
Product
,
FAQPage
,
BreadcrumbList
.
在HTML/Vite中添加
<script type="application/ld+json">
代码块,在Next.js中使用独立的Script组件。必填字段:
json
{
	"@context": "https://schema.org",
	"@type": "WebSite",
	"name": "",
	"description": "",
	"url": "",
	"image": { "@type": "ImageObject", "url": "", "width": 1200, "height": 630 },
	"author": { "@type": "Person", "name": "" },
	"publisher": {
		"@type": "Organization",
		"name": "",
		"logo": { "@type": "ImageObject", "url": "" }
	}
}
常见的
@type
值:
WebSite
,
Article
,
Organization
,
Product
,
FAQPage
,
BreadcrumbList

7. Internationalization (hreflang)

7. 国际化(hreflang)

html
<link rel="alternate" hreflang="en" href="https://example.com/en/" />
<link rel="alternate" hreflang="es" href="https://example.com/es/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/" />
Next.js equivalent:
alternates.languages
in the Metadata object.
html
<link rel="alternate" hreflang="en" href="https://example.com/en/" />
<link rel="alternate" hreflang="es" href="https://example.com/es/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/" />
Next.js 中的等效配置:在Metadata对象的
alternates.languages
中设置。

8. Performance Hints

8. 性能提示

Include when external resources are used:
html
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="dns-prefetch" href="https://www.google-analytics.com" />
使用外部资源时需添加:
html
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="dns-prefetch" href="https://www.google-analytics.com" />

Placeholder Tokens

占位符标记

All boilerplate files use
{{PLACEHOLDER_NAME}}
tokens. Common tokens:
TokenPurpose
{{PAGE_TITLE}}
Page
<title>
{{PAGE_DESCRIPTION}}
Meta description
{{PAGE_URL}}
Page URL (absolute)
{{CANONICAL_URL}}
Canonical URL
{{KEYWORDS}}
Comma-separated keywords
{{AUTHOR_NAME}}
Content author
{{SITE_NAME}}
Brand / site name
{{THEME_COLOR}}
/
{{THEME_COLOR_LIGHT}}
/
{{THEME_COLOR_DARK}}
Hex color codes
{{OG_TITLE}}
/
{{OG_DESCRIPTION}}
/
{{OG_IMAGE_URL}}
/
{{OG_IMAGE_ALT}}
Open Graph
{{TWITTER_TITLE}}
/
{{TWITTER_DESCRIPTION}}
/
{{TWITTER_IMAGE_URL}}
/
{{TWITTER_IMAGE_ALT}}
Twitter
{{TWITTER_HANDLE}}
/
{{TWITTER_CREATOR_HANDLE}}
Twitter handles
{{SCHEMA_TYPE}}
/
{{SCHEMA_IMAGE_URL}}
JSON-LD
{{PUBLISHER_NAME}}
/
{{PUBLISHER_LOGO_URL}}
Publisher org
{{FAVICON_32x32_URL}}
/
{{FAVICON_16x16_URL}}
/
{{APPLE_TOUCH_ICON_URL}}
Icons
{{AUTHOR_URL}}
Author website URL (Next.js)
{{CREATOR_NAME}}
Content creator name (Next.js)
{{CATEGORY}}
Site category (Next.js)
{{GOOGLE_VERIFICATION_CODE}}
/
{{YANDEX_VERIFICATION_CODE}}
/
{{FACEBOOK_VERIFICATION_CODE}}
Search engine verification codes (Next.js)
{{EN_URL}}
/
{{ES_URL}}
Language-specific alternate URLs (Next.js)
{{ALTERNATE_EN_URL}}
/
{{ALTERNATE_DEFAULT_URL}}
hreflang alternate URLs (HTML/Vite)
When implementing for a user, replace every
{{...}}
token. Never leave placeholders in production output.
所有模板文件均使用
{{PLACEHOLDER_NAME}}
占位符标记。常见标记:
标记用途
{{PAGE_TITLE}}
页面
<title>
{{PAGE_DESCRIPTION}}
Meta描述
{{PAGE_URL}}
页面URL(绝对路径)
{{CANONICAL_URL}}
规范URL
{{KEYWORDS}}
逗号分隔的关键词
{{AUTHOR_NAME}}
内容作者
{{SITE_NAME}}
品牌/站点名称
{{THEME_COLOR}}
/
{{THEME_COLOR_LIGHT}}
/
{{THEME_COLOR_DARK}}
十六进制颜色代码
{{OG_TITLE}}
/
{{OG_DESCRIPTION}}
/
{{OG_IMAGE_URL}}
/
{{OG_IMAGE_ALT}}
Open Graph相关参数
{{TWITTER_TITLE}}
/
{{TWITTER_DESCRIPTION}}
/
{{TWITTER_IMAGE_URL}}
/
{{TWITTER_IMAGE_ALT}}
Twitter相关参数
{{TWITTER_HANDLE}}
/
{{TWITTER_CREATOR_HANDLE}}
Twitter账号
{{SCHEMA_TYPE}}
/
{{SCHEMA_IMAGE_URL}}
JSON-LD相关参数
{{PUBLISHER_NAME}}
/
{{PUBLISHER_LOGO_URL}}
发布机构信息
{{FAVICON_32x32_URL}}
/
{{FAVICON_16x16_URL}}
/
{{APPLE_TOUCH_ICON_URL}}
图标地址
{{AUTHOR_URL}}
作者网站URL(Next.js)
{{CREATOR_NAME}}
内容创作者名称(Next.js)
{{CATEGORY}}
站点分类(Next.js)
{{GOOGLE_VERIFICATION_CODE}}
/
{{YANDEX_VERIFICATION_CODE}}
/
{{FACEBOOK_VERIFICATION_CODE}}
搜索引擎验证代码(Next.js)
{{EN_URL}}
/
{{ES_URL}}
多语言替代URL(Next.js)
{{ALTERNATE_EN_URL}}
/
{{ALTERNATE_DEFAULT_URL}}
hreflang替代URL(HTML/Vite)
为用户实现时,需替换所有
{{...}}
标记。生产环境中绝不能保留占位符。

Quality Gate

质量检查项

Run these checks before considering any metadata task complete:
  1. No placeholders — grep for
    {{
    in all modified files; count must be zero.
  2. Absolute URLs — canonical, OG url, OG image, Twitter image, JSON-LD url/image must start with
    https://
    .
  3. Image alt text — every
    og:image
    /
    twitter:image
    must have a corresponding alt field.
  4. No duplicate tags — no two conflicting
    <title>
    ,
    description
    , or
    canonical
    tags in the same scope.
  5. Title length — verify under 60 characters.
  6. Description length — verify 150-160 characters.
  7. JSON-LD validity — valid JSON with required
    @context
    and
    @type
    keys.
  8. OG/Twitter parity — if OG title is set, Twitter title should also be set (and vice versa).
  9. Canonical consistency — canonical URL matches the actual page URL or intended redirect target.
  10. Theme color — includes both light and dark media variants.
  11. hreflang — includes
    x-default
    when language alternates exist.
  12. Robots — allows indexing unless user explicitly requests noindex.
在完成任何元数据任务前,执行以下检查:
  1. 无占位符 — 在所有修改的文件中搜索
    {{
    ,结果数量必须为零。
  2. 绝对URL — 规范链接、Open Graph URL、Open Graph图片、Twitter图片、JSON-LD URL/图片必须以
    https://
    开头。
  3. 图片替代文本 — 每个
    og:image
    /
    twitter:image
    必须对应一个替代文本字段。
  4. 无重复标签 — 同一作用域内(布局 vs 页面)不能存在冲突的
    <title>
    description
    canonical
    标签。
  5. 标题长度 — 验证长度不超过60个字符。
  6. 描述长度 — 验证长度为150-160个字符。
  7. JSON-LD有效性 — 包含必填的
    @context
    @type
    字段的有效JSON。
  8. Open Graph/Twitter一致性 — 若设置了Open Graph标题,也需设置Twitter标题(反之亦然)。
  9. 规范链接一致性 — 规范URL与实际页面URL或预期重定向目标一致。
  10. 主题色 — 包含浅色和深色模式的媒体查询变体。
  11. hreflang — 存在多语言替代链接时需包含
    x-default
  12. Robots设置 — 允许索引,除非用户明确要求禁止索引。

Image Specifications

图片规格

Use caseDimensionsRatioFormatMax size
OG / Twitter1200x6301.91:1JPG or PNG1 MB
Favicon 3232x321:1PNGn/a
Favicon 1616x161:1PNGn/a
Apple Touch180x1801:1PNGn/a
使用场景尺寸比例格式最大尺寸
Open Graph / Twitter1200x6301.91:1JPG或PNG1 MB
32x32图标32x321:1PNG无要求
16x16图标16x161:1PNG无要求
Apple触摸图标180x1801:1PNG无要求

Testing Tools

测试工具

Common Mistakes

常见错误

MistakeImpactFix
Relative URLs in
og:image
or
twitter:image
Social platforms can't fetch the imageAlways use absolute URLs starting with
https://
Missing
<HelmetProvider>
in Vite React
All
<SEO>
tags silently fail to render
Wrap app root in
<HelmetProvider>
in
main.tsx
Missing
createHead()
in Vite Vue
useHead()
throws at runtime
Call
app.use(createHead())
in
main.ts
Committing verification codes to public reposExposes site ownership tokensUse environment variables for
verification
values
Duplicate
<title>
or
description
tags
Crawlers pick an unpredictable oneUse only one source of truth per scope (layout vs. page)
og:image
set without
og:image:alt
Accessibility failure, some validators warnAlways pair image with alt text
Using
generateMetadata
for static pages
Unnecessary async overhead on every requestUse static
export const metadata
when values are known at build time
Leaving
{{...}}
placeholder tokens
Broken display on social platforms, poor SEOGrep for
{{
before shipping
JSON-LD with trailing commas or commentsInvalid JSON, structured data ignoredValidate JSON before finishing
twitter:card
set to
summary
when image is 1200x630
Image gets cropped to tiny squareUse
summary_large_image
for landscape images
错误影响修复方案
og:image
twitter:image
中使用相对URL
社交平台无法获取图片始终使用以
https://
开头的绝对URL
Vite React中缺少
<HelmetProvider>
所有
<SEO>
标签无法渲染
main.tsx
中用
<HelmetProvider>
包裹应用根组件
Vite Vue中缺少
createHead()
useHead()
运行时抛出异常
main.ts
中调用
app.use(createHead())
将验证代码提交到公共仓库暴露站点所有权令牌使用环境变量存储
verification
重复的
<title>
description
标签
爬虫会随机选择其中一个每个作用域(布局 vs 页面)仅保留一个可信数据源
设置
og:image
但未设置
og:image:alt
可访问性不达标,部分验证工具会发出警告始终为图片添加替代文本
静态页面使用
generateMetadata
每次请求都会产生不必要的异步开销若构建时已知值,使用静态
export const metadata
遗留
{{...}}
占位符标记
社交平台显示异常,SEO效果差上线前搜索
{{
检查是否有遗留占位符
JSON-LD中存在尾随逗号或注释JSON无效,结构化数据被忽略完成前验证JSON格式
图片尺寸为1200x630时
twitter:card
设为
summary
图片被裁剪为小方形横向图片使用
summary_large_image

Migration Paths

迁移路径

FromToNotes
react-helmet
Vite React (
SEO.tsx
)
Replace with
react-helmet-async
; wrap root in
<HelmetProvider>
vue-meta
Vite Vue (
SEO.vue
)
Replace
metaInfo
with
@unhead/vue
useHead()
composable
next-seo
Next.js (
metadata.ts
)
Remove
<NextSeo>
; use exported
metadata
or
generateMetadata
Pages Router
<Head>
App RouterReplace
import Head
with
export const metadata
源框架/库目标框架/库说明
react-helmet
Vite React(
SEO.tsx
替换为
react-helmet-async
;用
<HelmetProvider>
包裹根组件
vue-meta
Vite Vue(
SEO.vue
@unhead/vue
useHead()
组合式API替换
metaInfo
next-seo
Next.js(
metadata.ts
移除
<NextSeo>
;使用导出的
metadata
generateMetadata
Pages Router
<Head>
App Router替换
import Head
export const metadata