modulitos
modulitos

Reputation: 15854

How to dynamically render meta tags for social share button on a static site?

I have a static site where users can generate images and content in unlimited combinations. When the user is finished, permalink is generated to allow them to share their creation via Facebook/Twitter/GooglePlus/etc. I want their shared post to contain the user's image and content, but I discovered that the social media bots only parse HTML meta tags from my permalinks, and they do not evaluate any Javascript.

How can I make my user's content appear on the shared social media post? When the permalink is clicked, client side Javascript will evaluate the permalink's query params and render the user's content. I can render the user's content inside HTML meta tags too, which is used by Twitter and FB to populate a post's content, but the bots don't evaluate any javascript, so the meta tags are not rendered.

One possible solution that I have explored is pre-rendering. Perhaps my permalink can be the location of an HTML file on an AWS S3 bucket, which I can create as soon as the user shares their permalink. That HTML file on S3 can have the user-specific meta tags in it, and I can provide that to the social media bots. And when that file is accessed, I can have it redirect to my permalink. Does this seem reasonable? I can report back after trying this out.

Another solution is to use a pre-rendering service, like https://prerender.io/. It seems a bit bulky and black-boxed, but it might be more robust and reliable that my S3 solution above. Any ideas?

I am open to feedback and other solutions, and any suggestions would be great.


other relevant info:

This answer seems interesting, which involves activating the Facebook Javascript SDK: https://stackoverflow.com/a/34178987/1884158

And I am aware of tools like Twitter's Card Validator and Facebooks Share Debugger, here: https://cards-dev.twitter.com/validator https://developers.facebook.com/tools/debug/ which will be useful for testing any solutions.

And if it helps, my site is a React app that is bundled in HTML/CSS/JS and rendered entirely on the client.

Upvotes: 4

Views: 2641

Answers (1)

modulitos
modulitos

Reputation: 15854

I haven't found a proper solution to this problem, but I did come up with a workaround/hack that involves setting up a separate service. Here is the service that I came up with: https://github.com/mapseed/sharing/blob/master/share.js

If our static site is hosted at example.com, we can spin up a server running at sharing.example.com that accepts requests and will either redirect the request from sharing.example.com/my/route to example.com/my/route. But if the request has a user-agent HTTP header matching a social media crawler, as we are doing here, then we return an html page containing just the meta tags, as we are doing here.

This approach has a couple of restrictions, however:

  • The links that we want to share on social media need point to our sharing.example.com subdomain. This will make it possible for our service to return an HTML page with the proper meta tags if the request is coming from a social media bot, or otherwise redirect the request to our example.com website otherwise.

  • In order to generate the content of our meta tags, our shareable links will have to have query params to pass all of the information to populate our meta tags. For example, our shareable link would look like this: sharing.example.com/post/my-post?title=my-title&desc=my-description. This means that our shareable links can get quite long. You can see how we extract the information from our query params and inject it into our HTML template with the meta tags here: https://github.com/mapseed/sharing/blob/master/share.js#L18-L27

If these restrictions are acceptable, then this solution works quite well. Note that there is also a downside for SEO, because the links that will be shared are coming from sharing.example.com, and not our example.com website.

Also, we will have to spin up an extra server to run this service. Although we should be able to migrate this implementation into a serverless architecture, like AWS Lambda.

Upvotes: 3

Related Questions