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 шт):
В документации 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>
В описании ошибки предлагают использовать 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