Skip to content

sitemap.xml 怎麼產生?靜態站與前端框架的自動化做法

sitemap.xml:網站地圖的產生與提交

sitemap.xml 是一份 網址清單,主動告知搜尋引擎「這個網站有哪些頁面」。它負責 索引流程 的第一關,讓網址被發現。

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-09-07</lastmod>
  </url>
  <url>
    <loc>https://example.com/about</loc>
    <lastmod>2026-08-15</lastmod>
  </url>
</urlset>

欄位與它們的實際作用

欄位必要性實際作用
<loc>必填網址,必須是絕對網址且經過網址編碼
<lastmod>選填最後修改時間,誠實填寫時有參考價值
<changefreq>選填已被忽略
<priority>選填已被忽略

changefreq 與 priority 不必寫

Google 明確表示不使用這兩個欄位。原因和 meta keywords 一樣:完全由網站自行填寫、無法驗證,結果是所有人都把 <priority>1.0

寫了不會有壞處,但也沒有效果。省下來的力氣放在 <lastmod> 的正確性上更值得。

lastmod 要誠實

<lastmod> 是唯一還有參考價值的選填欄位,但前提是 填得誠實

做法後果
內容真的改了才更新時間搜尋引擎會參考它決定重新抓取的優先順序
每次部署都填成當天一段時間後這個欄位會被整體忽略

用 Git 的最後提交時間

最可靠的來源是版本控制。用檔案的最後提交時間當 <lastmod>,就不會因為部署而全部變成同一天:

bash
git log -1 --format=%cI -- docs/src/seo/indexing-sitemap.md

時間格式用 W3C Datetime,2026-09-072026-09-07T14:30:00+08:00 都可以。

數量上限與拆檔

限制
單檔網址數5 萬筆
單檔大小50MB(未壓縮)

超過就要拆成多個檔案,再用一個 索引檔 把它們列出來:

xml
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://example.com/sitemap-posts.xml</loc>
    <lastmod>2026-09-07</lastmod>
  </sitemap>
  <sitemap>
    <loc>https://example.com/sitemap-products.xml</loc>
    <lastmod>2026-09-06</lastmod>
  </sitemap>
</sitemapindex>

索引檔本身同樣受 5 萬筆限制,所以理論上可容納 25 億個網址。

拆檔的另一個好處

即使沒有超過上限,按內容類型拆檔(文章、商品、分類頁)也很有用,Search Console 的涵蓋範圍報告可以 按 sitemap 分別檢視,一眼看出是哪一類內容收錄有問題。

只放該收錄的網址

這些網址不該出現在 sitemap 裡

不該放為什麼
標了 noindex 的頁面一邊說「請收錄」一邊說「別收錄」,訊號矛盾
robots.txt 封鎖的路徑爬蟲根本下載不了
回傳 轉址或錯誤 的網址浪費爬取預算
非正規版本的網址應該只放 canonical 指向的那一個
分頁的第 2 頁以後通常沒有獨立收錄的價值

sitemap 應該只包含您希望被收錄、而且回傳 200 的正規網址。 這是 Search Console 涵蓋範圍報告出現大量錯誤最常見的原因。

怎麼讓搜尋引擎知道

兩種方式,都做最保險:

1. 在 robots.txt 宣告

這是被動的,但爬蟲每次來都會看到。

User-agent: *
Allow: /

Sitemap: https://example.com/sitemap.xml

2. 在 Search Console 提交

Search Console 的「Sitemap」頁面可以主動提交,並看到 它實際讀到幾筆、有幾筆有問題,這個回饋是 robots.txt 宣告給不了的。

自動產生

不要手工維護

手工維護的 sitemap 一定會過期。新增頁面忘了加、刪除頁面忘了移除,最後變成一份充滿錯誤的清單。

多數框架有內建支援或現成外掛,通常只要給定網域,建置時就會掃過所有頁面產出:

js
// 框架設定檔,欄位名稱各家略有不同
export default {
  sitemap: {
    hostname: domain,
  },
};

網域要來自環境變數,這樣測試機不會產出指向正式網域的 sitemap:

js
const domain = (process.env.SITE_HOST || 'http://localhost:5173').replace(/\/$/, '');

自己寫的話,骨架大致是這樣:

js
import { writeFileSync } from 'node:fs';

const pages = await collectPages(); // 掃目錄或讀路由表

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

writeFileSync('dist/sitemap.xml', xml, 'utf-8');

動態網址怎麼處理

電商的商品頁、部落格的文章頁通常來自資料庫,不在檔案系統裡。兩種做法:

做法適合
建置時查資料庫,產出靜態 sitemap內容更新不頻繁
由伺服器動態產生內容持續新增,例如:每日上架商品

動態產生時記得加上快取,不要每次請求都去撈全表:

js
// 每小時重新產生一次就夠
app.get('/sitemap.xml', cache('1 hour'), async (req, res) => {
  const urls = await db.getPublishedUrls();
  res.type('application/xml').send(buildSitemap(urls));
});

其他類型的 sitemap

類型什麼時候需要
圖片 sitemap圖片來自其他網域、由程式碼插入,或圖片就是主要內容
影片 sitemap影片是主要內容且需要在影片搜尋曝光
新聞 sitemap有新聞內容且已加入 Google 新聞

一般網站都不需要。圖片與影片的曝光更依賴 替代文字結構化資料

檢查清單

項目標準
sitemap.xml 存在且可存取必備
robots.txt 宣告位置建議
已在 Search Console 提交建議
只包含回傳 200 的正規網址必備
沒有包含 noindex 或被封鎖的網址必備
網址是絕對網址且網域正確必備
單檔未超過 5 萬筆與 50MB必備
由建置流程自動產生建議
<lastmod> 反映真實修改時間建議

常見問題

小網站需要 sitemap 嗎?

頁面數少且內部連結完整的網站,爬蟲光靠連結就走得完,sitemap 的邊際效益不高。但它成本極低且能加速新頁面被發現,仍然建議放一份。真正必要的情況是網站很大、內部連結稀疏,或有 孤兒頁面 沒有被任何連結指到。

changefreq 和 priority 有用嗎?

實際上已被忽略。Google 明確表示不使用這兩個欄位,因為它們完全由網站自行填寫、無法驗證,結果是所有人都把優先權填最高。只有 <lastmod> 在填寫誠實時仍有參考價值。

單一檔案可以放幾個網址?

上限是 5 萬筆網址且未壓縮前不超過 50MB。超過就要拆成多個檔案,再用一個索引檔把它們列出來。索引檔本身同樣受 5 萬筆的限制,所以理論上可容納 25 億個網址。

sitemap 裡該放哪些網址?

只放您希望被收錄、而且回傳 200 的正規網址。標了 noindex 的頁面、被封鎖的路徑、轉址與錯誤頁面都不該出現在裡面,那會發出互相矛盾的訊號並浪費爬取預算。

提交之後多久會被收錄?

沒有保證時間,從幾小時到數週都有可能。sitemap 是建議而非命令,搜尋引擎仍依網站整體重要性與爬取預算決定順序。要加速單一頁面可以用 網址檢查工具 主動請求索引。

延伸閱讀

參考資料:Google 搜尋中心:建立並提交 Sitemap