Is it possible to include static HTML in a dynamic route? (App Router)
Answered
European anchovy posted this in #help-forum
European anchovyOP
For one of my pages I have a much of the DOM effectively being static, whilst I also have a section that needs to be generated with information only available at the time of request. As such, my ideal strategy to handle this would be partial prerendering, however, that is an experimental feature of next and so by my understanding isn't suitable for a production environment. Is there an alternative? One idea I had was to build the static content seperately and then write a server script to inject it onto the page.
Answered by Arinji
you could make an api route, and call it in a client component inside a useEffect
30 Replies
Brown bear
Use generateStaticParams to make the dynamic routes ISR.
Then on your dynamic pages, make sure your top level page component is a server component, then the dynamic part is client component.
Then on your dynamic pages, make sure your top level page component is a server component, then the dynamic part is client component.
European anchovyOP
@Brown bear thanks for the suggestion. My understanding of generateStaticParams is that it would statically generate the page. Would adding the "use client" directive to the dynamic component mean that component is server rendered on each request? So the route would be generated at build but the specific client component is server rendered?
@European anchovy nextjs dosent work like that
its actually quite smart when its rendering
so firstly, the entire page can either be one thing
dynamic or static generated on build
but its not like dynamic is bad, if most of the page is static, it will optimise the page accordingly
it will only wait for you fetch the page data required, which can be removed if you scope the fetching into suspense boundaries :D
European anchovyOP
Thanks @Arinji for the clarification. The particular issue I've been running into is that I do want my page to be generated at build (so SSG) however, I have a fetch that is getting product data. This fetch request needs to be the latest so it cannot be cached. Therefore, I have tried using something like noCache to prevent the result of the request being cached but it seems like with App Router, a route is either static with client side hydration, or server side rendered. There doesn't appear to be mixing between those two strategies. I checked the output in my .next directory and could confirm this behaviour when I ran my build command. So, partial prerendering solves for this. But, is there a way (without having the product fetch occur on the client because it's a very big query) to have the fetch occur on the server and not be cached, whilst retaining static generation for the rest of that particular route?
you could make an api route, and call it in a client component inside a useEffect
Answer
while the rest of the page is staticly generated, that is run on the client hence dynamic
European anchovyOP
So then the HTML for the result of the fetch would be handled on the client not the server?
well the api route is always on the server
what happens with the response is done by the client
European anchovyOP
Hmmm. I don't think that solves my problem, as the result of the query is a long list of products including product images. The performance concern there being the client device having to load all the images and also any work that gets pushed into the main thread during page load.
@European anchovy So then the HTML for the result of the fetch would be handled on the client not the server?
the GET endpoint can be static generated or on demand revalidation
so it doesn't hit the database every time
European anchovyOP
Yeah the challenge I have is I do need the product query to be completely uncached and ideally generated on the server. So ideally it does the work of prerendering the HTML and just sending that, reducing the cost of processing it on the client. But, unless I'm misunderstanding. Using an API endpoint would not solve that problem? Unless I can get the endpoint to return the HTML? I guess it could right? Since it's just whatever I want.
It's basically just a static page with one section that is particularly expensive to generate that can only be generated at with information available at time of request, hence no cache. And I can't request it on the client because it's too expensive.
@European anchovy Yeah the challenge I have is I do need the product query to be completely uncached and ideally generated on the server. So ideally it does the work of prerendering the HTML and just sending that, reducing the cost of processing it on the client. But, unless I'm misunderstanding. Using an API endpoint would not solve that problem? Unless I can get the endpoint to return the HTML? I guess it could right? Since it's just whatever I want.
you could use client side rendering on that part and fetching the static GET endpoint
@Arinji well the api route is always on the server
as mentioned before, the api route is on the server.. its not gonna be done on the client
@Arinji as mentioned before, the api route is on the server.. its not gonna be done on the client
European anchovyOP
Thanks. I'll give it a go and see how it performs
@European anchovy Thanks. I'll give it a go and see how it performs
yeah and use route segment config for the route handler
European anchovyOP
Cheers, that's a good reminder.
I was so bummed out when i realised that adding cache: 'no-store' to a fetch reqeust changed the route to dynamic.
the top bar is client side rendering while the bottom content is ssr
its fetching a static GET endpoint
European anchovyOP
I pushed up a little app to test