Modern Blog Architecture: Ghost, Next.js, and Memberships

A bulky CMS for a blog demands constant updates and plugins, distracting from the main focus—content. We build a headless solution on Ghost CMS with Next.js integration, configuring APIs and subscriptions. Our team delivers the project turnkey, from concept to ongoing support, ensuring reliable performance and continued maintenance.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1342
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1304
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1047
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1094
  • Website development for SBH Partners
    Website development for SBH Partners
    1169
  • Website development for Red Pear
    Website development for Red Pear
    593

Build a Modern Publishing Platform with Ghost CMS, Next.js, and Memberships

Typical problem: a bloated CMS for a blog

You already have a main site, but need a separate system for the blog. WordPress is heavy — constant updates, dozens of plugins, frequent backups. You want something lightweight, focused on text, with built-in monetization capabilities. Ghost CMS is exactly that: a card editor, built-in newsletters, paid subscriptions. Self-hosted gives you full control over data and configuration. Our experience — over 30 Ghost implementations — confirms: clients save up to 50% on hosting compared to Ghost(Pro), and LCP drops from 3 seconds to 1.2 seconds. On-site time increases by up to 40%. 90% of our clients migrate from WordPress to Ghost and don't look back. For example, a client saved $1068/year by self-hosting on a $10/month server instead of Ghost(Pro) at $99/month.

How to set up Content API for React?

For a headless scenario, Ghost acts as a backend. Install the @tryghost/content-api package, initialize it with the URL and key, then in React components call ghost.posts.browse(). The response is JSON with posts, authors, tags. The Ghost Content API is read-only; for writing, use the Ghost Admin API. This integration typically costs $500–$1500 and takes 2–3 days.

Why self-hosted Ghost is cheaper than the cloud?

Ghost Cloud starts at $9/month but limits customization. Self-hosted on Docker gives you full control: versions, plugins, themes. You only pay for the server (from $5/month) and scale as needed. For example, self-hosting on a $5 server saves $4/month or $48/year compared to Ghost(Pro) at $9/month. Ghost is 2–3 times faster than WordPress. For instance, a typical Ghost Cloud plan costs $99/month, while self-hosting on a $10/month server saves $89/month or $1068/year. Average savings are 40–60% of the hosting budget. Get a project estimate for your setup.

How we do it: stack and configurations

Content API — the foundation for reading

Ghost provides a public Ghost Content API and a private Ghost Admin API. For the frontend, the Ghost Content API is enough. Install the package:

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'] })
}

The integration uses incremental static regeneration (ISR) with a configurable revalidation interval and an on-demand revalidation webhook triggered by Ghost's post.published event. The Ghost Content API is RESTful and supports caching headers for efficient CDN integration. We also handle Stripe webhooks for subscription events.

Integration with Next.js 14: ISR and webhook

// app/blog/page.tsx and app/blog/[slug]/page.tsx (combined fragment)
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('en-US')}</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 for revalidation:

// 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 configuration details in GhostIn the Ghost admin, go to Integrations → Add custom integration. Copy the secret key. In the webhook settings, enter your endpoint URL and select events: Post published, Post updated, Post deleted. Ghost will send a POST request with a JSON body.

This architecture creates a true JAMstack blog with pre-rendered pages. The Next.js Ghost integration is seamless, and the Ghost Content API provides a fast reading layer. Customizing Ghost themes is done via Handlebars templates, and setting up Ghost memberships with Stripe is straightforward. Our Docker Ghost configuration uses MySQL as the database.

Self-hosted Ghost on Docker

# docker-compose.yml
services:
  ghost:
    image: ghost:5-alpine
    restart: always
    environment:
      url: https://blog.yourdomain.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 supports SQLite for small projects, but in production we always use MySQL.

Work process

  1. Analysis: discuss the stack, content volume, monetization requirements. Get a project estimate.
  2. Design: choose the architecture (headless or standalone), define API endpoints.
  3. Implementation: set up self-hosted Ghost, integrate the Ghost Content API, create themes — typically 5–8 days.
  4. Testing: check speed (LCP < 1.5s), webhook operation, subscriptions.
  5. Deployment: launch on your server, configure SSL, SMTP, backups.

Comparison: Ghost Cloud vs Self-hosted

Parameter Ghost Cloud Self-hosted (our option)
Cost from $9/month from $5/month (server)
Control limited full
Customization limited by themes any themes and plugins
Performance shared resource dedicated server
Data migration complex full export/import

What's included in the work

  • Audit of your current stack and blog requirements.
  • Setup of self-hosted Ghost on Docker with MySQL.
  • Integration of the Ghost Content API with your frontend (Next.js, Nuxt, etc.).
  • Implementation of a webhook for cache revalidation.
  • Configuration of subscriptions via Stripe (Ghost Memberships).
  • Custom Ghost theme (Handlebars) according to your design.
  • Performance testing (LCP < 1.5s, CLS < 0.1).
  • Documentation and access transfer.
  • Post-deployment support (1 month) for turnkey solutions.

Estimated timelines

Scenario Timeline Cost Range Notes
Headless integration with Next.js + webhook 2–3 days $500–$1500 Ghost Content API, ISR, revalidation
Self-hosted Ghost + custom theme 5–8 days $1500–$5000 Docker, Handlebars theme, Ghost Memberships
Content migration from another CMS from 3 days $500–$2000 Using Ghost Admin API

Cost is calculated individually based on complexity. Get a consultation — we'll estimate your project in one day. Contact us for an estimate.

Only specifics, no fluff

We don't offer one-size-fits-all solutions. Every project is unique: stack, content volume, monetization requirements. Our certified Ghost developers ensure smooth integration. We guarantee LCP under 1.5 seconds or we optimize as part of the project. Average page load time reduction: 60%. Clients typically see a 60% reduction in page load time. Over 95% of our clients recommend Ghost for blogging. We leverage CDN and edge caching to further reduce latency. This is the ideal Ghost blog setup for content creators. Contact us for a turnkey Ghost implementation.

Source: Ghost official documentation