17: 搜索引擎优化
seo 资源集中管理应用所需的搜索和共享元数据:sitemap.xml、robots.txt、hreflang 替代项、规范链接,以及包含 <meta> 描述的 <head> 块,还有 Open Graph 和 Twitter 卡片。它从您已经设置的 props 中派生出所有内容,因此一个统一、完整但又适度的集合从一个地方发出。
17.1: 激活
添加资源(它需要 output):
{
"resources": [..., "seo", "output"]
}
这单独服务于两个路由:
| 路由 | 输出 |
|---|---|
GET /sitemap.xml |
从 %app->pages 和 %app->langs 构建的多语言网站地图 |
GET /robots.txt |
Allow 或 Disallow,基于 indexable 常量的限制(见 X.4) |
<head> 元数据是每个页面可选的:在需要的地方渲染 %seo->head(X.3)。
17.2: 网站地图和 hreflang
网站地图遍历 %app->pages,并为每个页面根据 %app->langs 中的每个条目发出一个 hreflang 替代项,以及一个 x-default。本地化路径来自 %app->slugs(一个 uri => localised-uri 映射),当你有它们时;否则,路径会以语言代码为前缀。
在你的 <head> 中,相同的替代项作为 <link rel=alternate hreflang> 标签存在。该资源为你提供一个 view,因此你循环你的语言,并让 seo 格式化每个链接:
view head:
<foreach array_keys(%app->langs) AS $lang>
{{ %seo->link($lang, $lang === %app->lang ? %req->uri : "/$lang".%req->uri) }}
</foreach>
{{ %seo->head }}
应用程序拥有哪些 URL 是替代的(它知道自己的路由和本地化);seo 拥有标记。
17.3: 头块
%seo->head 渲染常规的元数据集,所有内容均源自现有的 props:
<meta name=description>(仅在存在描述时);- Open Graph:
og:site_name、og:title、og:description、og:type、og:url、og:image、og:locale; <link rel=canonical>(当页面为noindex时会被删除);- Twitter 摘要卡,选择性加入(X.5);
- 当页面选择退出时,
<meta name=robots content=noindex,follow>(X.5)。
它是可组合的,而不是替代品:保留您应用程序自己的头部标签(标题、CSRF、样式),并将 %seo->head 作为补充。没有关键词和营销填充;该集合包括 Open Graph、Twitter 卡、规范、hreflang、描述和 robots,这是通常的完整但受限的基线。
默认值从您已有的 props 中读取:
| 属性 | 默认来源 |
|---|---|
og:title |
文档标题 |
og:description / description |
%app->description |
og:image |
%app->image,如果没有则回退到站点根目录的 /icon.webp |
og:url / canonical |
当前请求的 URL |
og:site_name |
应用的 id |
og:locale |
从 %app->lang 派生(例如 nl 变为 nl_NL) |
og:type |
website |
17.4: robots.txt 和可索引常量
robots.txt 已生成,并且默认是安全的。除非应用将 indexable 常量设置为一个真实值,否则资源将提供:
User-agent: *
Disallow: /
因此,开发、阶段和任何非公开主机都可以通过不声明 indexable 来取消索引。仅在真实的生产入口点上设置它,同时也设置真实的主机:
phlo_app(
id: 'Example',
host: 'example.com',
indexable: true,
);
使用 indexable: true,资源会提供一个 Allow: /,每个 %app->robotsDisallow 中的条目都有一行 Disallow:,并且还有一行 Sitemap:。由于 robots.txt 是来自路由,因此没有静态的 robots.txt 需要维护或意外从开发主机部署。
17.5: 每个应用和每个页面的覆盖
默认设置涵盖了大多数应用程序。使用跨类注入习惯(请参见高级章节)覆盖其余部分,该习惯在构建时设置 prop:
prop %seo.twitterCard = true
prop %seo.ogType = 'article'
prop %seo.siteName = 'Example Co'
twitterCard 选项用于启用 Twitter 摘要卡,ogType 用于覆盖 Open Graph 类型,而 siteName 用于覆盖站点名称(默认值:%app->title,如果没有则回退到应用 ID)。
每个请求从应用 props 中读取两个选择退出选项,因此单个页面可以在不影响网站其余部分的情况下从索引中删除:
| 属性 | 效果 |
|---|---|
%app->image |
整个应用的默认 Open Graph 图像 |
%app->noIndex(或 %app->noLink) |
将当前页面标记为 noindex,follow 并删除其规范链接 |
在渲染之前在路由中设置 %app->noIndex,以使该页面不出现在搜索结果中,而应用的其余部分仍然可以被索引。