Vue JS中的开放图元标签不显示图像

时间:2017-12-04 18:28:25

标签: facebook-graph-api vue.js vuejs2 vue-meta

我设计了一个博客,我希望在分享到社交网络时,预览图像会像Medium's帖子一样显示

<meta property="og:image" content="https://medium.com/js-dojo/getting-your-head-around-vue-js-scoped-slots-281bf82a1e4e"/>

我使用vuejs2 whith webpack和vue-meta来改变我帖子的动态图像。  但对于facbook,即使我把它们放在index.html中也没有用。

我发现this article on medium 表示有必要使用服务器端渲染,但是没有说如何从具有基本配置(没有SSR)的完全设计的项目迁移到解决问题的项目问题。结构已经不同了,我没有参考

这是我的代码vue-meta

metaInfo () {
  return {
    title: '41devs | blog',
    titleTemplate: '%s - le titre',
    meta: [
      {name: 'viewport', content: 'user-scalable=no'},
      {property: 'og:title', content: 'title'},
      {property: 'og:type', content: 'article'},
      {property: 'og:url', content: 'http://c5e3b0ec.ngrok.io/blog/s'},// here it is just ngrok for my test
      {property: 'og:description', content: 'description'},
      {property: 'og:image', content: 'https://firebasestorage.googleapis.com/v0/b/dev-blog-2503f.appspot.com/o/postsStorage%2F-KxXdvvLqDHBcxdUfLgn%2Fonfleck?alt=media&token=24a9bf5b-dce2-46e8-b175-fb63f7501c98'},
      {property: 'twitter:image:src', content: 'https://firebasestorage.googleapis.com/v0/b/dev-blog-2503f.appspot.com/o/postsStorage%2F-KxXdvvLqDHBcxdUfLgn%2Fonfleck?alt=media&token=24a9bf5b-dce2-46e8-b175-fb63f7501c98'},
      {property: 'og:image:width', content: '1000'},
      {property: 'og:site_name', content: '41devs | blog'}
    ]
  }
}

3 个答案:

答案 0 :(得分:0)

当Facebook检查您的网页以查找元数据时,他们不会运行您的Javascript。 Vue永远不会运行,您的标签永远不会被替换。这是Facebook的抓取工具的限制。

这意味着您确实必须在服务器级别渲染这些标记,无论是通过Vue的服务器端渲染还是通过其他方法(我不知道您正在运行的服务器类型)。但是,是的,最终,您必须能够将此值硬编码到您的服务器响应中,否则它将无法在Facebook中显示。

答案 1 :(得分:0)

我处理此问题的方法是创建一些中间件来解析URL路径并使用Cheerio模块动态更新元标记。

用于OG元标记信息的文件:

const products = [
  {
    id: 111111111,
    title: 'Corporate Fat Cat',
    ogImage: 'https://cdn.com/corporate.jpg',
    description: 'The fat cats in Washington don’t even look this good'
  },
  {
    id: 222222222,
    title: 'Gangsta Cat',
    ogImage: 'https://cdn.com/gangsta.jpg',
    description: 'That’s how we roll'
  },
  {
    id: 333333333,
    title: 'Mechanic Cat',
    ogImage: 'https://cdn.com/mechanic.jpg',
    description: 'I have no idea what I’m doing.'
  }
];

中间件:

app.use('/*', (req, res, next) => {
  if (/^\/api\//.test(req.originalUrl)) next();
  else if (/\/item\//.test(req.originalUrl)) updateMetaTags(req, res);
  else res.sendFile(`${__dirname}/client/dist/index.html`);
});

updateMetaTags函数:

async function updateMetaTags(req, res) {

  // Get and parse products array from app src
  const productsSrc = `${__dirname}/client/src/products.js`;
  const productsText = await fs.promises.readFile(productsSrc);
  const productsArr = JSON.parse(productsText);

  // Retrieve product object that includes the current URL item id
  const productID = (req.originalUrl.match(/\d{9}/) || [])[0];
  const productObj = productsArr.find(prod => prod.id == productID);

  // Update the meta tag properties in the built bundle w/ Cheerio
  const baseSrc = `${__dirname}/client//dist/index.html`;
  const baseHTML = await fs.promises.readFile(baseSrc);
  const $base = $(baseHTML);
  const $url = $base.find('meta[property=og\\:url]');
  const $title = $base.find('meta[property=og\\:title]');
  const $image = $base.find('meta[property=og\\:image]');
  $desc = $base.find('meta[property=og\\:description]');

  $url.attr('content', `https://${req.get('host')}${req.originalUrl}`);
  $title.attr('content', productObj.title);
  $image.attr('content', productObj.ogImage);
  $desc.attr('content', productObj.description);

  // Send the modified HTML as the response
  res.send($.html($base));
}

在此blog post中,我对此进行了详细介绍。

答案 2 :(得分:-1)

您的标题和titleTemplate结构错误。

return {
    title: 'Le titre',           // Set a current title of page
    titleTemplate: '%s - 41devs blog', // Name of your blog/website,
                                       // Title is now "Le titre - 41devs blog"
    meta: [ ...
    ]
}

它在Google https://support.google.com/webmasters/answer/79812?hl=en中的搜索引擎优化中表现最好