如何在 Vue.js 中延迟 Open Graph 元标记的渲染,直到 API 调用完成?

问题描述 投票:0回答:1

我正在开发一个 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 可用。如何确保元标记仅在获取数据后才设置?

任何帮助或建议将不胜感激!

javascript vue.js dom meta-tags
1个回答
0
投票

看看这是否适合您。查看源代码(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>
© www.soinside.com 2019 - 2024. All rights reserved.