跳到內容
Delivery API
在規劃採用某項功能之前,請先查看功能狀態。

開始使用

連接 Next.js 網站

從您現有的 Next.js App Router 網站讀取已發布的 Atlas 內容,並具備預覽、備援內容,以及發布時即時重新整理。

本頁翻譯自英文。若內容有任何差異,以英文版為準。 閱讀英文版

本指南會將現有的 Next.js(App Router)網站連接到 Atlas 的 Development 環境。在您自行部署程式碼之前,公開網站上不會有任何變動。

  • Atlas Studio 中的一個網站,以及該網站已啟用的網站合約。請參閱網站合約。
  • 您的網站可以執行伺服器端程式碼:伺服器元件、路由處理常式、Node 或 Cloudflare Workers。
  • 您的 Development 網站執行所在的 HTTPS 來源(或在本機作業時使用 http://localhost)。

在 Studio 中開啟 Integrations → Website → New delivery token。選擇有效期限(1 至 365 天)。權杖只會顯示一次;Atlas 只儲存其指紋。

將這些值放入網站的伺服器端環境設定,例如 .env.local 或主機服務的環境設定:

終端機視窗
ATLAS_CMS_ORIGIN=https://delivery.atlas.example
ATLAS_ENVIRONMENT_ID=env_XXXXXXXX
ATLAS_DELIVERY_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

2. 加入一個小型的僅限伺服器端用戶端

Section titled “2. 加入一個小型的僅限伺服器端用戶端”
lib/atlas.ts
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。這正是備援內容得以運作的原因。

pages 端點會回傳某個路由已發布的頁面。其 document.regions 依序存放各區塊;每個區塊指向網站合約中的一個元件,並帶有其欄位值。

app/[[...slug]]/page.tsx
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 管理。

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.

預覽僅適用於 Development 環境。

若要讓編輯者在 Studio 的頁面編輯器內查看草稿,請在您的 Content-Security-Policy 中允許 Studio:frame-ancestors 'self' https://<studio origin>。選用的點擊編輯功能說明於預覽、發布與還原。

在 Studio(Integrations → Webhooks)中建立一個指向您網站某個路由的 Webhook,並將其簽署密鑰存放在伺服器端環境變數中。在採取任何動作之前,請先驗證每個請求;確切的檢查方式請參閱 Webhooks。接著對受影響的路由呼叫 revalidatePath(或 revalidateTag('atlas'))。

伺服器啟動時,傳送 POST /deployments,附上此建置所算繪之合約套件的摘要值,以及它所支援的元件 id 與版本。Studio 隨後會在 Integrations → Website 下顯示網站是否與已啟用的合約同步。網站未同步時,發行版本無法進入 Production。詳細資訊:Delivery API。

  • 在 Studio 中發布的頁面會出現在您的 Development 網站上,且外觀與先前相同。
  • 將 ATLAS_CMS_ORIGIN 指向錯誤的位址時,網站仍會提供其內建內容。
  • 簽章錯誤的 Webhook 會被拒絕。
  • 傳遞權杖不會出現在任何瀏覽器套件中(請搜尋您的 .next/static 輸出)。
  • Studio 顯示該部署為已同步(In sync)。

下一步:以遷移檢查清單處理網站的其餘部分。