I want to make a dynamic meta data for my blog pages. #82115
-
Below is my code what I'm using. import { notFound } from 'next/navigation'
import { Metadata, ResolvingMetadata } from 'next'
import { IndividualBlogData } from '@/constants/Blogspage/IndividualBlog'
import SideBar from '@/components/Blog/Individual/SideBar'
import ImageComponent from '@/components/ui/Image'
import BlogScrollSection from '@/components/Blog/Individual/MainContent'
// import { IndividualBlogType } from '@/types/types'
type Props = {
params: { blogName: string }
searchParams?: { [key: string]: string | string[] | undefined }
}
// ✅ Dynamic metadata generation using async pattern
export async function generateMetadata(
{ params }: Props,
_parent: ResolvingMetadata
): Promise<Metadata> {
const blog = IndividualBlogData.find(blog => blog.name === params.blogName)
if (!blog) {
return { title: 'Not Found' }
}
return {
title: blog.metaTitle,
description: blog.description,
openGraph: {
title: blog.metaTitle,
description: blog.description,
images: [blog.img || ''],
},
metadataBase: new URL('https://reverfin.vercel.app'), // optional
}
}
// ✅ Page component using proper param typing
export default async function BlogPage({ params }: Props) {
const blog = IndividualBlogData.find(blog => blog.name === params.blogName)
if (!blog) notFound()
return (
<main>
<div className='w-full flex items-center justify-center flex-col'>
<div className='w-full max-w-[100rem] px-12 pt-16'>
<div className='border-x border-primary-500 px-10 py-16 flex items-center justify-center'>
<div className='max-w-[75rem] w-full'>
<div className='flex items-start justify-start flex-col gap-8'>
<div>
<div className='font-ppMori text-[14px] border border-primary-400 bg-primary-800 rounded-full px-4 py-1 w-max'>
<p className='mt-0.5'>{blog.category}</p>
</div>
</div>
<p className='text-4xl font-alliance'>{blog.title}</p>
<div>
<p className='text-sm font-ppMori'>{blog.date}</p>
</div>
</div>
{blog.img && (
<div className='-mt-4'>
<ImageComponent
alt={blog.name}
fill
loading='lazy'
className='relative w-full aspect-video'
src={blog.img}
/>
</div>
)}
<div className='flex items-start justify-start flex-row gap-10'>
<div className='sticky top-20 min-w-72'>
<p className='font-alliance text-xl mb-5'>Table of content</p>
<SideBar content={blog.sideContent} />
</div>
<div>
<BlogScrollSection content={blog.mainContent} />
</div>
</div>
</div>
</div>
</div>
</div>
</main>
)
} But I'm getting this error... Error: Route "/blog/[blogName]" used
If anyone find the solution. Please let me know |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Hi, In Next 15 a breaking change was introduced. Please do these changes: type Props = {
params: Promise<{ blogName: string }>
searchParams?: Promise<{ [key: string]: string | string[] | undefined }>
} And then you'll need to await before reading the export async function generateMetadata(
{ params }: Props,
_parent: ResolvingMetadata
): Promise<Metadata> {
const { blogName } = await params;
const blog = IndividualBlogData.find(blog => blog.name === blogName)
// and later on
// ✅ Page component using proper param typing
export default async function BlogPage({ params }: Props) {
const { blogName } = await params;
const blog = IndividualBlogData.find(blog => blog.name === blogName) |
Beta Was this translation helpful? Give feedback.
Hi,
In Next 15 a breaking change was introduced.
Please do these changes:
And then you'll need to await before reading the
blogName
: