Next.js Discord

Discord Forum

Pre-render dynamic routes at built time

Answered
Gouty oak gall posted this in #help-forum
Open in Discord
Gouty oak gallOP
Creating a blog website with app router. How can I pre-render my blog post pages at build time using static generation?

\blogs is prerendered as static content
\blogs\[slug] is server-rendered on demand, but if I use generateStaticParams, it's prerendered as static HTML. While prerendering as static HTML is much better than server-rendering on demand, it's still not as good for my use case as prerendering as static content.

How can I prerender each blog as static content at built time?

\blogs gets the data from a database at built time and then never again
\blogs\[slug] (with generateStaticParams) doesn't get the data from a database at built time, but only when user visits the page for the first time - I want this to be done at built time, just like with blogs.

I feel like this should have a simple solution, but I've been trying everything I could think of or find online for hours with no success of making the blog pages fully static.

Any help is very appreciated!
Answered by joulev
With generateStaticParams, the data is fetched at build time, for the slug values you return in the generateStaticParams function.

Only slug values not returned by that function are evaluated at the first request.

So you simply need to return all possible values of slug in generateStaticParams for it to be built entirely at build time.

If you put export const dynamicParams = false in the page, you will even remove the build-at-runtime step for slug values not returned in generateStaticParams. A 404 would be returned instead, for those slug values. So if you want to be absolutely sure everything is built at build time, add this export to the page.
View full answer

3 Replies

@Gouty oak gall Creating a blog website with app router. How can I pre-render my blog post pages at build time using static generation? `\blogs` is prerendered as static content `\blogs\[slug]` is server-rendered on demand, but if I use generateStaticParams, it's prerendered as static HTML. While prerendering as static HTML is much better than server-rendering on demand, it's still not as good for my use case as prerendering as static content. How can I prerender each blog as static content at built time? `\blogs` gets the data from a database at built time and then never again `\blogs\[slug]` (with generateStaticParams) doesn't get the data from a database at built time, but only when user visits the page for the first time - I want this to be done at built time, just like with blogs. I feel like this should have a simple solution, but I've been trying everything I could think of or find online for hours with no success of making the blog pages fully static. Any help is very appreciated!
With generateStaticParams, the data is fetched at build time, for the slug values you return in the generateStaticParams function.

Only slug values not returned by that function are evaluated at the first request.

So you simply need to return all possible values of slug in generateStaticParams for it to be built entirely at build time.

If you put export const dynamicParams = false in the page, you will even remove the build-at-runtime step for slug values not returned in generateStaticParams. A 404 would be returned instead, for those slug values. So if you want to be absolutely sure everything is built at build time, add this export to the page.
Answer
@joulev With generateStaticParams, the data *is* fetched at build time, for the slug values you return in the generateStaticParams function. Only slug values *not* returned by that function are evaluated at the first request. So you simply need to return all possible values of slug in generateStaticParams for it to be built entirely at build time. If you put `export const dynamicParams = false` in the page, you will even remove the build-at-runtime step for slug values not returned in generateStaticParams. A 404 would be returned instead, for those slug values. So if you want to be absolutely sure everything is built at build time, add this export to the page.
Gouty oak gallOP
dsglkjdsgke THANK YOU! I was starting to think generateStaticParams works a bit differently, as it didn't work as I thought it should, even though the function returned all slugs. But now that you confirmed it should work this way, I went and checked my generateStaticParams() and the documentation for the 50th time... I WASN'T RETURNING THE SLUGS PROPERLY, THAT'S WHY IT DIDN'T WORK. I returned
return projects.map((project) => ({ params: { slug: project.slug, }, }));

instead of
return projects.map((project) => ({ slug: project.slug, }));


This definitely didn't just take me multiple hours to solve... :fine:
But at least it works now, thanks!
haha it happens yeah, pages router and app router syntaxes are different. glad you got it working.