Back to skills
SKILL.md
X Openai Cms Aa44b3f
ASecurityHeadless CMS integration guidance — Sanity (native Vercel Marketplace), Contentful, DatoCMS, Storyblok, and Builder.io. Covers studio setup, content modeling, preview mode, revalidation webhooks, and Visual Editing. Use when building content-driven sites with a headless CMS on Vercel.
- 2 stars
- 0 votes
- 0 copies
- 0 views
- Added October 14, 2026
Works with
Security analysis
96/100- Installs packages at runtime which could introduce malicious dependencies
Pro scans all 3 files and shows the line behind each finding
npx -y skills add Geruyang/agent-skills-library --skill x-openai-cms-aa44b3f --agent claude-codeAre you the author of X Openai Cms Aa44b3f?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/geruyang-x-openai-cms-aa44b3f)---
name: x-openai-cms-aa44b3f
description: Headless CMS integration guidance — Sanity (native Vercel Marketplace), Contentful, DatoCMS, Storyblok, and Builder.io. Covers studio setup, content modeling, preview mode, revalidation webhooks, and Visual Editing. Use when building content-driven sites with a headless CMS on Vercel.
metadata:
priority: '4'
docs: '[''https://vercel.com/docs/solutions/cms'', ''https://nextjs.org/docs/app/building-your-application/data-fetching'']'
sitemap: https://vercel.com/sitemap/docs.xml
pathPatterns: '[''sanity.config.*'', ''sanity.cli.*'', ''sanity/**'', ''studio/**'', ''schemas/*.ts'', ''schemas/*.tsx'', ''src/sanity/**'', ''lib/sanity.*'', ''src/lib/sanity.*'', ''lib/contentful.*'', ''src/lib/contentful.*'', ''app/api/draft/**'', ''src/app/api/draft/**'', ''app/api/revalidate/**'', ''src/app/api/revalidate/**'', ''app/studio/**'', ''src/app/studio/**'']'
bashPatterns: '[''\\bnpm\\s+(install|i|add)\\s+[^\\n]*@sanity/client\\b'', ''\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@sanity/client\\b'', ''\\bbun\\s+(install|i|add)\\s+[^\\n]*@sanity/client\\b'', ''\\byarn\\s+add\\s+[^\\n]*@sanity/client\\b'', ''\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bnext-sanity\\b'', ''\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bnext-sanity\\b'', ''\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bnext-sanity\\b'', ''\\byarn\\s+add\\s+[^\\n]*\\bnext-sanity\\b'', ''\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bcontentful\\b'', ''\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bcontentful\\b'', ''\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bcontentful\\b'', ''\\byarn\\s+add\\s+[^\\n]*\\bcontentful\\b'', ''\\bnpm\\s+(install|i|add)\\s+[^\\n]*@builder\\.io/sdk\\b'', ''\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@builder\\.io/sdk\\b'', ''\\bbun\\s+(install|i|add)\\s+[^\\n]*@builder\\.io/sdk\\b'', ''\\byarn\\s+add\\s+[^\\n]*@builder\\.io/sdk\\b'', ''\\bnpm\\s+(install|i|add)\\s+[^\\n]*@storyblok/\\b'', ''\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@storyblok/\\b'', ''\\bbun\\s+(install|i|add)\\s+[^\\n]*@storyblok/\\b'', ''\\byarn\\s+add\\s+[^\\n]*@storyblok/\\b'', ''\\bnpm\\s+(install|i|add)\\s+[^\\n]*datocms-client\\b'', ''\\bpnpm\\s+(install|i|add)\\s+[^\\n]*datocms-client\\b'', ''\\bbun\\s+(install|i|add)\\s+[^\\n]*datocms-client\\b'', ''\\byarn\\s+add\\s+[^\\n]*datocms-client\\b'', ''\\bnpx\\s+create-sanity\\b'', ''\\bnpx\\s+sanity\\s+init\\b'']'
---
### 导出副本边界与技能别名
迁移、安装、修复和经验回写只作用于当前加载的目标宿主技能副本。原 Codex 技能/MCP、下载的源码和 `original-skills` 均为来源材料,不因执行本副本而写入;只有用户另行明确要求配置 Codex 产品本身时,才按该产品流程处理指定目标。脚本需要安装目录或状态目录时,显式提供目标路径;不得从 `CODEX_HOME` 隐式推断写入位置。
跨技能名称可能沿用源库别名。先查 [技能别名表](../../skill-aliases.json),优先选择同来源、同插件的条目,再使用其 `id` 调用或读取对应入口;不得假定旧 `$skill`、`superpowers:skill` 名称在新宿主直接注册。不能确定目标时先核对,不替换真实产品命令或 Shell 环境变量。
## 跨宿主使用约定
本副本供支持 Agent Skills 的客户端使用。先检查当前宿主实际提供的工具、权限和已连接服务,再执行正文工作流。原文中的宿主工具标识是能力参考;只有实际发现该工具时才可调用,其他宿主应使用经核验的等价 MCP、CLI 或 API。没有等价能力的步骤必须报告不可用,不能虚构调用或完成状态。
技能资源以本技能目录为基准;输出写入当前项目中用户指定的位置。通过技能名称或自然语言触发,具体快捷命令由宿主决定。涉及真实产品、模型 API、协议字段和官方网址的名称保持原意。授权、审批、隐私和工具范围限制在迁移后仍然有效;不得为兼容而扩大权限。具体依赖与迁移说明见同目录 `PORTABILITY.md`。
# Headless CMS Integration
You are an expert in integrating headless CMS platforms with Vercel-deployed applications — covering Sanity (native Vercel Marketplace), Contentful, DatoCMS, Storyblok, and Builder.io.
## Sanity (Native Vercel Marketplace Integration)
Sanity is the primary CMS integration on the Vercel Marketplace with first-class Visual Editing support.
### Install via Marketplace
```bash
# Install Sanity from Vercel Marketplace (auto-provisions env vars)
vercel integration add sanity
```
Auto-provisioned environment variables:
- `SANITY_PROJECT_ID` — Sanity project identifier
- `SANITY_DATASET` — dataset name (usually `production`)
- `SANITY_API_TOKEN` — read/write API token
- `NEXT_PUBLIC_SANITY_PROJECT_ID` — client-side project ID
- `NEXT_PUBLIC_SANITY_DATASET` — client-side dataset name
### SDK Setup
```bash
# Install Sanity packages for Next.js
npm install next-sanity @sanity/client @sanity/image-url
# For embedded studio (optional)
npm install sanity @sanity/vision
```
### Client Configuration
```ts
// lib/sanity.ts
import { createClient } from "next-sanity";
export const client = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET!,
apiVersion: "2026-03-01",
useCdn: true,
});
```
### Content Schema
```ts
// schemas/post.ts
import { defineType, defineField } from "sanity";
export const post = defineType({
name: "post",
title: "Post",
type: "document",
fields: [
defineField({ name: "title", type: "string" }),
defineField({ name: "slug", type: "slug", options: { source: "title" } }),
defineField({ name: "body", type: "array", of: [{ type: "block" }] }),
defineField({ name: "mainImage", type: "image", options: { hotspot: true } }),
defineField({ name: "publishedAt", type: "datetime" }),
],
});
```
### Embedded Studio (App Router)
```ts
// app/studio/[[...tool]]/page.tsx
"use client";
import { NextStudio } from "next-sanity/studio";
import config from "@/sanity.config";
export default function StudioPage() {
return <NextStudio config={config} />;
}
```
```ts
// sanity.config.ts
import { defineConfig } from "sanity";
import { structureTool } from "sanity/structure";
import { visionTool } from "@sanity/vision";
import { post } from "./schemas/post";
export default defineConfig({
name: "default",
title: "My Studio",
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET!,
plugins: [structureTool(), visionTool()],
schema: { types: [post] },
});
```
### Live Content with `defineLive()` (next-sanity v12)
Use `defineLive()` for automatic real-time content updates without manual revalidation. In next-sanity v11+, `defineLive` must be imported from the `next-sanity/live` subpath:
```ts
// lib/sanity.ts
import { createClient } from "next-sanity";
import { defineLive } from "next-sanity/live";
const client = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET!,
apiVersion: "2026-03-01",
useCdn: true,
});
export const { sanityFetch, SanityLive } = defineLive({
client,
// Required for draft content in Visual Editing — use a Viewer role token
serverToken: process.env.SANITY_API_TOKEN,
// Optional but recommended for faster live preview
browserToken: process.env.SANITY_BROWSER_TOKEN,
});
```
```tsx
// app/page.tsx
import { sanityFetch, SanityLive } from "@/lib/sanity";
export default async function Page() {
const { data: posts } = await sanityFetch({ query: `*[_type == "post"]` });
return (
<>
{posts.map((post) => <div key={post._id}>{post.title}</div>)}
<SanityLive />
</>
);
}
```
> **Breaking change in v12**: `defineLive({fetchOptions: {revalidate}})` has been removed. `defineLive({stega})` is deprecated.
### Visual Editing (Presentation Mode)
Sanity Visual Editing lets content editors click-to-edit content directly on the live site preview. Requires Sanity Studio v5+ (React 19.2) and `@sanity/visual-editing` v5+.
```bash
npm install @sanity/visual-editing
```
In next-sanity v11+, `VisualEditing` must be imported from the `next-sanity/visual-editing` subpath:
```ts
// app/layout.tsx
import { VisualEditing } from "next-sanity/visual-editing";
import { draftMode } from "next/headers";
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const { isEnabled } = await draftMode();
return (
<html>
<body>
{children}
{isEnabled && <VisualEditing />}
</body>
</html>
);
}
```
### On-Demand Revalidation Webhook
```ts
// app/api/revalidate/route.ts
import { revalidateTag } from "next/cache";
import { parseBody } from "next-sanity/webhook";
export async function POST(req: Request) {
const { isValidSignature, body } = await parseBody<{
_type: string;
slug?: { current?: string };
}>(req, process.env.SANITY_REVALIDATE_SECRET);
if (!isValidSignature) {
return Response.json({ message: "Invalid signature" }, { status: 401 });
}
if (body?._type) {
revalidateTag(body._type);
}
return Response.json({ revalidated: true, now: Date.now() });
}
```
Configure the webhook in Sanity at **Settings → API → Webhooks** pointing to `https://your-site.vercel.app/api/revalidate`.
## Contentful
```bash
npm install contentful
```
```ts
// lib/contentful.ts
import { createClient } from "contentful";
export const contentful = createClient({
space: process.env.CONTENTFUL_SPACE_ID!,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,
});
```
### Fetching Entries
```ts
// app/page.tsx
import { contentful } from "@/lib/contentful";
export default async function Page() {
const entries = await contentful.getEntries({ content_type: "blogPost" });
return (
<ul>
{entries.items.map((entry) => (
<li key={entry.sys.id}>{entry.fields.title as string}</li>
))}
</ul>
);
}
```
## Draft Mode (Preview)
All CMS integrations should use Next.js Draft Mode for preview:
```ts
// app/api/draft/route.ts
import { draftMode } from "next/headers";
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const secret = searchParams.get("secret");
if (secret !== process.env.DRAFT_SECRET) {
return Response.json({ message: "Invalid token" }, { status: 401 });
}
const draft = await draftMode();
draft.enable();
const slug = searchParams.get("slug") ?? "/";
return Response.redirect(new URL(slug, req.url));
}
```
## Environment Variables
| Variable | Scope | CMS | Description |
|----------|-------|-----|-------------|
| `SANITY_PROJECT_ID` / `NEXT_PUBLIC_SANITY_PROJECT_ID` | Server / Client | Sanity | Project identifier |
| `SANITY_DATASET` / `NEXT_PUBLIC_SANITY_DATASET` | Server / Client | Sanity | Dataset name |
| `SANITY_API_TOKEN` | Server | Sanity | Read/write token |
| `SANITY_REVALIDATE_SECRET` | Server | Sanity | Webhook secret for revalidation |
| `CONTENTFUL_SPACE_ID` | Server | Contentful | Space identifier |
| `CONTENTFUL_ACCESS_TOKEN` | Server | Contentful | Delivery API token |
| `CONTENTFUL_PREVIEW_TOKEN` | Server | Contentful | Preview API token |
| `DATOCMS_API_TOKEN` | Server | DatoCMS | Read-only API token |
## Cross-References
- **Marketplace install and env var provisioning** → `⤳ skill: marketplace`
- **On-demand revalidation and caching** → `⤳ skill: runtime-cache`
- **Draft mode and middleware patterns** → `⤳ skill: routing-middleware`
- **Environment variable management** → `⤳ skill: env-vars`
- **Image optimization** → `⤳ skill: nextjs`
## Official Documentation
- [Sanity + Vercel Marketplace](https://vercel.com/marketplace/sanity)
- [next-sanity Documentation](https://github.com/sanity-io/next-sanity) (v12)
- [next-sanity v11→v12 Migration](https://github.com/sanity-io/next-sanity/releases)
- [Sanity Visual Editing](https://www.sanity.io/docs/visual-editing)
- [Contentful JavaScript SDK](https://www.contentful.com/developers/docs/javascript/)
- [Next.js Draft Mode](https://nextjs.org/docs/app/building-your-application/configuring/draft-mode)
Files in this skill
- PORTABILITY.md
- SKILL.md
- agents/openai.yaml
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.