Open Kasheftin opened 1 year ago
Qwik does not do different streaming, for head, body. But qwik resolves the head data before start rendering.
Same technique is used by Remix or new Nextjs: https://remix.run/docs/en/main/route/meta https://nextjs.org/docs/app/building-your-application/optimizing/metadata
The <head>
can not be changed later during SSR, by upcoming components, because it's already rendered, it's always sent in the network before your useTask$()
even runs. That's why it's streaming.
Without this constrain, we could not start sending a single byte of HTML, because at any point any component could change the header.
The way it works in Qwik is by providing a declarative way to resolve the head information, even before rendering: https://qwik.builder.io/docs/pages/#head-export
Unfortunately, I dont think it's solvable without resolving the head
title and stuff at the root level.
I ended up in a similar position as OP. Being unable to change meta tags / head content from within a component would allow for more flexible data fetching. I have more than one dynamic catchall route so I could "fan" out the routeLoaders without having one giant data fetching at the root route but, let's say you have a list view route with filters, categories, etc - that instantly makes it necessary to handle the entire state logic in the route component and needing to push props down into components to render, including pagination methods etc or setting up even more global context.
It is doable, I already refactored most of it, but it is one of those things that I wish I was nudged too earlier when reading the docs. :)
Which component is affected?
Qwik City (routing)
Describe the bug
I made quite significant progress in developing a big app with custom dynamic routing and then met an obstacle with setting document head/title/og-meta. Now I'm stuck and not sure what is better - write a custom qwik-city following https://blog.brecht.io/why-and-how-i-created-a-spa-router-for-qwik/ or dive into qwik-city source code.
I created a separate repo demonstrating the problem, https://github.com/Kasheftin/qwik-ssr-head-issue.
routes/[...path]/index.tsx
.HeadStore
component which defines a head context. Since it's the root-most, any other component has access to the head store includingrouter-head.tsx
.stores/main.tsx
wrapper component for that.[...path]
parser which uses loaded sections under the hood.useResource$
for loading the data. After receiving the data it sets HeadStore properties. They are read and substituted into the document title inrouter-head.tsx
.The logic, described above, does not work in SSR (when the page is being initially loaded). It starts working during SPA navigation. I've read https://www.builder.io/blog/streaming-is-it-worth-it but did not find anything about separate head/body streaming in the qwik-city source code. I guess there's some special logic handling useDocumentHead and head exports and I'm looking for a way to turn it off. The real app routing is much more complex, and it's going to be very hard to reimplement it using directory-based routing and head export. The entire document including both head and body should be reactive.
Reproduction
https://github.com/Kasheftin/qwik-ssr-head-issue
Steps to reproduce
npm install
following bynpm run dev
.System Info
Additional Information
No response