Next.js Discord

Discord Forum

Additional request sent on static page

Unanswered
Maine Coon posted this in #help-forum
Open in Discord
Maine CoonOP
Hello 👋

I created a static page with a button that uses router.push to append a query param to URL. Then I noticed that when the router.push('/?search="something"') happens, there's an additional request for some kind of metadata:

https://next-experimental-framework.vercel.app/
1:HL["/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
2:HL["/_next/static/css/f9878c8f0d013614.css","style",{"crossOrigin":""}]
0:["yN9QNAjDdsOwNbz5U8ibL",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],"$L3",[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/f9878c8f0d013614.css","precedence":"next","crossOrigin":""}]],"$L4"]]]]
etc... 


You can find the whole response in a network tab - it happens once, then it's probably cached for some time.
During investigation, I prepared a static build (output: "export") and in out dir there's an index.txt file with the content.

## Question

Why is it needed? I would expect that if it's a static page, there won't be any additional request, as it's a static page 😅

## How to reproduce it?

You can take a look on a simple PoC here: https://github.com/Onxi95/next-experimental-framework/tree/main/query-params

40 Replies

This is an RSC payload I think
your page is rerendering an RSC
instead of sending HTML, the RSC can be represented as a JSON structure that React can easily interpret
Maine CoonOP
Yeah, but why is it needed? I assume that static export shouldn't make any additional requests (other than e.g. client fetches for API if present), as it might be a stand-alone page 🤔
static export has the pre-rendered html and rsc... it uses rsc txt document for internal rendering but the html to have it prerendered for faster and no JS
When you interleave server and client components, the client might have to be able to rerender the server component
but not rerender in the traditinal React sense (it's in the browser so it can't actually fetch data etc. like the RSC do)
it will take the payload and turn it into HTML
it's still vague cause it's not really documented or in complex RFC*
but basically RSC !== dead HTML
the main benifit is way smaller fetch req iirc
also if your feeling curious, you can past it into: https://rsc-parser.vercel.app/ and see a more parsed format of it
Maine CoonOP
I think I'm still missing something 😅 I use 2 client components:

* <SearchParams />
* <RoutePush />

both use "use client" directive. They don't accept any children, so they shouldn't be rendering any RSC components.

page.tsx & layout.tsx are both RSC if I get it right.
In this index.txt payload there are some references to client components, but it seems there's a complete globals.css a css here - why does it happen why I change query params? It seems like it's a waste of bandwidth 🤔
so including this content
since the searchParams make the page dynamic everything will reload
(searchParams are annoying in Next cause you can't statically render them and it kills me)
not sure it actually reloads the CSS, but the link to the CSS, which is probably cached by the browser
Maine CoonOP
I'm not sure if it will trigger a dynamic renders, as out directory can be served from a CDN - by dynamic I mean some kind of server-side logic that handles request, CDN will just serve a file 😅
https://nextjs.org/docs/app/api-reference/functions/use-search-params
Static Rendering
If a route is statically rendered, calling useSearchParams() will cause the tree up to the closest Suspense boundary to be client-side rendered.

I used a Suspense, and I'm fine with client-side render, but this additional request for txt file (every time if there's a new query param) annoys me so much 😅
The main point is I don't get why there's a separate .txt file with some RSC content and it's served separately every time when a new query param is present while it's still a static export and I guess it doesn't even change, as it's a static file
this is kind of advanced internal stuff beyond the currently documented knowledge
Saltwater Crocodile
Is it somehow possible to have SSG for a url without searchParams and if searchParams are used to switch to SSR?
Shy Albatross
if there's nothing in front of your Next app then you could do that with middleware, if there is, then there - if the address is naked then serve cache, else bypass cache, then in Next your page can just be a lmabda and it will only get hit when there are params
Saltwater Crocodile
Do you have some kind of example in order to achieve that?
but this is a hack, you use a route param that mimicks the sarch params
unless @Shy Albatross was thinking about something else
search params are Next.js kryptonite, the way it's designed it's pretty hard to statically render them without either dynamic or client rendering
if you stick to useSearchParams, the page can stay static I think, but will be client-side rendered
you need to try it out (add logs, check the network)
@Eric Burel but this is a hack, you use a route param that mimicks the sarch params
Saltwater Crocodile
A terrible hack imo. Also hard to achieve if you have multiple search params, which are all optional.
@Eric Burel search params are Next.js kryptonite, the way it's designed it's pretty hard to statically render them without either dynamic or client rendering
Saltwater Crocodile
It's a pain. I'd like to have a solution where I can set a page to ISR, but to have components within a Suspense boundary, which are server rendered and are able to access search parameters. I wonder why this is not possible? I mean I can access cookies and headers, why not search parameters?
Maine CoonOP
So sad that's not a trivial thing to render just a static html that uses useSearchParams & router.push(/something?query="hello") without any external requests to the server that delay the action 😅 I really want to use search params to preserve a state, but it sounds like it might be easier just to use browser's native API to set it and call it a day without touching next's router.push API - it's obviously a hack, but I don't have any better idea - maybe when I find some time, I'll write an issue on GH pointing it out 😔
indeed it could be a function like cookies() etc., that's heavily debated on some github threads
I deplore the choice that have been made to provide only bits of the request, in my understanding it's in order to have consistency with layouts
but layouts are almost unusable the way they are coded no