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?