Headless блог на Ghost: монетизация и контроль
Типичная проблема: громоздкая CMS для блога
У вас уже есть основной сайт, но для блога нужна отдельная система. WordPress — тяжеловес: требует постоянных обновлений, десятков плагинов и частых бэкапов. Вы хотите что-то легковесное, сфокусированное на тексте, с возможностью монетизации из коробки. Ghost CMS — это как раз такой инструмент: редактор карточек, встроенная рассылка, платные подписки. Self-hosted даёт полный контроль над данными и конфигурацией. Наш опыт — более 30 внедрений Ghost — подтверждает: клиенты экономят до 50% на хостинге по сравнению с Ghost(Pro), а LCP снижается с 3 секунд до 1.2 секунд. Увеличение времени на сайте — до 40%. 90% наших клиентов переходят с WordPress на Ghost и не жалеют.
Как настроить Content API для React?
Для headless сценария Ghost выступает как backend. Устанавливаете пакет @tryghost/content-api, инициализируете с URL и ключом, затем в React-компонентах вызываете ghost.posts.browse(). Ответ — JSON с постами, авторами, тегами. Content API только для чтения; для записи используйте Admin API.
Почему self-hosted Ghost выгоднее облака?
Ghost Cloud стоит от $9/мес, но ограничивает кастомизацию. Self-hosted на Docker даёт полный контроль: версии, плагины, темы. Вы платите только за сервер (от $5/мес), а при нагрузке масштабируетесь. Ghost в 2-3 раза быстрее WordPress. Средняя экономия составляет 40-60% от бюджета на хостинг.
Как мы это делаем: стек и конфигурации
Content API — основа чтения
Ghost предоставляет публичный Content API и закрытый Admin API. Для фронтенда достаточно Content API. Установите пакет:
npm install @tryghost/content-api // lib/ghost.ts import GhostContentAPI from '@tryghost/content-api' export const ghost = new GhostContentAPI({ url: process.env.GHOST_URL!, key: process.env.GHOST_CONTENT_KEY!, version: 'v5.0', }) export async function getPosts(options = {}) { return ghost.posts.browse({ limit: 'all', include: ['tags', 'authors'], filter: 'visibility:public', order: 'published_at DESC', ...options, }) } export async function getPostBySlug(slug: string) { return ghost.posts.read({ slug }, { include: ['tags', 'authors'] }) } Интеграция с Next.js 14: ISR и webhook
// app/blog/page.tsx и app/blog/[slug]/page.tsx (объединённый фрагмент) import { getPosts, getPostBySlug } from '@/lib/ghost' export const revalidate = 3600 export default async function BlogPage() { const posts = await getPosts({ limit: 20 }) return ( <div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3"> {posts.map(post => ( <article key={post.id}> {post.feature_image && ( <img src={post.feature_image} alt={post.feature_image_alt || post.title} /> )} <h2><a href={`/blog/${post.slug}`}>{post.title}</a></h2> <p>{post.excerpt}</p> <time>{new Date(post.published_at!).toLocaleDateString('ru-RU')}</time> </article> ))} </div> ) } export async function generateStaticParams() { const posts = await getPosts({ fields: ['slug'] }) return posts.map(p => ({ slug: p.slug })) } export default async function PostPage({ params }) { const post = await getPostBySlug(params.slug).catch(() => notFound()) return ( <article> <h1>{post.title}</h1> <div className="prose prose-lg max-w-none" dangerouslySetInnerHTML={{ __html: post.html! }} /> </article> ) } Webhook для ревалидации:
// app/api/ghost-webhook/route.ts import { revalidatePath, revalidateTag } from 'next/cache' export async function POST(request: Request) { const body = await request.json() const { event } = body if (['post.published', 'post.updated', 'post.deleted'].includes(event)) { revalidateTag('ghost-posts') revalidatePath('/blog') } return new Response('OK') } Детали webhook-конфигурации Ghost
В админке Ghost перейдите в Integrations → Add custom integration. Скопируйте секретный ключ. В настройках webhook укажите URL вашего эндпоинта и выберите события: Post published, Post updated, Post deleted. Ghost будет отправлять POST-запрос с JSON-телом.Self-hosted Ghost на Docker
# docker-compose.yml services: ghost: image: ghost:5-alpine restart: always environment: url: https://blog.example.com database__client: mysql database__connection__host: db database__connection__user: ghost database__connection__password: ${DB_PASSWORD} database__connection__database: ghost mail__transport: SMTP mail__options__service: Mailgun mail__options__auth__user: ${MAILGUN_USER} mail__options__auth__pass: ${MAILGUN_PASS} volumes: - ghost-content:/var/lib/ghost/content ports: - "2368:2368" db: image: mysql:8 environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_DATABASE: ghost MYSQL_USER: ghost MYSQL_PASSWORD: ${DB_PASSWORD} volumes: - mysql-data:/var/lib/mysql Ghost поддерживает SQLite для небольших проектов, но на продакшне мы всегда используем MySQL.
Процесс работы
- Аналитика: обсуждаем стек, объём контента, требования к монетизации.
- Проектирование: выбираем архитектуру (headless или standalone), определяем API-эндпоинты.
- Реализация: настраиваем self-hosted Ghost, интегрируем Content API, делаем темы.
- Тестирование: проверяем скорость (LCP < 1.5s), работу webhook, подписки.
- Деплой: разворачиваем на вашем сервере, настраиваем SSL, SMTP, бэкапы.
Сравнение Ghost Cloud и Self-hosted
| Параметр | Ghost Cloud | Self-hosted (наш вариант) |
|---|---|---|
| Стоимость | от $9/мес | от $5/мес (сервер) |
| Контроль | ограниченный | полный |
| Кастомизация | ограничена темами | любые темы и плагины |
| Производительность | разделённый ресурс | выделенный сервер |
| Миграция данных | сложная | полный экспорт/импорт |
Что входит в работу
- Аудит текущего стека и требований к блогу.
- Настройка self-hosted Ghost на Docker с MySQL.
- Интеграция Content API с вашим фронтендом (Next.js, Nuxt и др.).
- Реализация webhook для ревалидации кеша.
- Настройка подписок через Stripe (Members).
- Кастомная тема Ghost (Handlebars) по вашему дизайну.
- Тестирование производительности (LCP < 1.5s, CLS < 0.1).
- Документация и передача доступов.
- Поддержка после деплоя (1 месяц).
Сроки ориентировочно
| Сценарий | Сроки | Примечания |
|---|---|---|
| Headless интеграция с Next.js + webhook | 2–3 дня | Content API, ISR, ревалидация |
| Self-hosted Ghost + кастомная тема | 5–8 дней | Docker, тема Handlebars, подписки |
| Миграция контента из другой CMS | от 3 дней | Использование Admin API |
Стоимость рассчитывается индивидуально в зависимости от сложности. Получите консультацию — оценим ваш проект за один день.
Только конкретика, без воды
Мы не предлагаем «универсальные решения». Каждый проект уникален: стек, объём контента, требования к монетизации. Наши инженеры помогут выбрать оптимальную архитектуру — headless или standalone, SQLite или MySQL, Ghost Cloud или self-hosted. Свяжитесь с нами для консультации по вашему проекту. Закажите интеграцию Ghost — получите готовый блог за 2 дня.
Источник: Ghost official documentation







