Astro sitemap 配置:hreflang、排除、lastmod

用 @astrojs/sitemap 在 Astro 里生成、校验、提交 sitemap.xml——hreflang 配对、filter 排除、lastmod,以及 Google 实际怎么用它(2026 年 6 月)。

一份正确的 sitemap 是性价比最高的 SEO 改动。错的那种会悄悄把草稿页漏进索引,或者给 Google 喂死链、白白烧掉抓取预算。这篇带你一次把支持双语、会排除草稿的那一版做对。

太长不看

@astrojs/sitemap(截至 2026 年 6 月为 v3.7.x),在 astro.config.mjs 里填好 site:,用 filter 选项排掉草稿,用 i18n 选项输出 hreflang 配对。把 sitemap-index.xml 在 Google Search Console 里提交一次,剩下交给 Google 自己轮询。老的 ping 接口已经死了(2023 年底起返回 404),所以”新鲜度”现在靠一个诚实的 lastmod,不靠 ping。

什么时候需要自定义配置

默认集成应付一般静态博客足够了。出现下面任一情况,就需要下面这套配置:

  • 站点有超过 30 个想被收录的 URL。
  • 有多语言或区域版本,想要正确的 hreflang 标注。
  • 有草稿、预览、登录后才看的页面,绝对不能让搜索引擎收录。
  • 想在内容真正变更时给 Google 一个真实的 lastmod 信号。

如果你做的是私有内部工具或单页落地页,跳过这篇——那种场景下 sitemap 只是噪声,没有收益。

实操步骤

1. 装官方集成

npx astro add sitemap

这会把 @astrojs/sitemap 写进 package.json 并接入 astro.config.mjs。集成需要 Astro 3 及以上;在当前的 Astro 5 上无需改动即可用。

2. 配 astro.config.mjs

site: 是必填项。漏了它,集成会生成一个没有任何 URL 的文件,而且不报错——一个会白浪费一次部署的静默失败。双语内容站可用的形态如下:

import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://yourdomain.com',
  trailingSlash: 'always',
  build: { format: 'directory' },
  integrations: [
    sitemap({
      i18n: {
        defaultLocale: 'en',
        locales: { en: 'en', zh: 'zh-CN' },
      },
      filter: (page) =>
        !page.includes('/drafts/')
        && !page.includes('/preview/')
        && !page.includes('/admin/')
        && !page.endsWith('/404/'),
      serialize: (item) => {
        // 首页 daily、文章 weekly、其余 monthly
        if (item.url.match(/\/articles\/[^/]+\/$/)) item.changefreq = 'weekly';
        else if (item.url === 'https://yourdomain.com/') item.changefreq = 'daily';
        else item.changefreq = 'monthly';
        return item;
      },
    }),
  ],
});

几个关键选项说明:

  • i18n 接收 defaultLocale(必须是 locales 里的某个 key)和 locales(URL 路径段到 hreflang 语言属性的映射,只允许字母和连字符)。集成会把同一内容的多语言页面归组,并自动补上 xhtml:link 备选项。
  • filter(page) 收到的是完整绝对 URL,每页调用一次。返回 true 保留,返回 false 排除。
  • serialize(item) 是你逐页设置 changefreqprioritylastmod 的钩子;返回 undefined 可以彻底删掉某条。

3. 构建并确认文件存在

npm run build
ls -la dist/sitemap*.xml
# dist/sitemap-index.xml
# dist/sitemap-0.xml
head -20 dist/sitemap-0.xml

哪怕站点很小,集成也总会写出一个 sitemap-index.xml 加一个或多个 sitemap-N.xml。要提交的是那个 index。

4. 检查 hreflang 输出

每组 URL 都应该带上 xhtml:link 备选项,这样 Google 才能按地区给出对应语言:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>https://yourdomain.com/en/articles/astro-sitemap-setup/</loc>
    <xhtml:link rel="alternate" hreflang="en"
                href="https://yourdomain.com/en/articles/astro-sitemap-setup/" />
    <xhtml:link rel="alternate" hreflang="zh-CN"
                href="https://yourdomain.com/zh/articles/astro-sitemap-setup/" />
    <changefreq>weekly</changefreq>
  </url>
</urlset>

如果备选项没出来,最常见的原因是 i18n.locales 的 key 跟实际路径段对不上(比如 locales: { zh: 'zh-CN' } 但你的 URL 用的是 /zh-cn/)。

5. 让 robots.txt 指向 sitemap

放一份 public/robots.txt,让爬虫不用手动提交就能发现它:

User-agent: *
Allow: /

Disallow: /drafts/
Disallow: /preview/
Disallow: /admin/

Sitemap: https://yourdomain.com/sitemap-index.xml

6. 部署后核对 URL 数量

curl -s https://yourdomain.com/sitemap-index.xml | grep -c '<loc>'
curl -s https://yourdomain.com/sitemap-0.xml | grep -c '<loc>'
# sitemap-0 的数量应大致等于(en 文章 + zh 文章 + hub 页)

如果数量跟你的页面数差太远,要么是 filter 排得太狠,要么是 site: 填错了。

7. 在 Search Console 提交一次

在 Google Search Console 的 Sitemaps 里提交 sitemap-index.xml。除非 URL 本身变了,否则不用再提交——Google 按自己的节奏轮询。也不再有 ping 接口可调:Google 的 https://www.google.com/ping?sitemap=... 在 2023 年 6 月被弃用,2023 年底起返回 404,原因是绝大多数未经认证的提交都是垃圾信息。

如果你想在 Bing 和 Yandex 上加快发现,用 IndexNow 替代任何 ping URL——那才是内容变更后催爬虫的现代受支持方式。

sitemap 的上限

上限数值说明
单文件 URL 数50,000sitemaps.org 协议的硬上限
文件体积(未压缩)50 MB自 2016 年从 10 MB 提升后未变;gzip 只省传输,未压缩仍不能超 50 MB
单 index 内 sitemap 数50,000理论总量上限 25 亿 URL

@astrojs/sitemap 在超过约 45,000 条时会自动拆分,所以你基本不会手动碰到这些上限。

容易踩的坑

  • 忘配 site:——Astro 不报错,但生成的 sitemap 是空的、没用的。
  • 把会 404 或重定向的页面列进去——每条错 URL 都在浪费抓取预算。
  • 把草稿或测试 URL 写进去,被收录后才发现。
  • 每次构建都把所有页面 lastmod 设成构建日期——Google 会把从不对应真实变更的 lastmod 当噪声,时间一长就不再信任它。
  • 多语言每种语言各提一份 sitemap,其实带 hreflang 的单个 sitemap index 更干净,也避免互相冲突的信号。

FAQ

  • Astro 会自动生成 sitemap 吗: 不会。只有 @astrojs/sitemap 集成才会生成;原生 Astro 什么都不出。用 npx astro add sitemap 装上。
  • 一份 sitemap 最大多大: 单文件 50,000 个 URL 或 50 MB(未压缩)。超过约 45,000 个 URL 时,Astro 集成会拆成多个文件,挂在 sitemap-index.xml 下面。
  • sitemap 变了要不要 ping Google: 不用。ping 接口 2023 年 6 月被弃用,现在返回 404。保持 lastmod 诚实,让 Google 自己重抓;想让 Bing/Yandex 更快收到就用 IndexNow。
  • Google 接受什么样的 lastmod 日期格式: 合法的 W3C Datetime / ISO 8601 值,比如 2026-06-042026-06-04T12:00:00+00:00。而且它必须对应真实的内容变更,否则 Google 会打折扣。
  • 要不要逐页设 prioritychangefreq: 这俩是价值很低的提示,Google 在排名上基本忽略。lastmod 才是仍会影响抓取调度的那个信号,精力花这里。
  • 想让某些页面不在 sitemap 里怎么办: 用 filter 排除,同时在页面上加 noindex 元标签,双保险——sitemap 只是发现提示,不是收录规则。

相关阅读

标签: #独立开发 #Astro #SEO #Technical SEO #收录