Porotype Notes from a Vaadineer

Sharing Vaadin applications on Facebook

image

Have you ever wondered where the little ‘preview’ thumbnail comes from when you share links on Facebook (and G+), and how you might go about customising that for your Vaadin application? Read on!

Facebook actually crawls the page you share for suitable images, but this does not always work out in an optimal way. For instance, since Vaadin applications are loaded dynamically, Facebook previews do not work at all. Fortunately you can get around this by customising the Vaadin ‘bootstrap’ page - or any web page for that matter, but we’ll look at how to do it with Vaadin.

Facebook allows you to customise how it sees your page, by using Open Graph tags. You can read all about them here: https://developers.facebook.com/docs/opengraph/howtos/maximizing-distribution-media-content

Basically what you want to do is add a few meta-tags - the most interesting one being og:image, which specifies the preview image. But why stop there, let’s add the basic set:

  • og:title – The title of your article, excluding any branding.
  • og:site_name - The name of your website. 
  • og:url – This URL serves as the unique identifier for your post. 
  • og:description – A detailed description of the piece of content, usually between 2 and 4 sentences.
  • og:image – This is an image associated with your media. We suggest that you use an image of at least 1200x630 pixels.

First we should add the appropriate namespace xmlns:fb=“http://ogp.me/ns/fb# for the head-tag, then add the og-tags as meta-tags. 

In order to do this in Vaadin, we need to make a BootstrapListener and add it to our VaadinSession, all of which can be done in a SessionInitListener added to our VaadinServletService in an overridden servletInitialized(). Phew! Let see that in code, please:


public static class Servlet extends VaadinServlet {
  protected void servletInitialized() throws ServletException {
    super.servletInitialized();
    getService().addSessionInitListener(new SessionInitListener() {
      public void sessionInit(SessionInitEvent event) throws ServiceException {
        event.getSession().addBootstrapListener(new SharePreviewBootstrap());
      }
    });
  }
}

Yes, that’s quite a bit of boilerplate - I’m considering making this into an add-on to avoid that.

But let’s move on.

In the Bootstrap listener, all you need to do is modify the bootstrap page in modifyBootstrapPage(). You can add the namespace like so:

Element head = response.getDocument().head()
head.attr("xmlns:fb", "http://ogp.me/ns/fb#");

And then add the meta-tags like this:

Element meta = new Element(Tag.valueOf("meta"), "");
meta.attr("property", "og:image"); 
meta.attr("content",“”);
head.appendChild(meta);

Repeat that for all the Open Graph tags you want to add, then deploy, then enter your applications url in the share-box on Facebook, and voila: preview. Well, as long as you remembered to deploy the actual image too…

You can try it by sharing this example (note that you do not actually have to press ‘share’, just enter the url): http://marc.app.fi/SharePreview/

G+ does the same thing, by the way - and probably some other sites, let me know your findings.

Also feel free to ‘view source’ for the example application to see all the tags added. 

You should also try the Facebook debugger, which will take a look att your url, and tell you what is good and what is not: https://developers.facebook.com/tools/debug/

One more detail: You can dynamically choose which image to show depending on the request. You might for instance want to send a different one for different sections:

String path = response.getRequest().getPathInfo();
if (path != null & path.endsWith(…) {
	// send the desired tags
}

Or you might want to do all of this just for Facebook, in which case you can use the User-Agent:

String ua = response.getRequest().getHeader("User-Agent");
if (ua.startsWith(“facebookexternalhit”)) {
	// It’s Facebook! Crawling!
}

Happy sharing!

And let me know if you’d like this to be a add-on or something!