连接 Next.js 网站
从您现有的 Next.js App Router 网站读取 Atlas 已发布的内容,支持预览、回退以及发布时即时刷新。
本页面由英文翻译而来。如有任何差异,以英文版本为准。 阅读英文版
本指南将现有的 Next.js(App Router)网站连接到 Atlas 的开发环境。在您自行部署代码之前,公开网站不会有任何变化。
- 在 Atlas Studio 中有一个站点,以及为它激活的站点契约。请参阅站点契约。
- 您的网站可以运行服务器代码:服务器组件、路由处理程序、Node 或 Cloudflare Workers。
- 您的开发环境网站所运行的 HTTPS 源(本地开发时可使用
http://localhost)。
1. 创建交付令牌
Section titled “1. 创建交付令牌”在 Studio 中打开 Integrations → Website → New delivery token。选择有效期(1 至 365 天)。令牌只会显示一次;Atlas 只保存它的指纹。
将这些值放入网站的服务器环境中,例如 .env.local 或托管平台的环境设置:
ATLAS_CMS_ORIGIN=https://delivery.atlas.exampleATLAS_ENVIRONMENT_ID=env_XXXXXXXXATLAS_DELIVERY_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX2. 添加一个仅限服务器使用的小型客户端
Section titled “2. 添加一个仅限服务器使用的小型客户端”import 'server-only';
export type AtlasSection = { id: string; component: { id: string; version: string }; // a component from your site contract props: Record<string, unknown>; hidden: boolean;};export type AtlasPage = { page: { id: string; route: string; title: string }; document: { regions: Record<string, AtlasSection[]> }; // region keys come from your page type seo: { title: string; description: string; noindex: boolean; canonicalPath?: string }; assets: Record<string, { url: string; alt?: string }>;};
const base = `${process.env.ATLAS_CMS_ORIGIN}/v1/delivery/environments/${process.env.ATLAS_ENVIRONMENT_ID}`;
export async function atlas<T>(path: string, init?: { revalidate?: number }): Promise<T | null> { try { const response = await fetch(`${base}${path}`, { headers: { Authorization: `PublishedConsumer ${process.env.ATLAS_DELIVERY_TOKEN}` }, next: { revalidate: init?.revalidate ?? 60, tags: ['atlas'] }, signal: AbortSignal.timeout(5000), }); if (response.status === 404) return null; if (!response.ok) throw new Error(`Atlas ${response.status}`); return (await response.json()) as T; } catch (error) { console.error('Atlas unavailable, using built-in content', error); return null; // the caller falls back to the site's own content }}当 Atlas 无法访问时,该客户端返回 null。这正是回退得以实现的原因。
3. 根据区块渲染页面
Section titled “3. 根据区块渲染页面”pages 端点返回某个路由的已发布页面。其 document.regions 按顺序存放区块;每个区块指明您契约中的一个组件,并带有其字段值。
import { notFound } from 'next/navigation';import { atlas, type AtlasPage } from '@/lib/atlas';import { renderSection } from '@/atlas/sections';import { builtInPage } from '@/content/built-in';
export const revalidate = 300;
export default async function Page({ params }: { params: Promise<{ slug?: string[] }> }) { const route = '/' + ((await params).slug ?? []).join('/'); const page = await atlas<AtlasPage>(`/pages?route=${encodeURIComponent(route)}`);
if (!page) { const fallback = builtInPage(route); // today's content, unchanged if (!fallback) notFound(); return fallback; } const sections = (page.document.regions.main ?? []).filter((section) => !section.hidden); return <main>{sections.map((section) => renderSection(section, page.assets))}</main>;}renderSection 将契约中的每个 component.id(例如 acme.home.hero)映射到您现有的 React 组件。请将字段值作为文本或通过您的组件渲染。切勿将 CMS 内容传给 dangerouslySetInnerHTML。
您硬编码的路由会与这个通配路由一起继续工作。由您决定哪些路由交给 Atlas 管理。
4. 添加草稿预览
Section titled “4. 添加草稿预览”Studio 中的 Preview on website 会打开 https://<your site>/api/atlas/preview?token=…。该链接的有效期为 15 分钟。请添加这个路由:
// app/api/atlas/preview/route.ts — outline// 1. Read ?token= and call GET /preview/pages?token=<token> with your delivery token.// 2. 403 PREVIEW_INVALID or 410 PREVIEW_EXPIRED → show a plain error.// 3. Render the draft with <meta name="robots" content="noindex"> and never cache it.预览仅适用于开发环境。
若要让编辑人员在 Studio 的页面编辑器中看到草稿,请在您的 Content-Security-Policy 中允许 Studio:frame-ancestors 'self' https://<studio origin>。可选的点击编辑功能请参阅预览、发布和回滚。
5. 内容一发布就刷新页面
Section titled “5. 内容一发布就刷新页面”在 Studio 中创建一个 Webhook(Integrations → Webhooks),指向您网站上的某个路由,并将其签名密钥存放在服务器环境变量中。在处理每个请求之前都要先验证它;具体校验方式请参阅 Webhook。然后针对受影响的路由调用 revalidatePath(或 revalidateTag('atlas'))。
6. 报告您的构建
Section titled “6. 报告您的构建”服务器启动时,发送 POST /deployments,附上本次构建所渲染的契约包的摘要,以及它支持的组件 id 和版本。随后 Studio 会在 Integrations → Website 下显示网站是否与当前生效的契约保持同步。站点与契约不同步时,发布版本无法进入生产环境。详情:交付 API。
- 在 Studio 中发布的页面出现在您的开发环境网站上,并且外观与之前相同。
- 将
ATLAS_CMS_ORIGIN指向一个错误的地址时,网站仍然提供其内置内容。 - 签名错误的 Webhook 会被拒绝。
- 交付令牌不会出现在任何浏览器包中(请搜索您的
.next/static输出)。 - Studio 将该部署显示为 In sync。
下一步:查看迁移检查清单,完成站点的其余部分。