Налаштування Contentful Delivery API / Management API / Preview API
Contentful надає три окремих HTTP API з різними токенами доступу та базовими URL. Плутанина між ними — типова причина того, що draft контент відображається в production або зміни не зберігаються.
Три API та їх призначення
Content Delivery API (CDA) — лише читання опублікованого контенту. Базовий URL: https://cdn.contentful.com. Токен: delivery access token (read-only, можна комітити в змінні оточення).
Content Preview API (CPA) — лише читання, але включаючи чорновики (неопубліковані записи). Базовий URL: https://preview.contentful.com. Токен: preview access token. Використовується в Next.js Draft Mode / preview mode.
Content Management API (CMA) — повний CRUD. Базовий URL: https://api.contentful.com. Токен: personal access token або OAuth. Ніколи не використовується на фронтенді.
Налаштування клієнта
import { createClient } from 'contentful';
// Для production
const deliveryClient = createClient({
space: process.env.CONTENTFUL_SPACE_ID!,
accessToken: process.env.CONTENTFUL_DELIVERY_TOKEN!,
});
// Для preview (Next.js Draft Mode)
const previewClient = createClient({
space: process.env.CONTENTFUL_SPACE_ID!,
accessToken: process.env.CONTENTFUL_PREVIEW_TOKEN!,
host: 'preview.contentful.com',
});
// Вибір клієнта за флагом
export const getClient = (preview = false) =>
preview ? previewClient : deliveryClient;
Next.js Draft Mode + Preview API
// app/api/draft/route.ts
import { draftMode } from 'next/headers';
import { redirect } from 'next/navigation';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const secret = searchParams.get('secret');
const slug = searchParams.get('slug');
if (secret !== process.env.CONTENTFUL_PREVIEW_SECRET) {
return new Response('Invalid token', { status: 401 });
}
draftMode().enable();
redirect(`/blog/${slug}`);
}
// У компоненті сторінки
import { draftMode } from 'next/headers';
export default async function BlogPost({ params }) {
const { isEnabled } = draftMode();
const client = getClient(isEnabled);
const entry = await client.getEntries({
content_type: 'blogPost',
'fields.slug': params.slug,
});
}
CMA: управління контентом програмно
import { createClient } from 'contentful-management';
const cmaClient = createClient({
accessToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN!,
});
const space = await cmaClient.getSpace(process.env.CONTENTFUL_SPACE_ID!);
const env = await space.getEnvironment('master');
// Створення запису
const entry = await env.createEntry('blogPost', {
fields: {
title: { 'en-US': 'New Post' },
slug: { 'en-US': 'new-post' },
},
});
// Публікація
await entry.publish();
Змінні оточення для всіх трьох API налаштовуються в .env.local та в CI/CD pipeline окремо для preview та production оточень.







