composition-api icon indicating copy to clipboard operation
composition-api copied to clipboard

feat: automatically track changes to `head` within `useFetch`

Open nicolashmln opened this issue 4 years ago • 6 comments

🐛 The bug When you edit the meta in the useFetch, once the page is loaded the metas are erased. Note: all the metas are in place when you look at the code generated from the SSR

🛠️ To reproduce Here is the sandbox https://codesandbox.io/s/cool-glitter-ykhpv

You can have a look in the pages/posts/_id.vue to see how the metas are set. I believe we can write the code like that, but please let me know if I made a mistake. Note: the title is initialized in the nuxt.config.js

When you load a page from a post (better to test in a new window and not in the sandbox UI), you can first see that the title is right, but when the page is loaded the title goes back to Test. If you look at the source generated from the SSR everything is in place, but if you inspect the code once the page is loaded you can see that the meta twitter:title is missing for example. Also, if you go from the homepage to a post (so without reloading the entire website), you can see that the title is right.

🌈 Expected behaviour The metas are kept once the page is loaded

Thank you

nicolashmln avatar Feb 22 '21 04:02 nicolashmln

@nicolashmln This is not a bug; just make sure you don't set the metadata within useFetch. However, I agree it could be nice if that worked as you have it and I'll consider adding that as a feature. For now, I would avoid setting your meta within useFetch and instead do something more like this:

setup() {
    const post = ref()

    const { $http, params } = useContext()

    const { title, meta } = useMeta()

    useFetch(async () => {
      post.value = await $http.$get(
        `https://jsonplaceholder.typicode.com/posts/${params.value.id}`
      )
    })

    title.value = post.value.title
    meta.value.push({
      hid: 'ogTitle',
      name: 'og:title',
      content: post.value.title,
    })
    meta.value.push({
      hid: 'twitterTitle',
      name: 'twitter:title',
      content: post.value.title,
    })

    useMeta({
      bodyAttrs: {
        itemtype: `http://schema.org/WebPage`,
      },
      meta: [{ hid: 'description', name: 'description', content: 'page desc' }],
    })
  }

danielroe avatar Feb 23 '21 12:02 danielroe

Okay thank you

nicolashmln avatar Feb 24 '21 06:02 nicolashmln

I've created a sandbox with your suggestion https://codesandbox.io/s/distracted-einstein-30028 and doesn't seem to work, the title is not the one from the post. Am I missing something? Note: I had to set the title like that title.value = post.value ? post.value.title : null; otherwise I had an error saying post.value is undefined

nicolashmln avatar Feb 25 '21 02:02 nicolashmln

@nicolashmln Sorry, it won't work exactly as written because on the server side the fetch hasn't yet happened. Try using the computed form of useMeta.

danielroe avatar Feb 25 '21 07:02 danielroe

I tried to run code with your suggestion but still can't get data from API and set it to meta. it doesn't seem to run sequentially. Please help

thinhnguyen1105 avatar Jul 27 '21 05:07 thinhnguyen1105

Hello, It still does not work with #530 When you refresh the page, the title is removed

jnralava avatar Dec 17 '21 23:12 jnralava