SEO:meta 与 sitemap
本教程共 56 篇 · 第 47 篇 · 更新于 2026-08-07 · 约 12 分钟阅读
本节目标:搞懂 Astro 不会自动帮你写 SEO 标签这个事实,学会用一个 Head 组件统一管理 meta 信息,并配置 @astrojs/sitemap 自动生成站点地图,让搜索引擎更好地收录你的网站。
很多刚接触 Astro 的朋友会纳闷:「我在哪填网站标题和描述?是不是在 astro.config.mjs 里有个 SEO 字段?」答案是:没有这种字段。这一章先把这个最容易踩坑的点讲清楚,再给你一套标准做法。
先纠正一个常见误解
Astro 的配置文档(astro.config.mjs)只负责「怎么构建项目、怎么渲染 HTML」这类工程信息。它里面没有给搜索引擎或社交平台用的 SEO 字段,也没有「站点标题」「站点描述」这种配置项。
有人从别的框架过来,习惯在配置里塞一堆 meta。在 Astro 里这样做是错的。正确的做法是:像写普通 HTML 页面一样,用标准的 <link> 和 <meta> 标签,把 SEO 信息写进每个页面的 <head> 里。
那页面那么多,难道每个文件都手写一遍?当然不用。Astro 的答案是:抽一个 Head 组件。
用 Head 组件统一管理
<head> 里的内容(标题、描述、图标、社交分享卡等)每个页面都差不多,最干净的做法是做成一个 Head.astro 组件,放进共享布局(layout),由布局应用到所有页面。
Head 组件就是个普通 Astro 组件,它可以接收 props(比如当前页的标题)。下面是一个典型写法:
---
// src/components/Head.astro
const { title = "我的 Astro 网站", ...props } = Astro.props;
---
<title>{title}</title>
<meta name="description" content="欢迎来到我的新 Astro 站点!">
<link rel="sitemap" href="/sitemap-index.xml">
<!-- Open Graph 社交分享标签 -->
<meta property="og:title" content="我的新 Astro 网站" />
<meta property="og:type" content="website" />
<meta property="og:url" content="http://www.example.com/" />
<meta property="og:description" content="欢迎来到我的新 Astro 站点!" />
<meta property="og:image" content="https://www.example.com/_astro/seo-banner.webp">
然后在布局里引入它,放到 <head> 中:
---
// src/components/MainLayout.astro
import Head from "./Head.astro";
const { ...props } = Astro.props;
---
<html>
<head>
<meta charset="utf-8">
<Head />
</head>
<body>
<slot />
</body>
</html>
每个页面只要在布局上传不同的 title 等 props,就能拿到专属的 meta,而不用重复写一堆标签。这就是零基础读者最该建立的心智模型:SEO 标签 = 普通 HTML 标签 + 一个可复用组件。
关键 meta 标签清单
下面这些标签是 SEO 和社交分享的基础,逐项认识一下:
<title>:页面标题,SEO 里权重最高,搜索结果第一行显示的就是它。<meta name="description">:页面描述,常作为搜索结果摘要出现。<link rel="canonical">:规范 URL,告诉搜索引擎「这个页面的正式地址」,避免重复内容被分散权重。可以在布局里用new URL(Astro.url.pathname, Astro.site)动态生成。- Open Graph(
og:title/og:type/og:url/og:description/og:image):社交平台(微信、Facebook 等)分享链接时显示的卡片信息。没它,分享出去就是个光秃秃的链接。 - Twitter Card 标签(
twitter:card等):Twitter/X 平台的分享卡片,规则类似 Open Graph。 <link rel="icon">:网站小图标(favicon)。
这些标签直接写进 Head 组件即可,不需要任何特殊集成。Astro 在构建时会原样保留它们。
用 Astro.url 自动生成 canonical
规范链接(canonical)最怕写死——一旦你改了路由或部署到子路径,写死的地址就错了。更稳的做法是在 Head 组件里用 Astro.url 和 Astro.site 动态拼:
---
// src/components/Head.astro
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
---
<link rel="canonical" href={canonicalURL} />
Astro.url.pathname 是当前页面的路径(比如 /blog/hello/),Astro.site 是你在配置里填的域名。两者一拼,就得到绝对地址,无论部署到根域名还是子路径都不会出错。
favicon 与移动端视口
两个常被忽略但基础的标签也建议放进 Head 组件:
- favicon(站点小图标):
<link rel="icon" href="/favicon.svg" />。把图标文件放public/目录,构建后会原样复制到根路径。 - 移动端视口:
<meta name="viewport" content="width=device-width, initial-scale=1.0" />。没有它,手机上页面可能按桌面宽度缩放,体验很差。一般布局里已经由模板带了,确认一下即可。
这些都属于「普通 HTML 标签」,Astro 不特殊对待,你按标准写法放进去就行。
验证你的 SEO 是否生效
写完标签,怎么确认没白写?两个简单办法:
- 本地
astro build后,打开dist/里对应的.html,搜索<title>、<meta name="description">、<link rel="canonical">,看内容是否如预期。 - 部署后用浏览器的「查看网页源代码」(不是审查元素),确认
<head>里确实有这些标签。搜索引擎读的是源代码,不是运行时 DOM。
如果某个页面的标题没变,通常是布局没把 title prop 传下去,或者 Head 组件里把 <title> 写死了。回到组件检查 props 传递即可。
站点地图 Sitemap 集成
光有 meta 还不够。网站页面多了,搜索引擎需要一张「地图」来高效爬取,这就是 sitemap(站点地图)。Astro 提供了官方集成 @astrojs/sitemap 自动生成它。
安装很简单,用官方命令一键搞定:
npx astro add sitemap
这条命令会装好包,并自动把集成写进 astro.config.mjs。手动装也行:
npm install @astrojs/sitemap
然后配置里要加一个关键的 site 字段——这是 sitemap 生成正确绝对 URL 的前提:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
site: 'https://www.example.com',
integrations: [sitemap()],
});
注意 site 必须以 http:// 或 https:// 开头,填你正式部署的域名。构建(build)之后,输出目录里会出现 sitemap-index.xml 和 sitemap-0.xml。大站点还可能生成 sitemap-1.xml 等分片。
让爬虫更容易发现 sitemap
生成了 sitemap 还不够,最好主动告诉爬虫它的位置,有两处可加:
在页面 <head> 里放一个链接(放进 Head 组件):
<link rel="sitemap" href="/sitemap-index.xml" />
在 public/robots.txt 里声明(或动态生成):
User-agent: *
Allow: /
Sitemap: https://www.example.com/sitemap-index.xml
如果你不想维护静态文件,也可以在 src/pages/robots.txt.ts 里用端点动态拼出 robots.txt,复用配置里的 site 值,避免域名写死两遍。
排除不想被收录的页面
有些页面(比如后台、VIP 区域)不想进 sitemap。有两种办法。
第一,在该页 frontmatter 里设 sitemap: false:
---
// src/pages/secret.astro
export const sitemap = false;
---
第二,在 sitemap 配置里用 filter() 函数批量过滤:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
site: 'https://example.com',
integrations: [
sitemap({
filter: (page) =>
page !== 'https://example.com/secret-vip-lounge-1/' &&
page !== 'https://example.com/secret-vip-lounge-2/',
}),
],
});
filter 会对每个页面调用一次,返回 true 收录、返回 false 排除。页面参数是带域名的完整 URL。
注意一点:@astrojs/sitemap 只能为静态生成的路由生成条目。SSR 模式下的动态路由它无法爬取,所以 sitemap 主要针对预渲染页面。
结构化数据 JSON-LD 思路
想让搜索结果显示更丰富的样式(如评分、面包屑),可以用结构化数据。Astro 没有内置生成器,需要你手写一段 JSON-LD(一种通用的结构化数据格式)注入页面。
做法是在布局 frontmatter 里定义 schema 对象,再用 set:html 指令把它塞进 <script type="application/ld+json">:
---
const schema = {
"@context": "https://schema.org",
"@type": "WebSite",
"name": "我的 Astro 网站",
"url": Astro.site,
};
---
<script type="application/ld+json" set:html={JSON.stringify(schema)} />
这段内容对访客不可见,但搜索引擎能读懂,从而更好地理解你的站点。具体 schema 类型按业务去 schema.org 查即可,这里只讲接入方式。
小结:SEO 在 Astro 里是「手工但可控」
Astro 不替你生成 meta,初看麻烦,实则把控制权完全交给你:该写什么标签、怎么复用、怎么排除,都清清楚楚。记住这条主线——Head 组件管标签,sitemap 集成管地图,JSON-LD 管结构化数据,三者配合就能满足绝大多数内容的 SEO 需求。