feat: Replace @vueuse/head with @unhead/vue#804
Conversation
| nuxtApp.hooks.hook('render:before', () => { pauseDOMUpdates = true }) | ||
| // wait for new page before unpausing dom updates | ||
| nuxtApp.hooks.hook('render:done', unpauseDom) |
There was a problem hiding this comment.
The hook does not exist in Nuxt 2, so it is changed from the original code of Nuxt 3.
original code is
https://github.com/nuxt/nuxt/blob/4ac4dfda15c5b92507334681c5d089cf6c5441c3/packages/nuxt/src/head/runtime/plugins/unhead.ts#L25-L29
There was a problem hiding this comment.
render:done is a server-side hook, so will never be called in this block (afaik?)
see https://v2.nuxt.com/docs/internals-glossary/internals-renderer
There was a problem hiding this comment.
I think we need to drop support for the pausing / unpausing feature.
This may introduce a potential flash of the title/classes for users and it may lead to unexpected ssr data, but not sure what else the solution would be without bridge implementing Suspense
There was a problem hiding this comment.
Thank you for your kind review!
I remove pausing / unpausing feature.
Somehow I tried to support it in Nuxt 2, but it's difficult.
|
Really nice work @wattan! Initial review looks good, I'll have another look with fresh eyes when I have a chance. |
|
A couple of things I noticed while testing:
[Vue warn]: "style" is a reserved attribute and cannot be used as component prop. 2:18:45 pm
found in
---> <Meta>
<Head>I imagine this is also the case for the nuxt 3 components as well, we should ideally just use the exported components from unhead or vueuse/head, I'll need to do some work on them though. Will keep testing and let you know if I spot anything else |
|
An issue with this imeplementation is any promises within script setup won't be resolved before rendering the meta. Consider the following code: <script>
export default {
async setup() {
const data = await new Promise(resolve => {
setTimeout(() => {
resolve('test')
}, 500)
})
useHead({
title: data // SSR does not work, CSR will work
})
}
}
</script>The SSR title would be undefined. I think this is a pretty poor DX. The workaround is pretty simple though: <script>
export default {
setup() {
const data = new Promise(resolve => {
setTimeout(() => {
resolve('test')
}, 500)
})
useHead({
title: data // SSR and CSR works, Unhead will resolve promises before rendering
})
}
}
</script>I don't think we can solve for the first example without using Suspense and I don't think that's possible with nuxt/bridge. Maybe just a documentation thing? |
harlan-zw
left a comment
There was a problem hiding this comment.
May need to remove pausing / unpausing feature
|
I don't think async script setup is possible at all with Nuxt 2, which may resolve this potential issue? |
|
I see that the title also supports |
There was a problem hiding this comment.
Alright in that case and with the updates, looks good.
Thanks again for the great work!
One minor optional thing to consider is adding the polyfills, this helps with any code which used the slightly different @vueuse/head API. May not be needed.
Example code:
import { polyfillAsVueUseHead, createHead } from '@unhead/vue'
const head = createHead()
// support the same api as @vueuse/head
polyfillAsVueUseHead(head)
🔗 Linked issue
Fixes: #803
Fixes: #792
❓ Type of change
📚 Description
Since
@vueuse/headis scheduled to be deprecated, change to use@unhead/vueas in Nuxt 3.Replacing
@unhead/vuewill fix some bugs.📝 Checklist