Открыть график метатеги в Vue JS не показывают изображение
Я создаю блог, и мне бы хотелось, чтобы при публикации в социальных сетях изображение предварительного просмотра отображалось как в сообщениях Medium.
<meta property="og:image" content="https://medium.com/js-dojo/getting-your-head-around-vue-js-scoped-slots-281bf82a1e4e"/>
Я использовал vuejs2 с webpack и vue-meta, чтобы изменить динамическое изображение моего поста. Но для facbook там не работает, даже когда я помещаю их в index.html.
Я нахожу эту статью в среде, где говорится, что необходимо использовать серверную визуализацию, но не говорится, как перейти от полностью разработанного проекта с базовой конфигурацией (без 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'}
]
}
}
2 ответа
Когда Facebook проверяет вашу страницу, чтобы найти метаданные, они не запускают ваш Javascript. Vue никогда не запускается, ваши теги никогда не заменяются. Это ограничение сканера Facebook.
Это означает, что вам действительно придется отображать эти теги на уровне сервера, будь то с помощью рендеринга на стороне сервера Vue или каким-либо другим способом (я не знаю, какой тип сервера вы используете). Но да, в конечном счете, вы должны иметь возможность жестко закодировать это значение в ответе вашего сервера, иначе оно не будет отображаться в Facebook.
Я решил создать промежуточное ПО, которое анализирует путь 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));
}
Ваши title и 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: [ ...
]
}
Это было сделано для лучшего SEO в Google https://support.google.com/webmasters/answer/79812?hl=en