useSeoMeta в Nuxtjs 3

У меня на сайте имеется страница всех новостей, а также под каждую новость индивидуальная страница.

При переходе на страницу с новостью, отправляется POST (через функцию $fetch) в /api/feed с идентификатором новости. Данные приходят, выводятся на странице, с этим всё ок.

Проблема возникает, когда я хочу использовать useSeoMeta после запроса. Выпадает ошибка:

[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at https://nuxt.com/docs/guide/concepts/auto-imports#vue-and-nuxt-composables.

Код:

async created() {
    const { data: data } = await useAsyncData("mountains", () =>
    $fetch("/api/feed", {
        method: "post",
        body: JSON.stringify({ feed: this.feed }),
        headers: {
            "content-type": "application/json",
        },
     });
   );
   useSeoMeta({
       title: "Тайтл с новости",
       description: "Дескрипшн с новости",
   });
}

Как сделать установку тайтлов после fetch запроса?


Ответы (2 шт):

Автор решения: Mr.Fokuss

В документации Nuxt есть пример использования для Options-API https://nuxt.com/docs/migration/meta#options-api. В вашем случае можно сделать так:

<script>
import {defineNuxtComponent} from "#app";

export default defineNuxtComponent({
  head(nuxtApp){
    return {
      title: "Тайтл с новости",
      description: "Дескрипшн с новости",
    }
  },
  data() {
    return {
      feed:'dfbdefbdbd',
    }
  },
  async created() {
    const {data: data} = await useAsyncData("mountains", () =>
        $fetch("/api/feed", {
          method: "post",
          body: JSON.stringify({feed: this.feed}),
          headers: {
            "content-type": "application/json",
          },
        })
    );
  },
})
</script>

Если вам необходимо динамически изменять мета-данные, то это можно сделать через store

РЕДАКТИРОВАНО Попробовал другой вариант и он для меня сработал. В данном варианте можно динамически менять meta, но выполняется это на клиенте, что не очень хорошо для браузеров, да и заметно, что title меняется

<script>
import {defineNuxtComponent} from "#app";

export default defineNuxtComponent({
  data() {
    return {
      feed:'dfbdefbdbd',
      title:'',
      description:''
    }
  },
  async created() {
    const {data: data} = await useAsyncData("mountains", () =>
        $fetch("/api/feed", {
          method: "post",
          body: JSON.stringify({feed: this.feed}),
          headers: {
            "content-type": "application/json",
          },
        })
    );
    if (process.client){
      this.title = "Тайтл с новости"
      useSeoMeta({
        title:this.title
      })
    }
  },
})
</script>
→ Ссылка
Автор решения: eri

В описании ошибки предлагают использовать useSeoMeta в setup, что то в стиле (пишу по памяти, не проверял синтаксис):

export default {

  async setup() {
    const route = useRoute()
    const {data:data} = await useFetch("/api/feed", {
        method: "post",
        body: JSON.stringify({ feed: route.params.feed }),
        headers: {
            "content-type": "application/json",
        },
     })
    useSeoMeta({
       title: data.title,
       description: data.description,
   });

  return {data}
  }

}

feed забираем сразу в setup, из него fetch и сразу мета. Нет смысла выносить что-то из этого в хуки created, mounted, data - совсем не вижу. На полностью отрисованный в ssr документ боты будут рады.

Для реактивности на клиенте можно обернуть что нужно в ref

→ Ссылка