@farm.js /理智
用于Farm.js应用的Sanity CMS集成。它解析了Sanity客户端配置, 在启动时验证它,并接收Sanity webhooks,因此缓存的内容立即无效 编辑出版。
看到 稳定性和支持 因为这个包裹保证了什么。
安装
pnpm add @farm.js/sanity @sanity/client
@sanity/client 是对等依赖,因此应用程序和集成共享一个客户端。
配置
import { defineConfig } from "@farm.js/core";
import { sanity } from "@farm.js/sanity";
export default defineConfig({
integrations: {
cms: sanity(),
},
});
在没有选项的情况下,值来自环境:
| 变量 | 目的 |
|---|---|
SANITY_PROJECT_ID | 项目id。 SANITY_STUDIO_PROJECT_ID 也是读的。 |
SANITY_DATASET | 数据集。 SANITY_STUDIO_DATASET 也是读的。 |
SANITY_API_VERSION | 可选的。 SANITY_STUDIO_API_VERSION 也是读的。默认为固定日期。 |
SANITY_API_READ_TOKEN | 可选的。查看器令牌,用于私有数据集和草稿。 |
SANITY_WEBHOOK_SECRET | 一旦配置了webhook就需要。 |
缺少项目id或数据集在启动时失败,而不是在第一次请求时失败。
请注意,需要令牌的数据集向未经身份验证的查询返回空结果。 没有错误。如果缺少内容,则在执行其他操作之前先检查令牌。
阅读内容
应用程序拥有客户端。构建它一次,直接使用它,并将相同的对象交给 集成,因此Farm不构建第二个。
// src/lib/cms.server.ts
import { createSanityClient, resolveSanityConfig } from "@farm.js/sanity";
export const cms = createSanityClient(resolveSanityConfig({ useCdn: false }));
// farm.config.ts
integrations: {
cms: sanity({ instance: cms }),
}
将查询封装在 createServerQuery 因此,结果被缓存,并可以通过键使其无效。
import { createServerQuery } from "@farm.js/core";
import { cms } from "./cms.server";
export const postsQuery = createServerQuery({
key: () => ["sanity", "post", "list"],
staleTime: "5m",
handler: () =>
cms.fetch(`*[_type == "post"] | order(publishedAt desc) { title, "slug": slug.current }`),
});
发布时无效
当文档更改时,Sanity可以调用应用程序。集成验证请求 来自Sanity,然后询问应用程序更改影响了哪些缓存条目。
sanity({
instance: cms,
webhook: {
onChange(payload) {
if (payload._type !== "post") return;
const slug = payload.slug as string;
return {
keys: [
["sanity", "post", "list"],
["sanity", "post", slug],
],
paths: ["/posts", `/posts/${slug}`],
};
},
},
});
keys 是服务器查询键。 paths 路由路径的渲染输出应该是
也被重新验证了。对于不影响缓存内容的更改,不返回任何内容。
在Sanity中,创建一个webhook API > Webhooks:
- URL:
https://your-app.example/api/sanity/webhook - 触发创建、更新和删除
- 投影:
{ _id, _type, "slug": slug.current } - 的值
SANITY_WEBHOOK_SECRET
传递给 onChange 投影返回的是什么,所以包含字段是
映射的需要。例如,其他人引用的文档可以列出它们
"slugs": *[_type == "post" && references(^._id)].slug.current.
回复遵循Sanity接下来的做法: 401 一个糟糕的签名 400 为了一个畸形的身体
不重试,和 500 从失败中 onChange 重试。
通读API,而不是CDN
集 useCdn: false 当webhook驱动无效时,在客户端上。webhook之前触发
Sanity的CDN已经更新,因此通过CDN重新获取可以返回以前的内容和缓存
它又为满了 staleTime. Farm的缓存是这个设置中的缓存;第二个在前面
它只增加了种族。
为依赖的应用程序保留CDN staleTime 单独使用,或用于浏览器端读取。
多个服务器实例
Farm的数据缓存保存在每个进程的内存中,除非配置了分布式适配器。在一个
无服务器平台,webhook到达一个实例,只清除该实例的内存。使用
一个适配器,例如 @farm.js/cache-redis 因此,无效会到达每个实例。
选项
| 选项 | 默认的 | 笔记 |
|---|---|---|
projectId | env | |
dataset | env | |
apiVersion | 固定的日期 | 导出为 DEFAULT_SANITY_API_VERSION. |
token | env | 服务器只。从未传递给浏览器。 |
useCdn | true | 集 false 与webhook无效。 |
instance | 现有的 SanityClient. 跳过凭证验证。 | |
webhook.secret | env | |
webhook.path | /api/sanity/webhook | |
webhook.onChange | 将有效负载映射到 { keys?, paths? }. | |
log | 集成生命周期日志记录器。 |
带上自己的客户
通过已配置的客户端 instance 对于集成不公开的选项。这个
Integration按原样使用该对象。
import { createClient } from "@sanity/client";
sanity({ instance: createClient({ projectId, dataset, apiVersion, perspective: "published" }) });