Now static metadata
as we have it here is often all you need
because for many pages,
the metadata you wanna set might indeed be static
and not change depending on what's shown on the page.
But you also might have some pages
where the metadata does change
and does depend on the dynamic content of the page.
For example, here in my feed folder,
in the page.js file there, I'm showing all my posts.
And of course we could set up some static metadata
here as well, with a title of All Posts
and a description that could be, browse all our posts.
That might be fine and that might be all you need.
But you also might have some dynamic metadata
on some pages, so some metadata that's not always the same,
but that instead should change
as the data on the page changes.
For example, here, we might want a title that says,
browse all our X posts,
where X should be the number of posts.
And of course that number is dynamic.
It's not set in stone
and we definitely don't know it at the point of time
where we're writing this code.
And that's why NextJS also allows you
to set dynamic metadata,
and that's done by not exporting a constant called metadata,
but by instead exporting a function
called generateMetadata.
And that should be an async function.
And of course it must be named generateMetadata
because just as NextJS is looking
for a constant named metadata
or a variable that doesn't matter,
but it must be named metadata, NextJS is looking
for a function named generateMetadata like this
in your page.js files.
And if NextJS then finds such a exported function
with that exact name, it will execute that function
for you when it renders that page.
Now this function will then automatically receive
a configuration object or a data object,
whatever you want to call it.
It will receive that object automatically
because this object with its data
will be passed in by NextJS.
And this object will hold useful information.
For example, any page parameters that might be set
for this page so that you could retrieve dynamic data
if you were on a dynamic page.
But you can, for example, also extract any searchParams
that might be set in case these kinds
of information pieces are important to you
for generating the dynamic metadata.
Now here for this page, I actually don't have
any params or anything like that
because I'm not on a dynamic route.
I don't have a dynamic route segment here.
Instead it's a regular static route,
but I still want dynamic metadata,
therefore I'll still add generateMetadata,
but I don't care about any data passed to it.
But what I do care about is about my posts.
So here I will still get my posts
by calling await getPosts here,
just as I do it in the page component.
So that here I get my posts
and then I get my number of posts by using
or by accessing the length of this posts array.
And then once you're done preparing your dynamic data,
generateMetadata should return an object
where you then still set the title, description,
and any other metadata you wanna set up.
For example, we could still set a static description
of browse all our posts here,
but we could now also set a dynamic title that says,
browse all our,
and then the number of posts which I output here like this
since I'm using a string template.
And that's how we could dynamically generate such a metadata
object here with help of this generateMetadata function.
And that's really all that's to it.
With that all, if I load this feed page,
it will generate as before, but NextJS will now actually
also execute this generateMetadata function here
and set the metadata accordingly.
That's why now after loading this page,
I see the number of posts here in the page title
because that metadata was generated dynamically.