Интеграция CMS Prismic для управления контентом
Prismic — headless CMS с визуальным конструктором слайсов. Редакторы собирают страницы из переиспользуемых блоков, разработчики получают типизированный контент через REST или GraphQL API. Подходит для маркетинговых сайтов, лендингов и блогов, где контент меняется часто, а деплоить ради правки текста не хочется.
Что входит в интеграцию
Стандартная работа покрывает: настройку репозитория Prismic, проектирование Custom Types и слайсов, интеграцию SDK в существующий проект, настройку Preview и webhook-ов для ребилда.
Проектирование модели контента
Типы в Prismic делятся на Single (одна запись — главная страница, настройки) и Repeatable (коллекция — статьи, кейсы).
Слайсы — это переиспользуемые секции. Один слайс hero можно подключить к нескольким типам. Вся модель версионируется в JSON:
{
"Main": {
"uid": { "type": "UID", "config": { "label": "URL slug" } },
"title": { "type": "StructuredText", "config": { "single": "heading1" } },
"body": { "type": "Slices", "fieldset": "Slice Zone", "config": {
"choices": {
"hero": { "type": "SharedSlice" },
"text_block": { "type": "SharedSlice" },
"image_gallery": { "type": "SharedSlice" }
}
}}
}
}
Этот JSON коммитится в репозиторий и деплоится через Prismic CLI — никаких ручных кликов в UI.
Установка и настройка SDK
npm install @prismicio/client @prismicio/react @prismicio/next
npx @slicemachine/init
slicemachine/init создаёт slicemachine.config.json и базовую структуру папок. Для Next.js 14+ конфиг выглядит так:
// prismicio.ts
import * as prismic from '@prismicio/client'
import { CreateClientConfig, enableAutoPreviews } from '@prismicio/next'
export const repositoryName = process.env.PRISMIC_REPOSITORY_NAME!
export function createClient(config: CreateClientConfig = {}) {
const client = prismic.createClient(repositoryName, {
accessToken: process.env.PRISMIC_ACCESS_TOKEN,
routes: [
{ type: 'page', path: '/:uid' },
{ type: 'blog_post', path: '/blog/:uid' },
],
...config,
})
enableAutoPreviews({ client, previewData: config.previewData, req: config.req })
return client
}
Запросы к API
Prismic предоставляет как REST, так и GraphQL. Для большинства задач REST через SDK удобнее:
// app/[uid]/page.tsx
import { createClient } from '@/prismicio'
import { notFound } from 'next/navigation'
export default async function Page({ params }: { params: { uid: string } }) {
const client = createClient()
const page = await client
.getByUID('page', params.uid)
.catch(() => notFound())
return <SliceZone slices={page.data.body} components={components} />
}
export async function generateStaticParams() {
const client = createClient()
const pages = await client.getAllByType('page')
return pages.map(p => ({ uid: p.uid }))
}
Для GraphQL — когда нужно подтянуть связанные документы в одном запросе:
{
allBlog_posts(sortBy: publish_date_DESC, first: 10) {
edges {
node {
_meta { uid }
title
cover_image
author {
... on Author {
name
avatar
}
}
}
}
}
}
Preview и Draft
Редактор хочет видеть изменения до публикации. Prismic поддерживает Draft через Preview:
// app/api/preview/route.ts
import { redirectToPreviewURL } from '@prismicio/next'
import { createClient } from '@/prismicio'
export async function GET(request: Request) {
const client = createClient()
return redirectToPreviewURL({ client, request })
}
В Prismic Dashboard указываем Preview URL: https://site.com/api/preview. После нажатия «Preview» редактор попадает на сайт с куками — Next.js рендерит черновик.
Webhook и ISR
При публикации Prismic дёргает webhook. Для Next.js это сброс кэша:
// app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache'
export async function POST(request: Request) {
const secret = request.headers.get('x-prismic-secret')
if (secret !== process.env.PRISMIC_WEBHOOK_SECRET) {
return new Response('Unauthorized', { status: 401 })
}
revalidateTag('prismic')
return new Response('Revalidated')
}
Все запросы к Prismic помечаются тегом prismic через fetch options — сброс точечный, не полный ребилд.
Slice Machine и локальная разработка
Slice Machine — локальный UI для создания слайсов. Запускается рядом с dev-сервером:
npm run slicemachine # порт 9999
npm run dev # порт 3000
Каждый слайс — это папка с index.tsx, model.json и Stories для Storybook. Модель синхронизируется в Prismic одной командой:
npx prismic-ts-codegen # генерирует TypeScript типы из моделей
После этого все поля слайсов типизированы — опечатка в названии поля поймается на этапе сборки.
Типичные сложности
Связанные документы — Prismic не делает join автоматически. Если в статье есть поле author (Link), его нужно явно разрешить:
const post = await client.getByUID('blog_post', uid, {
fetchLinks: ['author.name', 'author.avatar'],
})
Либо использовать graphQuery для более сложных структур.
Локализация — каждый язык это отдельный документ. При запросе нужно передавать lang:
const page = await client.getByUID('page', uid, { lang: 'ru' })
Порядок миграции контента — если модель уже есть в другой CMS, используем Prismic Migration API для программного создания документов, а не ручной ввод.
Сроки
Базовая интеграция (до 5 типов контента, без кастомных слайсов): 3–5 дней. С проектированием модели контента, миграцией данных и настройкой Preview: 1–2 недели в зависимости от объёма.







