Upgrade & Secure Your Future with DevOps, SRE, DevSecOps, MLOps!

We spend hours on Instagram and YouTube and waste money on coffee and fast food, but won’t spend 30 minutes a day learning skills to boost our careers.
Master in DevOps, SRE, DevSecOps & MLOps!

Learn from Guru Rajesh Kumar and double your salary in just one year.

Get Started Now!

How to Show Flarum Discussions on a Laravel Website

Modern websites often need to display content from multiple platforms on a single homepage. A common example is showing WordPress blog posts or community discussions directly on a Laravel-based site without breaking layout or performance.

In this article, we’ll explain the best and most stable approach to fetch and display Flarum discussions on a Laravel website, using the same concept as WordPress blog fetch, but implemented correctly for production use.

This guide covers:

  • Why backend proxy is the best approach
  • How Flarum API works
  • Step-by-step Laravel + JavaScript integration
  • Clean UI rendering with fail-safe handling

Why Not Fetch Flarum Directly from Frontend?

Flarum provides a JSON:API endpoint, so technically you can fetch discussions directly using JavaScript. However, this approach causes multiple problems in real-world projects:

  • CORS issues (very common)
  • ❌ API rate limits exposed to users
  • ❌ Authentication tokens exposed in frontend
  • ❌ No caching → slow homepage
  • ❌ API failure breaks UI

Because of this, direct frontend fetch is not recommended for production.


Best Practice: Laravel Backend Proxy (Recommended)

The best and safest approach is:

Laravel Backend → Fetch Flarum API → Convert to simple JSON → Frontend JS renders UI

Benefits:

  • ✅ No CORS problems
  • ✅ API tokens stay secure
  • ✅ Easy caching (faster homepage)
  • ✅ Clean error handling
  • ✅ Same pattern as WordPress blog fetch

Step 1: Understand the Flarum API Endpoint

Flarum exposes discussions using JSON:API:

GET https://your-flarum-site.com/api/discussions

Common parameters:

  • page[limit]=9 → number of discussions
  • sort=-createdAt → latest discussions first
  • include=user,tags → include author and tags

Example:

/api/discussions?page[limit]=9&sort=-createdAt&include=user,tags

The response is nested and complex, so we will simplify it in Laravel.


Step 2: Configure Flarum in Laravel

Add Flarum configuration in config/services.php:

'flarum' => [
    'base_url' => env('FLARUM_BASE_URL'),
    'api_token' => env('FLARUM_API_TOKEN'), // optional
],

Add values in .env:

FLARUM_BASE_URL=https://community.example.com
FLARUM_API_TOKEN=

If discussions are public, API token is not required.


Step 3: Create a Laravel Proxy Route

Create a route that your frontend will call instead of calling Flarum directly.

Route::get('/flarum/discussions', [FlarumController::class, 'discussions'])
    ->name('flarum.discussions');

Step 4: Fetch and Normalize Flarum Data (Controller)

Create a controller that:

  • Calls Flarum API
  • Extracts only required fields
  • Returns clean JSON
  • Caches the response
class FlarumController extends Controller
{
    public function discussions(Request $request)
    {
        $limit = min((int) $request->limit ?: 9, 12);

        return Cache::remember("flarum_discussions_$limit", now()->addMinutes(5), function () use ($limit) {

            $base = rtrim(config('services.flarum.base_url'), '/');

            $response = Http::acceptJson()
                ->get($base . '/api/discussions', [
                    'page' => ['limit' => $limit],
                    'sort' => '-createdAt',
                    'include' => 'user,tags',
                ]);

            if (!$response->ok()) {
                return ['success' => false, 'items' => []];
            }

            $json = $response->json();
            $included = collect($json['included'] ?? []);

            $users = $included->where('type', 'users')->keyBy('id');
            $tags  = $included->where('type', 'tags')->keyBy('id');

            $items = [];

            foreach ($json['data'] as $d) {
                $authorId = data_get($d, 'relationships.user.data.id');
                $author   = $users[$authorId]['attributes'] ?? [];

                $items[] = [
                    'title' => $d['attributes']['title'],
                    'link'  => $base.'/d/'.$d['attributes']['slug'],
                    'created_at' => $d['attributes']['createdAt'],
                    'reply_count' => $d['attributes']['replyCount'],
                    'author' => $author['displayName'] ?? $author['username'],
                ];
            }

            return ['success' => true, 'items' => $items];
        });
    }
}

Step 5: Create Blade Section for Discussions

Add a section similar to WordPress blog cards:

<div id="flarum-discussions" style="display:none;">
    <div id="flarum-loading">Loading discussions...</div>
    <div id="flarum-grid"></div>
</div>

Step 6: Fetch Discussions Using JavaScript

Now fetch discussions from your Laravel route, not from Flarum directly.

<script>
document.addEventListener("DOMContentLoaded", async () => {

  const section = document.getElementById("flarum-discussions");
  const loading = document.getElementById("flarum-loading");
  const grid    = document.getElementById("flarum-grid");

  section.style.display = "block";

  try {
    const res = await fetch("/flarum/discussions?limit=9");
    const data = await res.json();

    if (!data.success || !data.items.length) throw "No data";

    let html = "";
    data.items.forEach(d => {
      html += `
        <div class="discussion-card">
          <a href="${d.link}" target="_blank">
            <h5>${d.title}</h5>
            <p>By ${d.author} • ${d.reply_count} replies</p>
          </a>
        </div>
      `;
    });

    grid.innerHTML = html;
    loading.style.display = "none";

  } catch (e) {
    section.style.display = "none";
  }
});
</script>

Step 7: Fail-Safe Handling (Very Important)

If:

  • Flarum is down
  • API fails
  • Network error occurs

👉 The entire section hides automatically, so your homepage never breaks.


Final Architecture Overview

Frontend JS
    ↓
Laravel Proxy Route
    ↓
Flarum JSON API
    ↓
Laravel Normalization + Cache
    ↓
Clean JSON to Frontend

Conclusion

If you want to show Flarum discussions on a Laravel website using the same concept as WordPress blog fetch, the Laravel backend proxy approach is the most professional and production-ready solution.

It ensures:

  • Better performance
  • Strong security
  • Clean UI rendering
  • No CORS headaches
  • Scalable architecture

This pattern works perfectly for:

  • Communities
  • SaaS dashboards
  • Blogs + forums combo
  • Multi-platform content sites

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Artificial Intelligence
0
Would love your thoughts, please comment.x
()
x