我在 Nuxt 3 中有一个博客,每个博客内容以及元数据都是通过 api 响应呈现的。问题是,当我在社交媒体上分享博客时,它不显示 API 响应中收到的任何元数据,而只显示在
app.vue
文件内声明的静态元数据。当我通过浏览器开发工具中的“检查元素”选项卡检查元标记时,我可以在那里看到所有必需的数据。
// pages/blog/[slug].vue
<script setup>
import { onMounted, ref, defineProps } from 'vue';
import { useBlogStore } from '~/stores/blog';
import config from '~/app.config.ts'
const route = useRoute()
const blogStore = useBlogStore(); // Create an instance of the blog store
const blog = ref([]);
const { currentRoute } = useRouter();
onMounted(async () => {
try {
await blogStore.getBlog(route.params.slug); // Call the getBlogs action
blog.value = blogStore.$state.blog; // Update the local ref with the fetched data
} catch (error) {
console.log(error);
}
useHead({
title: blog.value.title,
meta: [
{ name: 'description', content: blog.value.meta_description },
{ name: 'keywords', content: blog.value.keywords },
{ name: 'og:image', content: blog.value.image_url },
{ name: 'og:title', content: blog.value.title },
{ name: 'og:description', content: blog.value.meta_description },
{ name: 'og:type', content: 'article' },
{ name: 'og:url', content: config.web.baseURL + currentRoute.value.fullPath },
{ name: 'twitter:card', content: 'summary_large_image' },
{ name: 'twitter:url', content: config.web.baseURL + currentRoute.value.fullPath },
{ name: 'twitter:title', content: blog.value.title },
{ name: 'twitter:description', content: blog.value.meta_description },
{ name: 'twitter:image', content: blog.value.image_url },
],
})
});
</script>
// app.vue
<script setup>
definePageMeta({
colorMode: 'dark',
})
useHead({
title: 'My Title',
meta: [
{ name: 'description', content: 'Nuxt app meta description for SEO!' },
{ name: 'theme-color', content: '#000000' },
],
})
</script>
我已经经历过几次这样的事情,但后来我明白了。 首先您必须确保使用正确的可组合项来获取 api,例如 useAsyncLazyData 和 useLazyFetch。
在此处阅读相关内容:https://nuxt.com/docs/api/composables/use-lazy-async-data
第二您可以使用nuxt提供的元标记并根据您的需要进行设置
这里关于 nuxt 的元标记:https://nuxt.com/docs/api/composables/use-lazy-async-data
例如:
<script setup>
// ... import section
definePageMeta({
hidden: true,
});
const { data, pending } = await useLazyAsyncData(
`products/${route.params.id}`,
() =>
$fetch(`${useRuntimeConfig()?.public.apiUrl}/products/${route.params.id}`, {
method: "get",
}),
{
transform: (payload) => payload?.result || null,
watch: false,
}
);
</script>
<template>
<div>
<n-skeleton v-if="pending" type="card" height="250px"></n-skeleton>
<section v-else>
<Head>
<Title>{{ data?.title }}</Title>
<Meta name="canonical" :content="url.origin" />
<Meta name="description" :content="data?.description" />
<Meta name="og:title" :content="data?.title" />
<Meta name="og:description" :content="data?.description" />
<Meta name="og:image" :content="data?.client?.picture" />
<Meta name="twitter:title" :content="data?.title" />
<Meta name="twitter:description" :content="data?.description" />
<Meta name="twitter:image" :content="data?.client?.picture" />
<Meta name="twitter:card" content="summary_large_image" />
</Head>
<ClientOnly>
<molecules-product :data="data" :pending="pending" />
</ClientOnly>
</section>
<br />
<br />
</div>
</template>
可能对你有帮助...