We made quite a few changes
to the StardewValleyPage,
and it now loads the review data
from a separate Markdown file.
But what about our other review page?
We should reallyÂ do the same for Hollow Knight.
Let's create a Markdown file for that game.
I'll just duplicate the Stardew Valley one,
and rename it to "hollow-knight.md".
Then we can change the title,
to say "Hollow Knight".
As the date, I'll just put the next day.
The image path needs updating as well.
And finally we'll want a review body,
that I'm going to copy from Wikipedia again,
just to have some text that's
relevant to this game.
Let's split it into two paragraphs,
and make the game title bold, like
we did for the other review.
Ok, the Markdown file is ready.
Now we need to display its contents on the page.
But we don't really want to duplicate
the same code again,
in this other component,
when almost everything will be the
same as the StardewValleyPage.
The only thing that needs to be different
is the argument we pass to the getReview function.
Next.js allows us to use the same
component for multiple paths.
That's called a "dynamic route".
Let's see how it works.
We don't want a separate component
for each review any more,
so I'll delete the "hollow-knight" route.
This means that, if we try loading
the "hollow-knight" path,
at the moment we'll get a 404 page.
But now we can change the "stardew-valley"
route to be "dynamic",
by renaming this folder to "[slug]"
in square brackets.
This is a strange name,
but the square brackets mean it will
match any path segment in the URL,
a bit like a wildcard.
And "slug" is name of the parameter
that will receive the actual value
for the requested path segment,
as we'll see in a minute.
Now, if I press Enter, this will
actually rename the folder,
and you can see that the browser
reloaded the page,
showing the content generated by this component.
That's because the "/reviews/hollow-knight" path
now matches this dynamic route.
So this is not just the StardewValleyPage
any more,
we can rename it to ReviewPage instead,
since it will be used for all the reviews.
But how can we know exactly
which review was requested?
Well, this component will receive some "props".
Let me log them to the console,
so we can see when this component is rendered,
and exactly what props it receives.
Let's look at the server logs,
and if I save this change,
you can see that the ReviewPage received
some "params" in the "props",
with the "slug" set to "hollow-knight".
So, what's going on here is that
the browser requests the "/reviews/hollow-knight"
path,
and the Next.js server maps it to
the "reviews" "[slug]" route,
because "[slug]" in square
brackets matches anything,
but for this particular request, the
actual value is "hollow-knight",
so that's what's passed as a parameter
to our page component.
Of course, if we request a different review,
like "stardew-valley",
the "slug" parameter will have a different value.
This means we can use that parameter
to load the right file,
and display different content for each review,
rather than always the same page.
We simply need to destructure these
"props" to access the "params",
in fact, we could extract the "slug"
directly from the props object,
and then pass the "slug" value
to the getReview function.
This way it should load a different
file for each review.
If we save this change,
you can see that it's now displaying
the Hollow Knight data.
While, if we navigate to the other review,
it still shows the Stardew Valley content.
So, every route will automatically load the right data,
based on the "slug".
There's no need to write a separate
page component for each review.
We can just use a dynamic route,
by putting the parameter name
inside square brackets,
and Next.js will use this ReviewPage component
for all the URLs that match the
"/reviews/" something pattern.