内置 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。