804 字
4 分钟
使用 Sanity CMS + Next.js 构建高性能内容驱动型应用
### 1. 为什么在 Jamstack 架构中选择 Sanity?
在现代 Web 开发中,Jamstack (JavaScript, API, Markup) 已成为构建快速、安全网站的主流方案。而 Sanity CMS 作为一款“无头(Headless)”内容平台,与传统的 CMS 有本质不同:
- 内容即数据(Content as Data):Sanity 不存储 HTML,而是存储结构化的 JSON 格式。这意味着一份内容可以无缝分发到网站、移动端甚至是智能手表。
- 解耦的 Studio:Sanity Studio 是一个基于 React 的开源编辑界面。你可以根据需求,像开发普通 React 应用一样定制复杂的输入控件。
- 强大的查询语言 GROQ:比 GraphQL 更简洁、更灵活,专为 JSON 数据查询设计。
### 2. 核心:无头 CMS 的五大优势
- 安全性:后端数据库不直接暴露在公网,通过 API 令牌访问,极大减小了被攻击的可能性。
- 多渠道分发:一次编写,随处运行。
- 灵活建模:不再受限于 WordPress 的“文章/页面”模式,你可以自由定义
Project,Author,Service等任何模型。 - 卓越的开发者体验 (DX):通过 CLI 工具快速初始化,API 驱动的开发流程符合现代工程习惯。
- 增量静态再生 (ISR):配合 Next.js,可以在内容更新后自动触发部分页面重新构建,无需全量更新。
### 3. 实战指南:集成 Sanity 到 Next.js
#### 第一步:初始化 Next.js 前端
npx create-next-app@latest clientcd clientnpm dev#### 第二步:搭建 Sanity Studio
在项目根目录外或子目录中,初始化 Sanity:
npm install -g @sanity/clisanity init选择默认设置后,进入 cms 目录启动管理后台:
cd cmssanity start -p 3333#### 第三步:定义内容模型 (Schema)
在 schemas/homepage.js 中,我们不仅定义字段,还添加一些辅助信息:
export default { name: 'homepage', title: '首页内容', type: 'document', fields: [ { name: 'title', title: '主标题', type: 'string', validation: Rule => Rule.required() // 添加简单校验 }, { name: 'subtitle', title: '副标题', type: 'string' }, { name: 'image', title: '封面图片', type: 'image', options: { hotspot: true } // 允许在后台在线裁剪图片 }, { name: 'cta', title: '行动呼吁 (URL)', type: 'slug' }, ],};#### 第四步:配置 Next.js 连接器
安装必要依赖:
npm install @sanity/client @sanity/image-url在 lib/sanity.js 中封装客户端(注意:现代版本建议使用 createClient):
import { createClient } from '@sanity/client';import imageUrlBuilder from '@sanity/image-url';
export const client = createClient({ projectId: 'your_project_id', dataset: 'production', apiVersion: '2022-03-07', // 指定 API 版本 useCdn: true, // 使用 CDN 加速获取数据});
// 处理图片 URL 的辅助函数const builder = imageUrlBuilder(client);export const urlFor = (source) => builder.image(source);#### 第五步:使用 GROQ 查询并渲染
在 pages/index.js 中利用 getStaticProps 实现高性能加载:
import { client, urlFor } from '../lib/sanity';
const homepageQuery = `*[_type == "homepage"][0]{ title, subtitle, "ctaUrl": cta.current, image}`;
export async function getStaticProps() { const data = await client.fetch(homepageQuery); return { props: { data }, revalidate: 10, // 每 10 秒尝试重新验证内容 };}
export default function Home({ data }) { return ( <main style={{ maxWidth: '800px', margin: '0 auto' }}> <h1>{data.title}</h1> {data.image && ( <img src={urlFor(data.image).width(800).url()} alt={data.title} /> )} <p>{data.subtitle}</p> <a href={data.ctaUrl} className="btn">立即开始</a> </main> );}### 4. 总结与进阶建议
通过将 Sanity 与 Next.js 结合,你拥有了一个兼具“静态网站性能”和“动态内容管理灵活性”的架构。
使用 Sanity CMS + Next.js 构建高性能内容驱动型应用
https://sw.rscclub.website/posts/sanitycmsnextjs/