Reputation: 8972
Working on my first Next.js 14 site I've read through the documentation for Dynamic Metadata but for some reason when I run my site locally and visit the page the metadata does not generate.
Structure:
[slug]/page.tsx
page.tsx
import type {Metadata} from 'next'
// API
import {getPage} from '@/api/page'
type MetadataProps = {
title: string
description: string
}
export async function generateMetadata(params: MetadataProps): Promise<Metadata> {
console.log(params)
return {
title: {
template: `%s | ${params?.title}`,
default: params?.title,
},
description: params?.description,
}
}
export default async function Page({params}: Readonly<{params: {slug: string}}>) {
const page = await getPage(params?.slug)
console.log({page})
await generateMetadata({
title: page?.title,
description: page?.description,
})
return (
<div>
<p>Page: {params?.slug}</p>
</div>
)
}
but in the console log before generateMetadata
and after I get data from the API getPage
I see:
{
page: {
description: 'description',
title: 'Test page',
_createdAt: '2024-08-05T18:38:16Z',
_id: 'some id',
_updatedAt: '2024-08-14T14:17:45Z',
slug: 'test-page'
}
}
along with seeing the object correctly in params
:
{
title: 'Test page',
description: 'description',
}
What is the correct way to dynamically generate metadata in Next.js 14 based on the API call an why do I not see the metadata?
Upvotes: 0
Views: 252
Reputation: 1150
You should call the API from the generateMetadata
function instead of from the Page
function.
Here's an example of how the code should look:
import type {Metadata} from 'next'
// API
import {getPage} from '@/api/page'
type Props = {
params: { slug: string }
}
export async function generateMetadata(
{ params }: Props,
): Promise<Metadata> {
// read route params
const slug = params.slug
const page = await getPage(slug)
return {
title: {
template: `%s | ${page?.title}`,
default: page?.title,
},
description: page?.description,
}
}
export default async function Page({params}: Readonly<{params: {slug: string}}>) {
return (
<div>
<p>Page: {params?.slug}</p>
</div>
)
}
For more details, refer to the official Next.js documentation on the generateMetadata function here.
Upvotes: 0