vueuse/head

Meta set on server side gets lost on client side

Closed this issue ยท 5 comments

Discussion: https://github.com/nuxt/framework/discussions/7785

If meta is set during SSR, client side should not manipulate it for performance reasons. At present, client side deletes the meta already set by SSR and recreates it.

We were hoping it to be fixed with Nuxt RC12 nuxt/framework#8000 but it is not. Tested on edge after this PR got merged.

Thanks @jgupta

Thanks for linking that discussion, this is a planned feature before the stable v1 release. I've put further notes in the linked discussion.

tkayo commented

we have a use case where any script tag is duplicated on client hydration when its already been rendered on the server

Hi,
i have several issues using useHead + inject dynamic fetched data into it.

Sometimes metas (injected inline css in head + title + other stuff) is renderend on server site ( i test this by only regarding source code of the page or deaktivating js on browser) and sometimes it is not. it has something to to with the fetch request.

And the client side removes title tag after it was rendered on the server side. but this should hopefully be fixed with the next rc version i guess.

This is my code:


composables / getHeadHtml.ts

const getHeadHtml =  () => {
    const route = 'https://jsonplaceholder.typicode.com/photos/1';

    const { data: getHead } = useAsyncData(
        "getHead",
        async () => {
            let response;

            try {
                response = await $fetch(route);

                const head: MetaObject = {
                    title: response.title,
                    meta: [],
                    link: [],
                    base: [],
                    style: [],
                    script: [],
                    htmlAttrs: '',
                    bodyAttrs: '',
                }

                head['style'].push({
                    'type': 'text/css',
                    'children': '.app { display: block !important; }'
                })

                useHead(head);

                return {
                    head
                }

            } catch(e) {
                console.log(e);
                return response;
            }
        });

    return {
        getHead
    };

pages/ page.vue

<template>
  <div class="app" style="display: none;">
Hello
  </div>
</template>

<script lang="ts" setup>
import getShopHtml from "~/composables/getShopHtml";

const { getHead } = getHeadHtml();

if(getHead.value) {
  useHead(getHead.value.head);
}
</script>

When i remove

if(getHead.value) {
  useHead(getHead.value.head);
}

from page the client removes title tag.

My main problem is the html i get from the server. In my real project i do not use the fake api. locally everything works fine. But in production mode the hmtl from the server is sometimes buggy. This does not concern the data in the template but the data i use in useHead() or in template tags. The object i try to create from dynamic data is always rendered correct - but the assignment to useHead (or directly injected in template via ) is not working. It seems to be a race condition between useHead / template tags and the $fetch composable in nuxt3.

Has anyone observed anything similar?

What would be the best way to get always correct rendered head html from server?
Or is this due to buggy nuxt3 rc? ( I am using the rc12)

This is now supported in v1.

@Milenoi, please try the latest v1, you may have more success. If you're still stuck please open up a new issue :)

@harlan-zw Using rc13 solved all my problems. all metas + head content is correctly rendered now in html on server side.
so glad about it.

thank you very much!