Back to Blog
Next.jsMDXSSGWebhookCachingContent Architecture

Next.js Content Architecture: Loading, Caching, and Revalidation with GitHub, MDX, and Webhooks

A practical guide to building a Next.js content system with GitHub, MDX, SSG, caching, and Webhooks, including a pattern for partial pre-rendering with authenticated full-content loading.

RaytonX
4 min read

When building content-driven products (courses, documentation, blogs), several common challenges usually come up:

  • Where should content live? Database or files?
  • How do we balance SEO and access control?
  • Do content updates require redeployment?
  • How do we avoid exposing the data source to the client?

In this article, we share a practical approach we use in real projects:

Using GitHub + Next.js + MDX to support SSG previews with authenticated full content loading

This setup helps teams keep content workflows flexible without giving up SEO, performance, or access control.


Core Idea

The overall architecture can be broken down into four layers:

  • GitHub: content storage (private repository)
  • Server layer: content fetching, caching, and access control
  • SSG pages: pre-rendered preview content
  • Client: loads full content after authentication

The key principle is:

GitHub acts only as a data source and is never exposed directly to the client.


1. Content Source: GitHub API

All content is stored in a private GitHub repository (in MDX format) and fetched via the GitHub API, instead of being downloaded at build time.

This approach provides several benefits:

  • Content updates do not require redeployment
  • Full Git workflow support (PRs, version history)
  • Content repository can be maintained independently

At the lowest level, a loadMdx function is responsible for fetching raw MDX content from GitHub.


2. Unified Content Layer

Instead of letting pages, APIs, and caching logic access GitHub directly, we introduce a unified content service layer.

For example:

  • getLessonContent

This layer is responsible for:

  • Combining metadata and content
  • Providing a single entry point for content access
  • Handling caching logic

Both:

  • SSG page rendering
  • Content API responses

depend on this layer.


3. SSG Rendering: Preview Content Only

Pages are statically generated (SSG) during build time, but only render partial content.

This serves two purposes:

  • Initial page load performance
  • SEO indexing

This design allows us to keep the benefits of SSG while still supporting gated content.


4. Loading Full Content After Login

The full content is not included in the SSG output.

After authentication, the client requests an internal API to retrieve the full content:

  • The server validates authentication
  • Calls the content service (usually hitting cache)
  • Returns the complete MDX

Importantly:

The client never directly calls the GitHub API

This ensures:

  • No exposure of access tokens
  • Proper access control on the server side
  • Decoupling from the external data source

5. Caching and Content Updates

To avoid hitting GitHub on every request, content is cached at the server layer.

We use Next.js caching features:

  • cache for memoization
  • tag for grouping content

When content is updated, a Webhook triggers cache invalidation:

  1. GitHub repository receives a push
  2. Webhook is triggered
  3. Calls /content-revalidate
  4. The server executes:
    • revalidateTag to refresh cached content
    • revalidatePath to refresh affected pages

This allows content updates without redeployment.


6. Limitation: New Pages

One important limitation:

revalidate cannot generate new SSG pages

This means:

  • Existing pages → can be updated
  • New routes/pages → will not be statically generated automatically

If new content needs to be included in SSG, a redeployment is still required.


Recommended Strategy

In practice, we combine both approaches:

  • Content updates → Webhook + revalidate
  • New routes → trigger deployment

This balances flexibility and stability.


Summary

This approach is essentially a combination of:

SSG + Content API + Caching + Webhook

It addresses several key challenges:

  • Content updates without redeployment
  • Preserving SEO and performance via SSG
  • Supporting authenticated access to full content
  • Avoiding direct exposure of the data source to the client

If you're interested in the implementation details (such as content loading, caching strategies, and Webhook handling), you can explore the project directly:

https://github.com/raytonx-labs/raytonx-learn