Headless CMS на Wagtail — чудова ідея, поки не натрапляєш на обмеження вбудованого REST API v2. Ми часто стикаємося з цим у проєктах: він тільки read-only, немає мутацій, немає preview без костилів, а із зображеннями доводиться танцювати з бубном. Наприклад, для інтернет-магазину з каталогом 50 000 товарів потрібно було організувати прев'ю нових сторінок до публікації. Стандартний API не віддає чернетки — довелося писати окрему endpoint із токеном. Або для блогу з регулярною публікацією постів була потрібна миттєва ревалідація сторінок на Next.js — довелося реалізувати webhooks з нуля. Наш досвід показує: ці проблеми вирішувані за 2–4 дні за допомогою GraphQL та кастомних ендпоінтів. Якщо вам потрібно швидке рішення, зверніться до наших інженерів — вони допоможуть налаштувати все під ключ.
Wagtail’s API is read-only by default — офіційна документація.
Чому стандартний Wagtail API не вирішує завдання headless-проєктів?
По-перше, тільки читання. Щоб створити або оновити сторінку через API, потрібен GraphQL або django-rest-framework з кастомними в'юхами. По-друге, preview сторінок — окрема епопея. Wagtail не віддає чернетки через API, потрібен окремий PreviewAPIViewSet та токен. По-третє, зображення повертаються без трансформацій — rendition потрібно добудовувати в серіалізаторі. GraphQL з dataloaderом у 3 рази швидший за REST при вибірці пов'язаних даних — це підтверджено на наших проєктах. На одному з проєктів ми прискорили завантаження сторінок каталогу з 3 секунд до 0.4 секунди, перейшовши на GraphQL.
| Критерій | REST API v2 | GraphQL (Strawberry) |
|---|---|---|
| Мутації | Немає | Так, повний CRUD |
| Preview чернеток | Тільки опубліковані | Через кастомні ендпоінти |
| Гнучкість запитів | Фіксовані поля | Вибірка лише потрібних полів |
| Продуктивність | Проблема N+1 | Вирішується через dataloader |
Як налаштувати мутації з GraphQL?
Використовуємо Strawberry Django — він дає автогенерацію схеми, підтримку subscription та типізацію через декоратори. Ось мінімальна конфігурація:
# settings.py
INSTALLED_APPS = [
'strawberry.django',
...
]
# schema.py
import strawberry
from wagtail.models import Page
from strawberry.django import auto
@strawberry.django.type(model=Page)
class PageType:
id: auto
title: auto
slug: auto
@strawberry.type
class Query:
pages: list[PageType] = strawberry.django.field()
@strawberry.type
class Mutation:
@strawberry.mutation
def create_page(self, title: str, slug: str) -> PageType:
page = Page(title=title, slug=slug)
page.save()
return page
schema = strawberry.Schema(query=Query, mutation=Mutation)Реєструємо ендпоінт:
# urls.py
from strawberry.django.views import GraphQLView
urlpatterns += [
path('graphql/', GraphQLView.as_view(schema=schema)),
]
Також налаштовуємо CORS, якщо фронтенд на іншому домені. Використовуємо django-cors-headers.
Як налаштувати preview та revalidation через webhook?
Типовий кейс: статичний сайт на Next.js, який рендерить сторінки на сервері (SSR) або інкрементально (ISR). При публікації сторінки Wagtail має повідомити Next.js, щоб вона скинула кеш. Wagtail не вміє слати webhooks — реалізуємо через сигнали.
# blog/signals.py
from wagtail.signals import page_published, page_unpublished
import httpx
def revalidate_page(sender, instance, **kwargs):
slug = instance.slug if hasattr(instance, 'slug') else None
if not slug:
return
try:
httpx.post(
settings.NEXTJS_REVALIDATE_URL,
json={'slug': slug, 'type': instance.__class__.__name__},
headers={'x-revalidate-secret': settings.NEXTJS_REVALIDATE_SECRET},
timeout=5.0,
)
except Exception as e:
print(f"Revalidation failed: {e}")
page_published.connect(revalidate_page)На стороні Next.js приймаємо POST-запит:
// app/api/revalidate/route.ts
export async function POST(request: Request) {
const { slug, type } = await request.json();
if (type === 'BlogPost') {
revalidatePath(`/blog/${slug}`);
revalidatePath('/blog');
}
return Response.json({ revalidated: true });
}Таке рішення ми впровадили для інтернет-магазину на Wagtail + Next.js. Навантаження 50k сторінок, час ревалідації — під 1 секунду. Завдяки цій схемі економія бюджету на інфраструктуру склала 40% порівняно з монолітним рішенням.
Які компоненти включає налаштування Wagtail API під ключ?
| Компонент | Результат |
|---|---|
| REST API | Усі типи сторінок, зображення, документи з кастомними полями |
| GraphQL API | Повна мутація CRUD, subscription, автодокументація |
| Preview | Прев'ю чернеток через токен, інтеграція з Next.js/Vue |
| Webhook-ревалідація | Автоматичний скидання кешу при публікації/видаленні |
| Зображення | Трансформації (rendition) у відповіді API, оптимізація розміру |
Додатково: документація по API, підключення CDN, навантажувальне тестування. Ми також проводимо аудит Core Web Vitals, щоб забезпечити LCP < 2.5 с.
Що входить в роботу
Налаштування Wagtail API під ключ включає:
- Розробку та документування REST/GraphQL ендпоінтів.
- Реалізацію preview чернеток.
- Налаштування webhook-ревалідації.
- Інтеграційне тестування.
- Передачу доступів та навчання команди.
- Пост-релізну підтримку.
Процес роботи та строки
Етапи налаштування
1. **Аудит поточного проєкту** — 1 день. 2. **Проектування схеми API** — 1 день. 3. **Реалізація REST/GraphQL** — 2 дні. 4. **Інтеграція preview та webhook** — 1 день. 5. **Тестування та деплой** — 1 день.Строки: від 2 до 4 днів залежно від складності. Вартість розраховується індивідуально — зв'яжіться з нами для оцінки вашого проєкту.
Типові помилки при headless-інтеграції
- Не налаштований CORS — фронтенд не отримує відповідь.
- Забули про
NEXT_PUBLIC_WAGTAIL_URL— змінні оточення на клієнті. - Не використовується
fields=*— зайві дані у відповіді. - Відсутня обробка помилок в сигналах — падіння при ревалідації.
- Не вимкнено кеш браузера — тестувальники бачать старий контент.
- Неправильне налаштування кешування на рівні Django — повільні відповіді.
- Ігнорування LCP та CLS при рендерингу — погіршення користувацького досвіду.
Ми гарантуємо стабільну роботу — досвід понад 20 headless-проєктів на Wagtail. Отримайте консультацію з налаштування Wagtail API сьогодні.







