Next.js Discord

Discord Forum

Do NextJS makde 2 requests for page and generateMetada ?

Answered
California pilchard posted this in #help-forum
Open in Discord
Avatar
California pilchardOP
My question is pretty simple, but in page.tsx in server side, do the request is made twice ? (in generateMetada and in Person)
export async function generateMetadata({
  params,
}: {
  params: {
    lang: string;
    person: string;
  };
}) {
  const { id } = getIdFromSlug(params.person);
  const supabase = createServerClient(params.lang);
  const { data: person } = await supabase
        .from('person_full')
        .select(`*`)
        .eq('id', id)
        .single();
  return {
    title: person.name,
    description: `This is the page of ${person.name}`,
  };
}

export default async function Person({
  params,
}: {
  params: {
    lang: string;
    person: string;
  };
}) {
  const { id } = getIdFromSlug(params.person);
  const supabase = createServerClient(params.lang);
  const { data: person } = await supabase
        .from('person_full')
        .select(`*`)
        .eq('id', id)
        .single();
  return (<></>);
}


If yes there is a way to prevent this ? And also if we have a layout.tsx making a query, and a page.tsx making the same query there is a way to share the same data for optimize api request ?

thx !
Answered by Bengal
It does do it twice, you can use the react cache to have it only called once with the subsequent requests being cached.
https://react.dev/reference/react/cache
View full answer

5 Replies

Avatar
Bengal
It does do it twice, you can use the react cache to have it only called once with the subsequent requests being cached.
https://react.dev/reference/react/cache
Answer
Avatar
California pilchardOP
YEs I do this :
export const getPerson = cache(async (id: string, lang: string) => {
  const { id: personId } = getIdFromSlug(id);
  const supabase = createServerClient(lang);
  const { data: person, error } = await supabase
    .from('person_full')
    .select(`*`)
    .eq('id', personId)
    .maybeSingle();
  if (error) throw error;
  return person;
})

export async function generateMetadata({
  params,
}: {
  params: {
    lang: string;
    person: string;
  };
}) {
  const person = await getPerson(params.person, params.lang);
  if (!person) return {
      title: 'Oups, personne introuvable !',
  }
  return {
    title: person.name,
    description: `This is the page of ${person.name}`,
  };
}

export default async function Person({
  params,
}: {
  params: {
    lang: string;
    person: string;
  };
}) {
  const person = await getPerson(params.person, params.lang);
  if (!person) notFound();


Its working but now I try to import the getPerson function from layout.tsx inside page.tsx its also working great (to share data between layout and page) but during building it fail with this logs :
Type error: Layout "src/app/[lang]/(app)/film/[film]/(default)/layout.tsx" does not match the required types of a Next.js Layout.
  "getMovie" is not a valid Layout export field.
Avatar
California pilchardOP
Okay I fix by creating a file getPerson.ts with the function and import it in every page or layout that I need
Works great ! definitvely increase speed
Avatar
Bengal
Awesome, I'm glad your issue is resolved