How I Connected Next.js 16 with Joomla 6 as a Headless CMS (Real Project Case Study)

nextjs joomla headless cms

The Problem: Static Website with No CMS

A client had a clean, fast static website.

Everything looked good.

But there was one missing piece.

They needed a blog.

Not just a simple page. A proper system where they could:

  • Log in securely
  • Add new articles
  • Manage categories
  • Update content anytime

Building a CMS from scratch would take time.

And honestly, it didn’t make sense.

So I looked for a smarter approach.

The Idea: Use Joomla as a Headless CMS

Instead of building something new, I used Joomla as the backend.

No frontend.

No templates.

Just content management.

Then I connected it to Next.js.

This gave me:

  • A ready-to-use admin panel
  • Secure authentication
  • API access to content
  • A fast frontend

The result was simple and powerful.

Final Architecture

Here’s what I built:

  • Main website → clientsite.com using Next.js
  • Blog section → /blog (dynamic)
  • Joomla backend → joomla.clientsite.com

Joomla handles:

  • Content creation
  • Content storage
  • API responses

Next.js handles:

  • UI
  • Routing
  • Rendering

This separation makes everything cleaner.

Step 1: Install Joomla 6 on a Subdomain

Create a subdomain like:

  • joomla.clientsite.com
  • or api.clientsite.com

Install a clean Joomla 6 setup.

Then simplify it:

  • Disable frontend modules
  • Ignore templates
  • Use it only for managing content

Think of it as a backend dashboard, not a website.

Step 2: Enable Joomla Web Services API

Joomla 4+ comes with built-in Web Services.

Go to Plugins and enable:

  • Web Services – Content
  • API Authentication

Once enabled, your API is live.

Example endpoint:

https://joomla.clientsite.com/api/index.php/v1/content/articles

Step 3: Generate Authentication Token

Joomla supports token-based authentication.

Steps:

  • Go to Users
  • Open your user profile
  • Generate API token

Now every API request can be secured.

Example header:

Authorization: Bearer YOUR_API_TOKEN

Step 4: Fetch Articles from Joomla API

Use the API to fetch content.

Example request:

GET https://joomla.clientsite.com/api/index.php/v1/content/articles

The response includes:

  • Title
  • Slug
  • Content
  • Categories
  • Metadata

Everything needed to render a blog.

Step 5: Connect Next.js 16 (App Router)

In Next.js, I used App Router with native fetch.

Here’s a simple example:

export async function getArticles() {
  const res = await fetch(
    "https://joomla.clientsite.com/api/index.php/v1/content/articles",
    {
      headers: {
        Authorization: "Bearer YOUR_API_TOKEN",
      },
      cache: "no-store",
    }
  );

  if (!res.ok) {
    throw new Error("Failed to fetch articles");
  }

  return res.json();
}

This pulls data directly from Joomla.

Step 6: Render Blog Page

Now create your blog listing page:

export default async function BlogPage() {
  const data = await getArticles();

  return (
    <div>
      {data.data.map((article) => (
        <div key={article.id}>
          <h2>{article.attributes.title}</h2>
        </div>
      ))}
    </div>
  );
}

Clean and simple.

Step 7: Create Dynamic Blog Pages

Use slugs from Joomla.

export async function generateStaticParams() {
  const data = await getArticles();

  return data.data.map((article) => ({
    slug: article.attributes.alias,
  }));
}

Now each article becomes:

/blog/my-article-slug

Fully dynamic.

Important: Avoid Duplicate Content

This step is critical.

Your Joomla backend is public.

So the same content exists in two places:

  • Joomla URLs
  • Next.js blog pages

This creates duplicate content.

Fix it:

Go to Joomla Global Configuration and set:

  • Robots → noindex

This ensures only your Next.js site gets indexed.

Why I Didn’t Use WordPress

You might ask:

Why not use WordPress?

It has an API:

/wp-json/wp/v2/posts

And yes, it works.

But here’s the reality.

How WordPress Works in Headless Mode

By default:

  • API is public
  • No authentication required
  • Anyone can access your content

Example:

https://example.com/wp-json/wp/v2/posts

You get everything instantly.

The Limitations

Authentication is not strict by default

To secure it, you need:

  • Application passwords
  • JWT plugins
  • OAuth setups

This adds complexity.

Plugin dependency

For real projects, you often need:

  • ACF for custom fields
  • Authentication plugins
  • API extensions

More plugins means:

  • More maintenance
  • More risks

Less control over API behavior

Customizing APIs requires:

  • Hooks
  • Filters
  • Custom coding

It’s flexible, but not clean.

Larger attack surface

Because of its popularity:

  • More bots target it
  • Plugin vulnerabilities are common
  • APIs are often exposed

Why Joomla Worked Better

With Joomla, things were straightforward.

  • API is structured
  • Authentication is built-in
  • No extra plugins needed
  • Better control over access

It gave me:

  • A secure backend
  • Clean API integration
  • Less maintenance

Performance Benefits

This setup is fast.

Because:

  • Main site is static
  • Blog is dynamic only where needed
  • API calls are lightweight

This improves:

  • Load speed
  • SEO
  • User experience

Pros of Using Joomla as Headless CMS

  • No need to build CMS
  • Secure admin panel
  • Built-in API
  • Easy for clients
  • Works well with modern frameworks
  • Scalable

Cons You Should Know

  • Requires initial setup understanding
  • API is less beginner-friendly
  • Token handling required
  • Joomla UI may feel heavy for small tasks

When You Should Use This Approach

Use it when:

  • You have a static site
  • You need dynamic blog content
  • You want a secure backend
  • You want to save development time

Avoid it when:

  • You need full CMS-driven frontend
  • You want everything in one system

Final Thoughts

This setup worked perfectly.

The client got:

  • A fast website
  • A simple backend
  • Full control over content

And I avoided building a CMS from scratch.

Sometimes the smartest solution is not building more.

It’s choosing better tools.

If you’re working with Next.js and need a CMS, give Joomla headless a try.