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.01meta 标签,用于向 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。