Next.js Discord

Discord Forum

generateMetadata do not set the tags when exist await params.

Unanswered
Masai Lion posted this in #help-forum
Open in Discord
Masai LionOP
Hey,
There is a strange "bug."
Whenever I put await params inside the function generateMetadata(), the SEO tags are not set.
If I reload the page manually, the tags do not show, but when I save in my text editor and the app reloads, the tags appear. This is very strange...

import type { Metadata } from "next";

type Props = {
    params: Promise<{ locale: string; page: string }>;
};


// DOES NOT WORK 
export async function generateMetadata({ params }: Props): Promise<Metadata> {
    const { page } = await params;
    console.log("page", page);
    return { title: "test" };
}

// WORKS
export async function generateMetadata({ params }: Props): Promise<Metadata> {
    return { title: "test" };
}

export default async function Page({ params }: Props) {
    const { page } = await params;
    return <div>{page}</div>;
}


Layout is clean, only <html><body>

How can I fix it?

6 Replies

This is because Next.js introduced Streaming Metadata when encountering an await keyword, this means your page will start painting on screen even before the generatesMetadata() finished its execution and will stream the necessary <head> tags are they’re becoming ready.

It’s basically a lazy loading for metadata tags, to avoid blocking the user and deliver a faster page load.

There’s not a config to directly get the previous behavior since this is now the default. But in theory this should disable that behavior:


import type { NextConfig } from 'next'
 
const config: NextConfig = {
  htmlLimitedBots: '.*',
}
 
export default config
Armant
If you want fetching from an API based on params, you should await inside the function, but only for your fetch, not for params.

export async function generateMetadata({ params }: Props): Promise<Metadata> {
const data = await fetch(https://api.example.com/page/${params.page}).then(r => r.json());
return { title: data.title };
}
Armant
Try await before params
import type { Metadata } from 'next';

type Props = {
params: Promise<{ page: string }>;
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
// Await the params object to resolve the promise.
const resolvedParams = await params;

// Use the resolved value to fetch data.
const data = await fetch(https://api.example.com/page/${resolvedParams.page}).then(r => r.json());

return { title: data.title };
}
Pacific sand lance
i know, just saying