我正在开发一个 Vue.js 应用程序,我需要根据从 API 获取的数据动态设置开放图谱 (OG) 元标记。 OG 标签对于社交媒体共享(例如 Facebook、WhatsApp)是必需的。我面临的问题是元标记,特别是 og:image,是在 API 调用完成之前设置的,导致最初的图像 URL 为空。共享页面时,将使用带有空图像 URL 的元标记,而不是更新的元标记。
这是我当前的代码:
<template>
<div v-if="dataFetched">
<div class="m-5 md:mx-28">
//template code continues here
//vue main script
<script setup>
import { ref, onMounted, watch, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useSeoMeta } from '@vueuse/head';
import DetailHeader from "~/components/listing-detail/DetailHeader.vue";
import DetailPictures from "~/components/listing-detail/DetailPictures.vue";
import DetailOverview from "~/components/listing-detail/DetailOverview.vue";
import DetailProperty from "~/components/listing-detail/DetailProperty.vue";
import DetailMap from "~/components/listing-detail/DetailMap.vue";
import DetailLocation from "~/components/listing-detail/DetailLocation.vue";
import DetailNearby from "~/components/listing-detail/DetailNearby.vue";
import DetailCalculator from "~/components/listing-detail/DetailCalculator.vue";
const axios = useNuxtApp().$axios;
defineProps({ id: String });
// Initialize data
const dataItem = ref([]);
const currentItem = ref(null);
const nearby_places = ref([]);
const dataFetched = ref(false);
const route = useRoute();
const router = useRouter();
const { nametitle } = route.params;
const nametitleValues = nametitle.split('-').map(value => value.replace(/-/g, ' '));
const title = nametitleValues.join(' ') + ' | A-plus Property Consultants';
const ogTitle = title;
const description = 'Discover ' + title + ', available on A-plus Property Consultants. Explore this property today!';
const ogDescription = description;
const ogImageUrl = ref('');
const currentUrl = 'https://aplus2.vercel.app' + route.fullPath;
const ogImageWidth = ref(32);
const ogImageHeight = ref(32);
const fetchData = async () => {
let url = `${apiEndpoint}?propertySEF=${nametitle}`;
try {
const response = await axios.get(url);
dataItem.value = response.data.listing;
currentItem.value = response.data.listing;
if (dataItem.value[0]?.property_nearby_place) {
nearby_places.value = JSON.parse(dataItem.value[0].property_nearby_place);
}
if (dataItem.value[0]?.photo?.[0]?.photo_file) {
ogImageUrl.value = `https://staging.aplussharing.com/storage/uploads/property/${dataItem.value[0].photo[0].photo_file}`;
}
dataFetched.value = true;
} catch (error) {
router.push({ name: "404" });
}
};
onMounted(() => {
fetchData();
});
watch(dataFetched, (newValue) => {
if (newValue) {
useSeoMeta({
title,
ogTitle,
description,
ogDescription,
ogImage: ogImageUrl.value,
ogUrl: currentUrl,
ogImageWidth: ogImageWidth.value,
ogImageHeight: ogImageHeight.value,
ogType: 'website',
});
}
},{immediate:true});
</script>
问题: OG 元标记(尤其是 og:image)在 API 调用完成之前呈现,导致 og:image URL 为空。在社交媒体上共享页面时,将使用初始(空)元标记。
目标: 我想阻止元标记的渲染,直到 API 调用完成并且 og:image URL 可用。如何确保元标记仅在获取数据后才设置?
任何帮助或建议将不胜感激!
看看这是否适合您。查看源代码(Ctrl + U)检查元值是否填充了API中的数据。 要使用 SEO,请确保您在 SSR 模式下运行。
<template>
<div>
<div class="m-5 md:mx-28">
template code continues here
</div>
</div>
</template>
//vue main script
<script setup>
const { data, pending, error, refresh } = await useFetch('https://jsonplaceholder.typicode.com/posts/1', {
method: "GET"
})
useServerSeoMeta({
title: () => data.value.title || "any default value",
description: () => data.value.description || "any default description value",
ogUrl: () => data.value.ogUrl || "any default ogUrl value",
ogTitle: () => data.value.ogTitle || "any default ogTitle value",
ogDescription: () => data.value.ogDescription || "any default ogDescription value",
ogImage: () => data.value.ogImage || "any default ogImage value",
ogType: () => data.value.ogType || "any default ogType value",
ogLocale: () => data.value.ogLocale || "any default ogLocale value",
twitterCard: () => data.value.twitterCard || "any default twitterCard value",
twitterTitle: () => data.value.twitterTitle || "any default twitterTitle value",
twitterDescription: () => data.value.twitterDescription || "any default twitterDescription value",
twitterImage: () => data.value.twitterImage || "any default twitterImage value",
})
</script>