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 сьогодні.







