Next.js Discord

Discord Forum

Dynamic metadata, help!

Answered
Asiatic Lion posted this in #help-forum
Open in Discord
Asiatic LionOP
Hi!

I'm attempting to dynamically render metadata for a certain path.


I've done it like this;

import { Part } from '@prisma/client';
import type { Metadata, ResolvingMetadata } from 'next';

type Props = {
    part: Part;
};

export async function generateMetadata({ part }: Props): Promise<Metadata> {
    return {
        title: part.name,
        description: part.description,
    };
}

export default function Page({ part }: Props) {
    return <div>{part.name}</div>;
}


I get the object from here

interface SparePartPageProps {
    params: { id: string };
}

export default async function SparePartPage({
    params,
}: SparePartPageProps): Promise<JSX.Element> {
    const fetchProduct = async () => {
        const part = await prisma.part.findFirst({
            where: { id: Number(params.id) },
        });
        return part;
    };

    const part = await fetchProduct();


    if (!part) {
        return <div>Ingen del hittades</div>;
    }

    return (
        <Stack alignItems={'center'}>
            <SpecificSparePartPage part={part} />
        </Stack>
    );
}


No errors, but no metadata either. Can someone clue me in?
Answered by Ray
generateMetadata() need to export from page.tsx and you should fetch the data it need
// page.tsx
import { cache } from 'react'
import { notFound } from 'next/navigation'

const fetchProduct = async (id) => {
  const part = await prisma.part.findFirst({
      where: { id: Number(id) },
  });
  return part;
};
const cachedFetchProduct = cache(fetchProduct)

export async function generateMetadata({ params }: Props): Promise<Metadata> {
    const part = await cachedFetchProduct(params.id)
    if (!part) notFound()
    return {
        title: part.name,
        description: part.description,
    };
}

export default async function SparePartPage({
    params,
}: SparePartPageProps): Promise<JSX.Element> {
    const part = await cachedFetchProduct();

    if (!part) notFound()

    return (
        <Stack alignItems={'center'}>
            <SpecificSparePartPage part={part} />
        </Stack>
    );
}
View full answer

1 Reply

@Asiatic Lion Hi! I'm attempting to dynamically render metadata for a certain path. I've done it like this; js import { Part } from '@prisma/client'; import type { Metadata, ResolvingMetadata } from 'next'; type Props = { part: Part; }; export async function generateMetadata({ part }: Props): Promise<Metadata> { return { title: part.name, description: part.description, }; } export default function Page({ part }: Props) { return <div>{part.name}</div>; } I get the object from here js interface SparePartPageProps { params: { id: string }; } export default async function SparePartPage({ params, }: SparePartPageProps): Promise<JSX.Element> { const fetchProduct = async () => { const part = await prisma.part.findFirst({ where: { id: Number(params.id) }, }); return part; }; const part = await fetchProduct(); if (!part) { return <div>Ingen del hittades</div>; } return ( <Stack alignItems={'center'}> <SpecificSparePartPage part={part} /> </Stack> ); } No errors, but no metadata either. Can someone clue me in?
generateMetadata() need to export from page.tsx and you should fetch the data it need
// page.tsx
import { cache } from 'react'
import { notFound } from 'next/navigation'

const fetchProduct = async (id) => {
  const part = await prisma.part.findFirst({
      where: { id: Number(id) },
  });
  return part;
};
const cachedFetchProduct = cache(fetchProduct)

export async function generateMetadata({ params }: Props): Promise<Metadata> {
    const part = await cachedFetchProduct(params.id)
    if (!part) notFound()
    return {
        title: part.name,
        description: part.description,
    };
}

export default async function SparePartPage({
    params,
}: SparePartPageProps): Promise<JSX.Element> {
    const part = await cachedFetchProduct();

    if (!part) notFound()

    return (
        <Stack alignItems={'center'}>
            <SpecificSparePartPage part={part} />
        </Stack>
    );
}
Answer