meta 标签与 SEO
问题
常用的 meta 标签有哪些?前端如何做 SEO 优化?
答案
<meta> 标签位于 HTML <head> 中,用于向浏览器和搜索引擎提供页面元数据。合理使用 meta 标签是前端 SEO 的基础功之一,也直接影响社交分享效果和移动端适配。
一、基础 meta 标签
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- 字符编码:必须放在最前面,告诉浏览器以 UTF-8 解码 -->
<meta charset="UTF-8" />
<!-- 视口设置:移动端适配必备 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 页面描述:搜索结果中显示的摘要文字,建议 70-160 字符 -->
<meta name="description" content="前端面试题库,涵盖 JavaScript、React、Vue 等高频面试题" />
<!-- 关键词:Google 已不再作为排名因素,但部分搜索引擎仍参考 -->
<meta name="keywords" content="前端面试,JavaScript,React,Vue" />
<!-- 作者信息 -->
<meta name="author" content="vincken" />
<!-- 搜索引擎指令 -->
<meta name="robots" content="index, follow" />
<title>前端面试题库</title>
</head>
</html>
charset必须在<head>的前 1024 字节内,否则浏览器可能二次解码导致乱码description是 SEO 最重要的 meta 标签,直接出现在搜索结果的摘要中keywords对 Google 排名已无效,但在百度等搜索引擎中仍有一定参考价值
二、viewport 详解
viewport meta 标签控制页面在移动端的布局视口宽度和缩放行为:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes" />
| 参数 | 含义 | 推荐值 |
|---|---|---|
width | 视口宽度 | device-width(设备宽度) |
initial-scale | 初始缩放比例 | 1.0 |
maximum-scale | 最大缩放比例 | 5.0(无障碍建议不低于 5) |
minimum-scale | 最小缩放比例 | 1.0 |
user-scalable | 是否允许用户缩放 | yes(无障碍规范要求) |
viewport-fit | 适配异形屏(刘海屏) | cover(配合 env(safe-area-inset-*) 使用) |
不要设置 user-scalable=no 或 maximum-scale=1.0。这会阻止视障用户放大页面,违反 WCAG 2.1 可访问性标准,Google Lighthouse 也会扣分。更多可访问性知识参考 语义化与可访问性。
不设置 viewport 会怎样?
浏览器会使用默认布局视口(通常为 980px),页面在手机上会被缩小显示,用户需要手动缩放才能阅读,体验极差。
三、Open Graph 协议
Open Graph 协议 由 Facebook 提出,用于控制页面在社交平台(微信、Twitter、Facebook、Slack 等)分享时的预览卡片效果:
<meta property="og:title" content="前端面试题库 - meta 标签与 SEO" />
<meta property="og:description" content="常用 meta 标签详解,前端 SEO 优化完整指南" />
<meta property="og:image" content="https://example.com/og-image.png" />
<meta property="og:url" content="https://example.com/html/meta-seo" />
<meta property="og:type" content="article" />
<meta property="og:site_name" content="前端面试题库" />
<meta property="og:locale" content="zh_CN" />
| 属性 | 必填 | 说明 |
|---|---|---|
og:title | 是 | 分享标题,建议 35 字符以内 |
og:description | 是 | 分享描述,建议 65 字符以内 |
og:image | 是 | 预览图片,推荐 1200x630px |
og:url | 是 | 页面规范 URL |
og:type | 是 | 内容类型:website/article/product |
og:site_name | 否 | 站点名称 |
og:locale | 否 | 语言地区 |
og:image 的图片尺寸建议 1200x630px(1.91:1 比例),这是大多数平台共用的最佳尺寸。图片大小不要超过 5MB,格式建议 JPG/PNG。
四、Twitter Card
Twitter 有自己的 meta 标签体系,与 Open Graph 类似但有独立字段:
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="前端面试题库 - meta 标签与 SEO" />
<meta name="twitter:description" content="常用 meta 标签详解,前端 SEO 优化完整指南" />
<meta name="twitter:image" content="https://example.com/twitter-image.png" />
<meta name="twitter:site" content="@your_twitter" />
<meta name="twitter:creator" content="@author_twitter" />
twitter:card 值 | 效果 |
|---|---|
summary | 小图 + 标题 + 描述 |
summary_large_image | 大图 + 标题 + 描述(推荐) |
app | 应用下载卡片 |
player | 视频/音频播放器 |
如果同时设置了 Open Graph 和 Twitter Card,Twitter 优先使用自身的 twitter:* 标签;如果未设置 twitter:*,则回退读取 og:* 标签。建议两套都写。
五、结构化数据(JSON-LD)
结构化数据 是一种标准化的机器可读格式,帮助搜索引擎理解页面内容。Google 支持 JSON-LD、Microdata、RDFa 三种格式,JSON-LD 是 Google 推荐的格式。
面包屑导航
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "首页",
"item": "https://example.com"
},
{
"@type": "ListItem",
"position": 2,
"name": "HTML",
"item": "https://example.com/html"
},
{
"@type": "ListItem",
"position": 3,
"name": "meta 标签与 SEO",
"item": "https://example.com/html/meta-seo"
}
]
}
</script>
文章
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "meta 标签与 SEO 完整指南",
"author": {
"@type": "Person",
"name": "vincken"
},
"datePublished": "2026-02-28",
"description": "常用 meta 标签详解,前端 SEO 优化完整指南",
"image": "https://example.com/og-image.png"
}
</script>
FAQ
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "什么是 Open Graph 协议?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Open Graph 是 Facebook 推出的社交分享预览标准,通过 meta 标签控制链接在社交平台的展示效果。"
}
},
{
"@type": "Question",
"name": "SPA 如何做 SEO?",
"acceptedAnswer": {
"@type": "Answer",
"text": "SPA 可以通过 SSR(服务端渲染)、SSG(静态站点生成)或预渲染方案来解决 SEO 问题。"
}
}
]
}
</script>
结构化数据不直接影响排名,但可以让页面在搜索结果中获得富媒体摘要(Rich Snippet),如 FAQ 折叠、面包屑路径、星级评分等,显著提升点击率(CTR)。
六、SEO 核心优化策略
SEO 优化可以从内容、结构、技术三个维度展开:
内容优化
| 优化项 | 说明 | 示例 |
|---|---|---|
<title> | 每页唯一,包含目标关键词,50-60 字符 | <title>meta 标签与 SEO - 前端面试题库</title> |
<meta description> | 准确描述页面内容,70-160 字符 | 包含核心关键词的自然语句 |
| 标题层级 | h1 唯一,h2-h6 层级分明 | 不要跳级(如 h1 直接到 h3) |
图片 alt | 所有有意义的图片必须有 alt 文字 | <img alt="React Fiber 架构图" /> |
| 内部链接 | 合理的站内链接结构 | 相关文章互相引用 |
结构优化
<header>
<nav aria-label="主导航">...</nav>
</header>
<main>
<article>
<h1>页面唯一主标题</h1>
<section>
<h2>章节标题</h2>
<p>内容段落...</p>
</section>
</article>
</main>
<footer>...</footer>
更多语义化标签的最佳实践参考 语义化与可访问性。
技术优化
| 技术手段 | 说明 |
|---|---|
| canonical URL | <link rel="canonical" href="..." /> 告诉搜索引擎规范 URL,避免重复内容 |
| robots.txt | 站点根目录文件,控制爬虫可抓取的路径范围 |
| sitemap.xml | XML 格式的站点地图,列出所有需要索引的页面 |
| HTTPS | Google 明确将 HTTPS 作为排名信号之一 |
| Core Web Vitals | LCP、FID/INP、CLS 等性能指标直接影响搜索排名 |
| 移动端适配 | Google 采用 Mobile-First Indexing,移动端体验优先 |
User-agent: *
Allow: /
Disallow: /admin/
Disallow: /api/
Sitemap: https://example.com/sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
<lastmod>2026-02-28</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://example.com/html/meta-seo</loc>
<lastmod>2026-02-28</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
</urlset>
性能对 SEO 的影响不可忽视,Google 已将 Core Web Vitals 作为排名因素之一。详细的性能优化方案参考 首屏优化。
七、Next.js 中的 SEO
Next.js 提供了声明式的 Metadata API 来管理页面 meta 信息:
import type { Metadata, ResolvingMetadata } from 'next';
interface Props {
params: Promise<{ slug: string }>;
}
// 静态 metadata
export const metadata: Metadata = {
title: 'meta 标签与 SEO',
description: '常用 meta 标签详解,前端 SEO 优化完整指南',
openGraph: {
title: 'meta 标签与 SEO',
description: '常用 meta 标签详解',
images: ['/og-image.png'],
type: 'article',
},
twitter: {
card: 'summary_large_image',
title: 'meta 标签与 SEO',
images: ['/twitter-image.png'],
},
robots: {
index: true,
follow: true,
},
alternates: {
canonical: 'https://example.com/html/meta-seo',
},
};
// 动态 metadata(根据路由参数生成)
export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
const { slug } = await params;
const post = await getPost(slug);
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
images: [post.coverImage],
},
};
}
export default async function Page({ params }: Props) {
const { slug } = await params;
const post = await getPost(slug);
return <article>{post.content}</article>;
}
Next.js 的 Metadata API 会自动处理 <title>、<meta>、<link rel="canonical"> 等标签的渲染。在 App Router 中,子页面的 metadata 会与父级 Layout 的 metadata 自动合并,无需手动管理。更多 Next.js 知识参考 Next.js 核心知识。
八、性能与 SEO
Google 在 2021 年正式将 Core Web Vitals 纳入排名算法,性能差的网站在搜索排名中会受到惩罚:
| 指标 | 含义 | 合格值 | 优化方向 |
|---|---|---|---|
| LCP | 最大内容绘制 | < 2.5s | 优化首屏资源加载、图片优化、CDN |
| INP | 交互响应延迟 | < 200ms | 减少主线程阻塞、代码分割 |
| CLS | 累积布局偏移 | < 0.1 | 图片设置尺寸、字体 font-display |
SPA 应用天然不利于 SEO,因为搜索引擎爬虫拿到的是空的 HTML。解决方案:
- SSR(服务端渲染):每次请求在服务端生成完整 HTML
- SSG(静态站点生成):构建时预渲染所有页面
- ISR(增量静态再生):SSG + 按需更新
详细对比参考 SSR 与 SSG。
九、常见 meta 标签速查表
| meta 标签 | 示例 | 说明 |
|---|---|---|
charset | <meta charset="UTF-8"> | 字符编码,必须在前 1024 字节 |
viewport | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | 移动端视口控制 |
description | <meta name="description" content="..."> | 搜索结果摘要 |
keywords | <meta name="keywords" content="..."> | 关键词(Google 已忽略) |
robots | <meta name="robots" content="index, follow"> | 搜索引擎抓取指令 |
author | <meta name="author" content="vincken"> | 页面作者 |
og:title | <meta property="og:title" content="..."> | 社交分享标题 |
og:description | <meta property="og:description" content="..."> | 社交分享描述 |
og:image | <meta property="og:image" content="..."> | 社交分享图片 |
og:url | <meta property="og:url" content="..."> | 社交分享规范 URL |
og:type | <meta property="og:type" content="article"> | 内容类型 |
twitter:card | <meta name="twitter:card" content="summary_large_image"> | Twitter 卡片类型 |
twitter:image | <meta name="twitter:image" content="..."> | Twitter 分享图片 |
theme-color | <meta name="theme-color" content="#ffffff"> | 移动端浏览器主题色 |
http-equiv refresh | <meta http-equiv="refresh" content="5;url=..."> | 页面重定向(不推荐) |
http-equiv X-UA-Compatible | <meta http-equiv="X-UA-Compatible" content="IE=edge"> | IE 兼容模式 |
format-detection | <meta name="format-detection" content="telephone=no"> | 禁止自动识别电话号码 |
常见面试问题
Q1: viewport meta 标签各参数什么意思?不设置会怎样?
答案:
viewport meta 标签的完整格式:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0, user-scalable=yes, viewport-fit=cover" />
各参数含义:
width=device-width:视口宽度等于设备屏幕宽度(逻辑像素)initial-scale=1.0:初始缩放比例为 1,即不缩放maximum-scale=5.0:最大允许缩放到 5 倍minimum-scale=1.0:最小缩放比例user-scalable=yes:允许用户手动缩放viewport-fit=cover:视口覆盖整个屏幕,用于 iPhone 刘海屏适配
不设置 viewport 的后果:
- 浏览器使用默认布局视口(通常 980px),页面在手机上显示很小
- 用户需要双指缩放才能阅读文字
- 媒体查询中的
max-width断点不会生效 - 响应式布局完全失效
不要设置 user-scalable=no 或 maximum-scale=1,这会导致 Lighthouse 无障碍扣分,也违反 WCAG 2.1 标准。
Q2: Open Graph 协议是什么?有什么作用?
答案:
Open Graph 是由 Facebook(现 Meta)在 2010 年推出的社交分享元数据协议。当用户在微信、QQ、Twitter、Facebook、Slack、Telegram 等平台分享链接时,平台会读取页面中的 og:* meta 标签来生成预览卡片。
核心标签:
<meta property="og:title" content="文章标题" />
<meta property="og:description" content="文章描述" />
<meta property="og:image" content="https://example.com/image.png" />
<meta property="og:url" content="https://example.com/article" />
<meta property="og:type" content="article" />
实际作用:
- 提升点击率:有预览图片的分享链接,点击率比纯文本链接高 2-3 倍
- 品牌展示:控制分享时显示的标题、描述和图片,保持品牌一致性
- 社交传播:美观的卡片更容易被二次转发
最佳实践:
- 图片尺寸 1200x630px(1.91:1),文件 < 5MB
- 标题不超过 35 字符,描述不超过 65 字符
- 使用 Facebook Sharing Debugger 验证效果
Q3: 前端可以做哪些 SEO 优化?
答案:
前端 SEO 优化可以从以下几个层面入手:
1. HTML 结构优化
- 使用语义化标签(
header、nav、main、article、section、footer) - 保持标题层级合理(一个页面只有一个
h1,h2-h6逐级嵌套) - 图片添加
alt属性,<a>标签添加有意义的锚文本
2. meta 标签优化
- 每个页面设置唯一的
<title>和<meta name="description"> - 添加 Open Graph 和 Twitter Card 标签
- 设置
<link rel="canonical">防止重复内容
3. 技术优化
- 使用 SSR/SSG 渲染,避免纯 SPA 的空 HTML 问题
- 提供
robots.txt和sitemap.xml - 启用 HTTPS
- 实现结构化数据(JSON-LD)
4. 性能优化
- 优化 Core Web Vitals(LCP < 2.5s、INP < 200ms、CLS < 0.1)
- 图片懒加载、代码分割、字体优化
- 详见 首屏优化
5. 移动端优化
- 响应式设计,正确设置 viewport
- 适配 Mobile-First Indexing
Q4: robots meta 标签和 robots.txt 有什么区别?
答案:
两者都用于控制搜索引擎爬虫行为,但作用层级不同:
| 对比项 | <meta name="robots"> | robots.txt |
|---|---|---|
| 作用范围 | 单个页面 | 整个站点 |
| 位置 | HTML <head> 中 | 站点根目录 /robots.txt |
| 控制粒度 | 页面级(可精确控制每个页面) | 路径级(按目录/文件匹配) |
| 控制内容 | 是否索引、是否跟踪链接 | 是否允许抓取 |
| 优先级 | 如果 robots.txt 禁止抓取,爬虫看不到 meta robots | 先执行,决定是否抓取页面 |
meta robots 常见值:
<!-- 允许索引,允许跟踪链接(默认行为) -->
<meta name="robots" content="index, follow" />
<!-- 禁止索引,但跟踪链接 -->
<meta name="robots" content="noindex, follow" />
<!-- 禁止索引,禁止跟踪链接 -->
<meta name="robots" content="noindex, nofollow" />
<!-- 禁止缓存快照 -->
<meta name="robots" content="noarchive" />
<!-- 禁止显示摘要 -->
<meta name="robots" content="nosnippet" />
关键区别:如果 robots.txt 禁止了某个路径,爬虫根本不会访问该页面,自然也不会读取其中的 meta robots 标签。所以 robots.txt 是"大门",meta robots 是"房间门"。
Q5: 什么是 canonical URL?什么时候需要设置?
答案:
canonical URL(规范链接)通过 <link rel="canonical"> 告诉搜索引擎:"当多个 URL 指向相同或相似内容时,请以这个 URL 为准进行索引"。
<link rel="canonical" href="https://example.com/html/meta-seo" />
需要设置 canonical 的场景:
-
同一内容多个 URL:
https://example.com/article和https://example.com/article?ref=twitter- URL 带有排序、筛选等查询参数
-
HTTP 和 HTTPS 版本并存:
http://example.com/page和https://example.com/page
-
www 与非 www:
www.example.com/page和example.com/page
-
分页内容:
- 列表页
?page=1、?page=2等
- 列表页
-
移动端和桌面端不同 URL:
m.example.com/page和www.example.com/page
不设置 canonical 的后果:
- 搜索引擎认为是重复内容,分散页面权重(PageRank)
- 可能导致搜索引擎索引了错误的 URL 版本
- 严重时可能被搜索引擎降权
Q6: 结构化数据(JSON-LD)是什么?对 SEO 有什么帮助?
答案:
结构化数据是一种标准化的语义标记,用于帮助搜索引擎更准确地理解页面内容。Google 推荐使用 JSON-LD(JavaScript Object Notation for Linked Data)格式。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [{
"@type": "Question",
"name": "什么是 viewport?",
"acceptedAnswer": {
"@type": "Answer",
"text": "viewport 是浏览器用来显示网页的区域..."
}
}]
}
</script>
对 SEO 的帮助:
| 效果 | 说明 |
|---|---|
| 富媒体摘要 | 搜索结果中显示 FAQ 折叠、星级评分、面包屑等 |
| 提升 CTR | 富摘要比普通结果更醒目,点击率提升 20-30% |
| 语音搜索 | Google Assistant 优先使用结构化数据回答问题 |
| 知识图谱 | 帮助内容进入 Google 知识图谱 |
Google 支持的常见类型:Article、FAQPage、BreadcrumbList、Product、HowTo、Event、Recipe、VideoObject 等。
结构化数据不直接影响排名,但通过富摘要显著提升点击率,间接提升 SEO 效果。可以用 Google Rich Results Test 验证结构化数据是否正确。
Q7: SPA 应用如何做 SEO?
答案:
SPA(单页应用)的 SEO 天然劣势在于:初始 HTML 是空的,内容通过 JavaScript 动态渲染。搜索引擎爬虫虽然能执行 JS,但有延迟和不确定性。
解决方案对比:
| 方案 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| SSR(服务端渲染) | 每次请求在服务端生成完整 HTML | SEO 最好,首屏快 | 服务器成本高,TTFB 增加 |
| SSG(静态生成) | 构建时预渲染所有页面 | 性能最好,可用 CDN | 不适合动态内容 |
| ISR(增量再生) | SSG + 按需更新 | 兼顾性能和实时性 | 需要框架支持(Next.js) |
| 预渲染 | 构建时用 Puppeteer 预渲染 | 不改代码 | 维护成本高,更新不及时 |
| 动态渲染 | 检测到爬虫时返回 SSR 版本 | 对现有项目改动小 | Google 不推荐(可能被认为是 Cloaking) |
推荐方案:
// 静态生成 + 60 秒后按需更新
export const revalidate = 60;
export default async function BlogPage() {
const posts = await getPosts();
return (
<main>
{posts.map((post) => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</main>
);
}
对于大多数内容型网站,SSG + ISR 是最佳选择。详细方案对比参考 SSR 与 SSG。
Q8: Next.js 中如何管理页面 meta 信息?
答案:
Next.js App Router 提供了两种方式管理 meta 信息:
方式一:静态 metadata 对象
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: '关于我们',
description: '了解我们的团队和使命',
openGraph: {
title: '关于我们',
description: '了解我们的团队和使命',
images: [{ url: '/og/about.png', width: 1200, height: 630 }],
},
robots: { index: true, follow: true },
alternates: { canonical: 'https://example.com/about' },
};
export default function AboutPage() {
return <main>关于我们页面内容</main>;
}
方式二:动态 generateMetadata 函数
import type { Metadata } from 'next';
interface Props {
params: Promise<{ slug: string }>;
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params;
const post = await fetch(`https://api.example.com/posts/${slug}`).then(
(res) => res.json()
);
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
images: [post.coverImage],
type: 'article',
publishedTime: post.createdAt,
},
};
}
export default async function BlogPost({ params }: Props) {
const { slug } = await params;
const post = await fetch(`https://api.example.com/posts/${slug}`).then(
(res) => res.json()
);
return <article>{post.content}</article>;
}
Layout 级别的全局 metadata:
import type { Metadata } from 'next';
export const metadata: Metadata = {
metadataBase: new URL('https://example.com'),
title: {
default: '前端面试题库',
template: '%s | 前端面试题库', // 子页面标题自动追加后缀
},
description: '涵盖前端高频面试题的知识库',
openGraph: {
siteName: '前端面试题库',
locale: 'zh_CN',
type: 'website',
},
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="zh-CN">
<body>{children}</body>
</html>
);
}
- Layout 中的 metadata 会被子页面的 metadata 自动合并(浅合并)
- 使用
title.template可以统一管理标题后缀 metadataBase会自动补全所有相对路径的 URL(如 og:image)- 动态 metadata 在服务端执行,可以直接调用数据库或 API