內建 SEO 功能

本頁內容

EmDash 為內容條目、頁面 head、站台地圖、robots.txt 和重新導向提供搜尋引擎最佳化(SEO)功能。只要集合啟用了 SEO,並且站台在頁面 head 中算繪 <EmDashHead>,大多數功能就能正常運作。

功能輸出需求
SEO 面板每個條目的標題、描述、圖片、正規 URL 和 no-index集合已啟用 SEO
Head 中繼資料描述、robots、canonical、Open Graph 和 Twitter Card 標籤頁面 head 中有 <EmDashHead>
結構化資料JSON-LD BlogPosting 或 WebSite頁面 head 中有 <EmDashHead>
站台地圖/sitemap.xml 和 /sitemap-{collection}.xml集合已啟用 SEO
robots.txt帶有站台地圖參照的 /robots.txt無
站台層級設定驗證標籤、預設社群圖片、標題分隔符號Settings > SEO 中的值
翻譯head 和站台地圖中的 hreflang 連結已設定 Astro i18n
重新導向與 404 記錄重新導向和 gone 規則,以及未命中 URL 的記錄無

在集合上啟用 SEO

在 EmDash 管理後台的 Content Types 中為集合開啟 SEO。在種子檔案中,將 "seo" 新增到集合的 supports 陣列:

{
  "version": "1",
  "collections": [
    {
      "slug": "posts",
      "label": "Posts",
      "urlPattern": "/posts/{slug}",
      "supports": ["drafts", "revisions", "seo"],
      "fields": [{ "slug": "title", "label": "Title", "type": "string", "required": true }]
    }
  ]
}

啟用 SEO 後,已儲存條目的編輯器會顯示 SEO 面板,集合會出現在站台地圖中。關閉了 Routable 的集合不會出現在站台地圖中。

編輯每個條目的 SEO 欄位

條目編輯器中的 SEO 面板包含以下欄位:

  • OG Image 是社群預覽圖片(og:image),也是站台地圖中為該條目列出的圖片。
  • SEO Title 在社群預覽和結構化資料中取代條目標題;當頁面透過 getSeoMeta() 算繪標題時,也會在 <title> 中取代條目標題。
  • Meta Description 是搜尋結果中顯示在標題下方的摘要。面板會依 160 個字元的建議值統計字數。
  • Canonical URL 為複製自其他 URL 的頁面,向搜尋引擎指明原始版本。
  • Hide from search engines 會向頁面新增 noindex, nofollow,並將條目從站台地圖和 hreflang 替代連結中移除。

空白欄位會回退到頁面傳給 createPublicPageContext() 的值。getSeoMeta() 會回退到條目的 title 和 excerpt 欄位。

在內容頁面中算繪 SEO 中繼資料

<EmDashHead> 會為頁面上下文算繪 SEO 中繼資料。在內容頁面上,將條目的集合和資料庫 ID 作為 content 傳入,<EmDashHead> 就會套用該條目 SEO 面板中的值。

以下範例算繪文章頁面的 head。getSeoMeta() 解析 <title> 和正規 URL,<EmDashHead> 算繪其餘標籤:

---
import { decodeSlug, getEmDashEntry, getSeoMeta, getSiteSettings } from "emdash";
import { createPublicPageContext } from "emdash/page";
import { EmDashHead } from "emdash/ui";

const slug = decodeSlug(Astro.params.slug);
if (!slug) return Astro.rewrite("/404");

const { entry: post } = await getEmDashEntry("posts", slug);
if (!post) return Astro.rewrite("/404");

const settings = await getSiteSettings();
const seo = getSeoMeta(post, {
  siteTitle: settings.title,
  siteUrl: settings.url || Astro.url.origin,
  titleSeparator: settings.seo?.titleSeparator,
  path: Astro.url.pathname,
});

const page = createPublicPageContext({
  Astro,
  kind: "content",
  title: seo.title,
  pageTitle: seo.ogTitle,
  description: seo.description,
  canonical: seo.canonical,
  siteName: settings.title,
  content: { collection: "posts", id: post.data.id, slug: post.data.slug },
});
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>{seo.title}</title>
    <EmDashHead page={page} />
  </head>
  <body>
    <h1>{post.data.title}</h1>
  </body>
</html>

<EmDashHead> 會算繪以下標籤:

  • meta description。
  • 條目對搜尋引擎隱藏時的 robots 指令。
  • 頁面上下文或條目設定了正規 URL 時的 canonical 連結和 og:url。
  • Open Graph 標籤(og:type、og:title、og:description、og:image、og:site_name)和 Twitter Card 標籤。當頁面沒有圖片時,og:image 使用站台設定中的預設社群圖片。
  • 頁面上下文包含 articleMeta 時的 article:published_time、article:modified_time 和 article:author。

<EmDashHead> 不會算繪 <title> 元素。請像範例那樣,在頁面或版面中算繪它。

對於不是內容條目的頁面,請使用 kind: "custom"。站台設定展示了一個根據站台設定建構自訂頁面上下文的版面。

外掛可以透過 page:metadata 鉤子新增或取代 head 標籤。對於同一個標籤,外掛的值優先於站台設定,站台設定又優先於由頁面上下文產生的值。

結構化資料

當頁面上下文包含所需資料時,<EmDashHead> 會向頁面新增一個 JSON-LD 腳本:

  • 帶有正規 URL 的文章頁面會得到一個 BlogPosting 圖,包含頁面上下文提供的標題、描述、圖片、發布和修改日期、作者及發布者。kind: "content" 會將 pageType 設為 "article",除非頁面上下文設定了其他類型。
  • 其他類型的頁面,在頁面上下文包含 siteName 時,會得到一個包含站台名稱和 URL 的 WebSite 圖。

JSON-LD 使用與 Open Graph 標籤相同的標題、描述和圖片,包括編輯者在 SEO 面板中填寫的值。外掛可以透過 page:metadata 鉤子取代它。

站台地圖

EmDash 在 /sitemap.xml 提供站台地圖索引。對於每個至少有一個已列出條目的集合,它會連結一個位於 /sitemap-{collection}.xml 的子站台地圖。

集合站台地圖會列出已發布、未刪除、有 slug 且未對搜尋引擎隱藏的條目。它根據集合的 URL 模式建構每個 URL,集合沒有模式時使用 /{collection}/{slug},並透過 Google 圖片站台地圖擴充功能列出條目的 SEO 圖片。

每個子站台地圖最多包含 2,000 個條目,並依條目 ID 排序,因此編輯條目不會讓它移動到另一頁。更大的集合會繼續使用 /sitemap-{collection}-2.xml、/sitemap-{collection}-3.xml,依此類推。索引會列出每一頁,並附上該頁中最近更新條目的日期。

將站台地圖 URL 新增到 Google Search Console 或 Bing Webmaster Tools,即可在那裡查看其索引狀態。

robots.txt

EmDash 提供 /robots.txt。預設情況下,它允許所有爬蟲、禁止存取 /_emdash/,並參照站台地圖:

User-agent: *
Allow: /

# Disallow admin and API routes
Disallow: /_emdash/

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

要取代預設內容,請在 Settings > SEO > robots.txt 中輸入自訂內容。如果自訂內容中沒有 Sitemap: 行,EmDash 會附加一行。

robots.txt 和站台地圖依序根據 Settings > General 中的 Site URL、siteUrl 選項或 EMDASH_SITE_URL 環境變數、請求來源建構絕對 URL。請設定其中之一,使 URL 與公開網域一致。瀏覽器和共用快取可能會將 robots.txt 保留最多一天,將站台地圖保留最多一小時。

站台層級 SEO 設定

EmDash 管理後台中的 Settings > SEO 包含以下值:

  • Title Separator 是頁面標題和站台名稱之間的文字。當頁面像內容頁面範例那樣,將 settings.seo.titleSeparator 作為 titleSeparator 傳給 getSeoMeta() 時才會生效。
  • Default Social Image 是沒有自己圖片的頁面所使用的 og:image。<EmDashHead> 會套用它。
  • Google Verification 和 Bing Verification 會新增 google-site-verification 和 msvalidate.01 meta 標籤,用於向 Google Search Console 和 Bing Webmaster Tools 證明站台擁有權。<EmDashHead> 會將它們新增到每個頁面。
  • robots.txt 會取代預設的 robots.txt。

已翻譯的內容

設定了 Astro i18n 後,EmDash 會為搜尋引擎關聯條目的各個翻譯:

  • <EmDashHead> 會為每個已發布的翻譯新增一個 <link rel="alternate" hreflang="...">,並新增一個 x-default 連結。請參閱向頁面 head 新增 hreflang 連結。
  • 每個集合站台地圖都會將每個翻譯作為獨立的 URL 列出,並附帶 xhtml:link 替代連結。請參閱國際化指南中的站台地圖。

重新導向與 404 記錄

在 EmDash 管理後台的 Redirects 中管理規則。一條規則要麼將來源路徑以狀態碼 301、302、307 或 308 重新導向到目標,要麼以 410 Gone 或 451 Unavailable For Legal Reasons 回應。來源路徑支援具名區段(/old/[slug])和萬用區段(/old-blog/[...path]),目標可以重複使用這些區段。

當已發布條目的 slug 發生變化時,EmDash 會根據集合的 URL 模式,建立一條從舊 URL 到新 URL 的 301 重新導向。它會合併原先指向舊 URL 的現有重新導向鏈。當另一個條目(例如某個翻譯)仍在使用舊 slug 時,它不會建立重新導向。

EmDash 會記錄以 404 回應結束的請求。Redirects 頁面上的 404 Errors 分頁會顯示最常被存取卻未命中的路徑。對於每個路徑,你可以新增重新導向,或將其標記為 gone(410),以告知搜尋引擎該頁面已被刪除。記錄最多保留 10,000 個路徑,並捨棄最久未出現的路徑。

種子檔案也可以定義重新導向。請參閱種子檔案參考中的 Redirects。

匯入的 SEO 資料

透過 EmDash Exporter 進行的 WordPress 匯入可以將 Yoast 和 Rank Math 的 SEO 標題和描述複製到目標集合的 SEO Title 和 SEO Description 欄位中。這些是一般內容欄位,獨立於 SEO 面板,因此頁面範本必須自行算繪它們。

站台轉移會將 SEO 面板的值、SEO 設定和重新導向複製到另一個 EmDash 站台。目標站台保留自己的站台 URL,其站台地圖和 robots.txt 會使用該 URL。