Replies: 3 comments
-
I posted a very similar question a few days ago: #19424 |
Beta Was this translation helpful? Give feedback.
0 replies
-
I hope this answer can help you. (I have tested this and it works for your example.) |
Beta Was this translation helpful? Give feedback.
0 replies
-
Late to the party. I'm experiencing the exact same issue as you described and I really like the elegance of your solution, along with the package you made to easily implement it! However, I do agree that it would be nice if the |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I'm using
useState('foobar')
with a default value ofone
in my default layout. In the page component I update the state value withupdated value
insideuseAsyncData
. The rendered value inside the layout component remainsone
during SSR.Full example on StackBlitz
I understand that rendering happens "from top to bottom", so updating a reactive value in a page component has no effect on parent components (like layout), as these have already been rendered at this point.
In Nuxt 2 this was possible inside
asyncData()
and I have used this extensively on all projects, where the page commits page specific data like breadcrumbs, language links, sharing links and other things to the store, which is then used in components rendered in the layout.My understanding is that this worked because asyncData was called before any rendering happened, though I'm not sure about that.
I can think of a few workarounds, like creating a server-only plugin that loads the data and puts it in the state/store. But this would require the plugin to replicate the fetching logic of each page component. In some projects of mine I have a dozen different pages with very different logic to set global state (especially with breadcrumbs). I would much rather prefer to keep this code only in the page components.
Of course all of this would not be an issue if the page component itself renders all the components that require page data. But in one project of mine the navigation's logo component contains data from the page. I'd have to render the entire navigation in my page component because of a single text that changes, which sounds like a bad idea.
Another idea I looked into was to create a wrapper for all components that have a dependency on data from a page. The wrapper would return a Promise in its
setup
, that resolves once the page component is done fetching data and rendering, returning the default slot:Used like this:
I quickly realized that the
page:finish
hook is not called during SSR. I then created my own hook ('async-data-loaded'
), which I'm calling from within my page'ssetup()
. And it works as expected: Rendering of the<Breadcrumb />
component is delayed until I call my hook.While this seems to work, it's a bit tricky because the hook might have already been called before or is not called at all for some reason (e.g. error). This would then result in a locked state where the rendering never finishes and the request is hanging. This could be solved by adding a
setTimeout
that resolves the render function after some time.Ideally there is a better way to know "when the page component is finished" or if it has already finished. From my research it looks like Nuxt does not tell me this currently and my few attempts to add that somehow myself failed (expect adding
await app.callHook('async-data-loaded')
in every page component.Would such a feature be something that could be added to Nuxt? If not, would it at least be possible to also trigger the
page:finish
hook during SSR? Or maybe I'm on a completely wrong path here and there's already a simple solution I just haven't thought about yet 😄Beta Was this translation helpful? Give feedback.
All reactions