0

I know it's an unconventional pairing, but I am using Next.js and the Laravel stack for my app.

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Blog extends Model
{
    use HasFactory;
    
    protected $guarded = [];

    // This should work for route model binding
    public function getRouteKeyName()
    {
        return 'slug';
    }

api.php

Route::apiResource('/blogs',BlogController::class)->only(['index','show','store','destroy']);

Controller:

public function show(Blog $blog) // ← Change parameter name to match resource
{
    return new BlogResource($blog);
}

page.tsx

import Image from "next/image";
async function getBlog(slug) {
  const baseUrl = process.env.APP_URL ?? "http://127.0.0.1:8000";
  const url = `${baseUrl}/api/blogs/${slug}`;

  console.log('🔄 Fetching from URL:', url); // Debug 1

  try {
    const response = await fetch(url, {
      headers: {
        "Accept": "application/json",
        "Content-Type": "application/json",
      },
      cache: "no-store",
    });

    console.log('📡 Response status:', response.status); // Debug 2
    console.log('📡 Response ok:', response.ok); // Debug 3

    if (!response.ok) {
      const errorText = await response.text();
      console.error('❌ HTTP Error:', response.status, errorText);
      throw new Error(`Failed to fetch blog: ${response.status} ${response.statusText}`);
    }

    const result = await response.json();
    console.log('📦 Full API result:', result); // Debug 4
    console.log('📦 Data property:', result.data); // Debug 5
    
    return result.data;
    
  } catch (error) {
    console.error('💥 [getBlog] Fetch error:', error);  
    return null;
  }
}

export default async function BlogPage({ params }) {
  const { slug } = params;
  const blog = await getBlog(slug);

  if (!blog) {
    return (
      <div className="container mx-auto py-16">
        <p className="text-red-500 text-xl">Blog not found</p>
      </div>
    );
  }

  return (
    <div className="w-full mx-auto">
      <div className="flex justify-start items-start mx-auto">
        <div className="lg:w-9/12 w-full flex flex-col text-white font-montserrat text-[20px] mt-[100px] ml-[50px]">

          {/* Blog Title */}
          <h1 className="text-4xl font-ebGaramond font-bold mb-6">
            {blog.title}
          </h1>

          {/* Blog Thumbnail */}
          {blog.thumbnail && (
            <Image
              src={blog.thumbnail} // Use the full URL directly
              width={1000}
              height={500}
              alt={blog.title}
              className="rounded-lg object-cover mb-8"
            />
          )}

          {/* Blog Body */}
          <div
            dangerouslySetInnerHTML={{ __html: blog.body }}
          />

          {/* Button */}
          <div className="mt-10 flex">
            <button
              className="
                bg-[#2c96e2]
                text-white
                font-ebGaramond
                text-[32px]
                font-bold
                w-[423px]
                h-[71px]
                rounded-[8px]
                mt-[100px]
                mb-[100px]
                hover:bg-[#193155]
                transition
              "
            >
              Request Quotation
            </button>
          </div>

        </div>
      </div>
    </div>
  );
}

The problem is that it's returning the error: Blog not found. When I try to access the blog from the backend through localhost:8000, I can access it. Just not the frontend. Which tells me it's an issue with the route model binding, because I am trying to access the blog through the slug. Does anyone have any quick fixes?

1 Answer 1

1
export default async function BlogPage({ params }: { params: Promise<{ slug: string }> }) {
  // Await the params promise
  const { slug } = await params;
  console.log('🔍 Slug:', slug);
  
  const blog = await getBlog(slug);

  if (!blog) {
    return (
      <div className="container mx-auto py-16">
        <p className="text-red-500 text-xl">Blog not found</p>
        <p className="text-gray-500">Slug: {slug}</p>
      </div>
    );
  }

figured the issue was with how I was getting the BlogPage params

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, this is correct.. Here is the source: nextjs.org/docs/messages/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.