Closed rob-strover-axomic closed 1 year 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. :)
@rob-strover-axomic were you able to implement it? Could you tell how you done it in your app?
Hi @Gytjarek
Yes, I implemented according to the usage instructions in the readme. The problems I was having with page responsiveness were actually down to a slow backend service that I needed to call on each route change in order to get the metadata content for my page components (server components). Having subsequent route changes after initial page load would require substantial reworking and would mean not leveraging the NextJS App router as intended.
One thing I would recommend you do is move to Next 14. This seemed to help with some unexpected routing behaviour I was coming up against.
Hope this helps
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: