nuxt / vue-meta

Manage HTML metadata in Vue.js components with SSR support
https://vue-meta.nuxtjs.org
Other
4.08k stars 247 forks source link

Help needed: How do I use this for facebook open graph meta. #133

Closed jofftiquez closed 5 years ago

jofftiquez commented 7 years ago

Currently I am trying :

metaInfo() {
  return {
    title: 'Memes are the best',
    meta: [
      {vmid: 'og:description', property: 'og:description', name:'description', content: 'Wow'}
    ]
  }
}

But whenever I test it with fb open graph debugger it can't scrape the meta information.

deadelus commented 7 years ago

Did find an issue ? I'im trying to do the same and I'm getting the same errors.. Thx :)

jofftiquez commented 7 years ago

@deadelus no one's answering yet.

deadelus commented 7 years ago

I found an issue here https://github.com/jvandemo/angular-update-meta/issues/13

jofftiquez commented 7 years ago

@deadelus nice, thanks!

deadelus commented 7 years ago

Try this one too : https://github.com/chrisvfritz/prerender-spa-plugin

jofftiquez commented 7 years ago

Thanks!

On Tue, Nov 14, 2017 at 11:32 AM, Trambolho Geoffrey < notifications@github.com> wrote:

Try this one too : https://github.com/chrisvfritz/prerender-spa-plugin

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/declandewet/vue-meta/issues/133#issuecomment-344135923, or mute the thread https://github.com/notifications/unsubscribe-auth/AIPPI-N8PTTlV6EgHgeBZGBMFMGSS1P2ks5s2Qm-gaJpZM4PFZ1R .

coolemur commented 6 years ago

Need a simpler solution than using SSR...

vvasic commented 6 years ago

add quotes and move vmid to the end

metaInfo() {
  return {
    title: 'Memes are the best',
    meta: [
      { 'property': 'og:description', 'content': 'Wow', 'vmid': 'og:description'}
    ]
  }
}
kont-wayfinder commented 6 years ago

Any solution for this? I have tried using prerender-spa-plugin.

My site is showing the open graph meta tags, however facebook debugger is not crawling my metas?

mfdeux commented 6 years ago

@kont-wayfinder You should check to see if the tags are being rendered without JS.

eeerrrttty commented 6 years ago

Is this vue-meta working with facebook? If not i won't even install it

smcstewart commented 6 years ago

This is not an issue with vue-meta, it's an issue with how social media crawlers handle Single Page Apps. There's nothing vue-meta can do to fix this. Social media crawlers do not run Javascript when they scrape your site for meta info to use when sharing. You have three options:

  1. Use Server Side Rendering;
  2. Pre-render using whatever tools you like;
  3. In your CDN or web server, detect when a social media crawler is hitting your site, then fetch a response on your server and return a generated page (or at least meta info) instead of the normal JS page.

All options have trade-offs, but 3) above means adding code elsewhere and not changing anything you've already got which for me, is a good solution as I can continue to write the rest of my app without the intricacies of SSR or Pre-rendering. However, you need to choose something for your situation.

Just as an aside, most search engines these days will actually run Javascript when they're indexing your site, so vue-meta will inject into your page correctly before the crawler "reads" your page. Social media crawlers may follow suit at some point.

SamJWeissman commented 6 years ago

@smcstewart

Potentially stupid question -- but how do you detect when a crawler is hitting your site?

smcstewart commented 6 years ago

When a request is made to your site you can check the user-agent header in the request for the user agents used by which ever social networks you want to share with. For example, Facebook: facebookexternalhit or Facebot, Twitter: Twitterbot, LinkedIn: LinkedInBot. Other networks will have details in their own developer docs. If the user agent starts with one of these strings, then you have a social media crawler and you can take some action. Otherwise, just pass the request on as normal.

SamJWeissman commented 6 years ago

@smcstewart

Awesome, thank you!

eluminous40 commented 6 years ago

How we can do it in VUE JS? @SamJWeissman Have you found any way to do it?

smcstewart commented 6 years ago

@eluminous40 Unfortunately, you can't right now. Social media crawlers currently do not run Javascript when they scrape your site for meta info. For Vue to have any hope of doing this, the crawlers need to either run Javascript or you need to render your page before the browser using either server-side rendering or pre-rendering.

eluminous40 commented 6 years ago

@smcstewart , Thank for reply. Do you have any idea how we can make it possible in VUE JS?

smcstewart commented 6 years ago

@eluminous40 Short of getting the social media crawlers to run Javascript before they scrape content, no. Common problem with SPAs based on Javascript, not just Vue.

SamJWeissman commented 6 years ago

@eluminous40

My project from the beginning has been broken up into two projects, the client side and server side code. I didn't want to completely swap over to server side rendering so I implemented a semi-hacky solution. With that being said, I'm not positive the implications my changes will have on search results in the future. But for rich previews, it works fine.

My front end is served using Express, so I added a small bit of logic to check whether the request is coming from a crawler. If it is, I make a request to "preview routes" that exist on my server side code. The preview routes fetch whatever data is required, and then send pre-constructed HTML ( essentially, the meta tags I need for a rich preview ) back to the front end.

Not necessarily the greatest solution, but it works fine in the meantime until I can go back and potentially re-implement server side rendering as a whole.

robsonsobral commented 6 years ago

Another 3 options:

  1. use Prerender.io;
  2. install the OpenSource version of Prerender on your server;
  3. use a hosting which offers prerender for social networks crawlers.
jofftiquez commented 6 years ago

@robsonsobral prerender is the way. One of our website uses it. www.fortcupine.com

coolemur commented 6 years ago

@jofftiquez Will prerender work for dynamic data ? For example if you have a list of products in your website that might change frequently.

jofftiquez commented 6 years ago

@coolemur as far as what I have experienced, no, it doesn't accommodate dynamic data. If that's the case, you might want to consider SSR instead.

robsonsobral commented 6 years ago

@coolemur , yes, it does. You can set window.prerenderReady to false until the parsing of API data is ready.

jofftiquez commented 6 years ago

@robsonsobral Interesting, how will it behave if I, say, requested a new list of data from the server?

robsonsobral commented 6 years ago

If prerender find prerenderReady === false, it will wait until its value turns true.

You can add <script>prerenderReady = false;</script> to the default index.html and change it after the page on every route be ready.

jofftiquez commented 6 years ago

@robsonsobral nice! Thanks!

eeerrrttty commented 6 years ago

There isn't a way to when facebook checks your link to find meta info to run some restfull code in the server side with a facebook's request then send it a response with the meta infos of that paga?!!!!

This should be a simples link request from facebook what would contain the id of the dynamic data, so in our server we could handle it then respond with meta info.

Is that possible?!

SamJWeissman commented 6 years ago

@eeerrrttty

https://github.com/declandewet/vue-meta/issues/133#issuecomment-435856380

eeerrrttty commented 6 years ago

Well, but how does facebook send this request when it finds my http link in his site?!

eeerrrttty commented 6 years ago

and how does it require the answer to be?

SamJWeissman commented 6 years ago

@eeerrrttty

Client Side Receiving Request:

// Client Code Using Express
return https.get(YOUR_PREVIEW_ENDPOINT, (response) => {
      response.on('data', (data) => {
        res.send(data.toString('utf8'));
      });
    }).on('error', (e) => {
      console.log(e);
    });
valentinoli commented 4 years ago

I implemented the proposed solution of detecting the social media crawler in Express, as @SamJWeissman did. Here is what I did if it helps someone:

Vue app Express server

const express = require('express')
const axios = require('axios')

const app = express()

const { API_URL } = process.env
const SOCIAL_MEDIA_CRAWLERS = /^(facebookexternalhit|Facebot|Twitterbot)/i

app.use(async (req, res, next) => {
  const { ['user-agent']: ua } = req.headers
  if (SOCIAL_MEDIA_CRAWLERS.test(ua)) {
    const { data, error } = await axios.get(
      `${API_URL}/meta?path=${req.path}&host=${req.hostname}`
    )
    if (error) {
      console.error(error)
      return next()
    }
    return res.send(data)
  }
  next()
})

API Express server

app.use('/meta', (req, res) => {
  const { host, path } = req.query
  // some logic
  res.send(`
    <!DOCTYPE html>
    <html>
      <head prefix="og: https://ogp.me/ns#">
        <!-- some metatags -->
      </head>
      <body></body>
    </html>
  `);
}

I passed the host and path fields for the og:url open graph property.

However, now I have abandoned this solution and instead I do prerendering to tackle the issue and at the same time improve SEO.