Перейти к содержимому
Delivery API
Прежде чем рассчитывать на какую-либо функцию, проверьте статус возможностей.

Начало работы

Подключение сайта на Next.js

Читайте опубликованный контент Atlas в вашем существующем сайте на Next.js App Router с предпросмотром, резервным вариантом и мгновенным обновлением при публикации.

Эта страница переведена с английского. При любых расхождениях действует английская версия. Читать на английском

Это руководство подключает существующий сайт на Next.js (App Router) к окружению Atlas Development. На вашем публичном сайте ничего не изменится, пока вы сами не развернёте код.

  • Сайт в Atlas Studio и активный для него контракт сайта. См. Контракт сайта.
  • Ваш сайт умеет выполнять серверный код: серверные компоненты, обработчики маршрутов, Node или Cloudflare Workers.
  • Источник HTTPS, на котором работает ваш сайт в Development (или 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
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
}
}

Клиент возвращает null, когда Atlas недоступен. Именно это обеспечивает работу резервного варианта.

Конечная точка 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, разрешите Studio в вашем Content-Security-Policy: frame-ancestors 'self' https://<studio origin>. Необязательное редактирование по клику описано в разделе Предпросмотр, публикация и откат.

5. Обновляйте страницы в момент публикации контента

Заголовок раздела «5. Обновляйте страницы в момент публикации контента»

Создайте вебхук в Studio (Integrations → Webhooks), указывающий на маршрут вашего сайта, и сохраните его секрет подписи в серверной переменной окружения. Проверяйте каждый запрос, прежде чем действовать по нему; точная проверка описана в разделе Вебхуки. Затем вызовите revalidatePath для затронутых маршрутов (или revalidateTag('atlas')).

При запуске сервера отправьте POST /deployments с дайджестом пакета контракта, который отображает эта сборка, и идентификаторами и версиями компонентов, которые она поддерживает. Затем Studio покажет в разделе Integrations → Website, синхронизирован ли сайт с активным контрактом. Релиз не может уйти в Production, пока сайт не синхронизирован. Подробности: Delivery API.

  • Страница, опубликованная в Studio, появляется на вашем сайте в Development и выглядит так же, как раньше.
  • Если указать в ATLAS_CMS_ORIGIN неверный адрес, сайт по-прежнему отдаёт встроенный контент.
  • Вебхук с неверной подписью отклоняется.
  • Токен доставки не встречается ни в одном клиентском бандле (поищите в выводе .next/static).
  • Studio показывает развёртывание как In sync.

Далее: чек-лист миграции для остальной части сайта.