Closed rob-strover-axomic closed 5 months ago
The server should respond with the loading
contents first, and then also render your page contents and deliver them to your browser - that's how it is meant to be in Next.js.
If you want more fine-grained control over this, you can add additional Suspense
boundaries to your application, to determine which parts of your control suspend in which specific way.
@phryneas Thanks for your speedy response!
So am I right in saying there is no way to produce the use case I described above? Does this mean it is not possible to retrieve data in an SEO friendly way outside of serverside components?
I believe you will get the same result with Server Components once you have a few Suspense boundaries in there.
This is React's "streaming render".
I think I read somewhere that Next detects if it's accessed by a crawler and doesn't do out-of-order streaming in that case, but I might be wrong.
This discussion might be interesting to you: https://github.com/vercel/next.js/discussions/50829
@phryneas Thanks, this is helpful, strange how lighthouse seems to get a fully server side rendered version of the site back. I will try and simulate what's going on here with Postman.
I'm still confused as to how streaming pieces of UI rendered on the server is better than using the client to render content after the first load but maybe that answer will become clear as I keep going.
It's a technical issue: RSC don't create HTML - so without a SSR pass of all your client components (that can intertwine with your RSC tree) your application cannot stream HTML to the browser at all.
At the same time, you want to start streaming data as fast as possible, so that's why that render is streamed.
So when I remove the loading
files from my Next JS application, refresh the page and see that the actual page markup is returned in the response, how is this worse than streaming some loading spinner markup first and then the rendered data markup? Isn't this more work?
A white screen instead of a customized loader (e.g. a skeleton view) is usually a worse user experience, and that's what you should optimize for, long before you optimize for SEO.
You should probably also set Suspense boundaries throughout your application, which would give you more granular loading states and would allow parts of your application to be interactive even while some others are still loading.
I can recommend giving this talk a watch: https://portal.gitnation.org/contents/how-to-use-suspense-and-graphql-with-apollo-to-build-great-user-experiences
Thanks for all your help and information here. :)
Hello,
Thanks for all your awesome work.
I'm using the Next JS 13 app router with the
@apollo/experimental-nextjs-app-support/ssr
useSuspenseQuery
hook in one of my client componentpage.tsx
files. When I load the page, I can see in the network tab in chrome that the server is responding with theloading.tsx
content and doesn't seem to wait for the query to complete and render the page content before responding. Is this expected? If I remove theloading.tsx
file then the server does wait for the query to complete and responds with the renderedpage.tsx
content. Ideally I do want a loading state to appear on the client side as a placeholder when navigating on the client side.To summarise; Ideally, I want the server to wait for the query to complete, render the content and then respond. I would then want client side route changes to show the loading content whilst the frontend waits for the request to complete. Is this possible?
Thanks for taking the time to give thoughts here, is there something I'm missing?
Code samples below: