Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Facebook Sharing for Single-Page Apps

Siena Aguayo
November 14, 2017

Facebook Sharing for Single-Page Apps

Facebook uses the OpenGraph tags defined on your page to populate its share dialogs. But what if you have a single-page app and you want to share many different pieces of content that technically have the same URL? Learn this One Weird Trick for sharing your beautiful content.

Presented at Fog City Ruby in San Francisco.

Siena Aguayo

November 14, 2017
Tweet

More Decks by Siena Aguayo

Other Decks in Technology

Transcript

  1. @sienatime Anatomy of a Share Dialog Facebook uses the OpenGraph

    tags on your page to make a share dialog. They are read by Facebook’s web crawler. og:title og:description og:image og:url
  2. @sienatime <head> <meta property="fb:app_id" content="fb_app_id"> <meta property="og:type" content="website"> <meta property="og:site_name"

    content="Indiegogo"> <meta property="og:title" content="Title for the share dialog"> <meta property="og:url" content="https://www.indiegogo.com/projects/2034858"> <meta property="og:description" content="This is the text that shows up in the share dialog"> <meta property="og:image" content="http://image_url"> <meta property="og:image:secure_url" content="https://image_url"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> </head> OpenGraph Tags Live in <head>
  3. @sienatime <head> <meta property="fb:app_id" content="fb_app_id"> <meta property="og:type" content="website"> <meta property="og:site_name"

    content="Indiegogo"> <meta property="og:title" content="Title for the share dialog"> <meta property="og:url" content="https://www.indiegogo.com/projects/2034858"> <meta property="og:description" content="This is the text that shows up in the share dialog"> <meta property="og:image" content="http://image_url"> <meta property="og:image:secure_url" content="https://image_url"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> </head> OpenGraph Tags Live in <head>
  4. @sienatime Works Great for Sharing the Whole Page og:url =

    https://www.indiegogo.com/projects/2034858
  5. @sienatime Single-Page App: Angular States Default State (Story) indiegogo.com/…#/ All

    Updates indiegogo.com/…#/updates/all Single Update indiegogo.com/…#/updates/1
  6. @sienatime The Problem with Sharing Single-Page Apps • Facebook doesn’t

    run your JavaScript, so meta tags must be rendered by the server. This means no manipulation of your tags by the client • Anything after the # (anchor/fragment) part of the URL doesn’t get sent to the server, and this is How The Internet Works, so the server doesn’t know what part of your app you’re on • Facebook Share Dialogs can’t be set programmatically via JavaScript
  7. @sienatime There Lies a Hint in User Agents... User agent

    strings are part of a web request used to identify what is being used to access your page. • Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36 • Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) CriOS/30.0.1599.12 Mobile/11A465 Safari/8536.25 (3B92C18B-D9DE-4CB7-A02A-22FD2AF17C8F) • facebookexternalhit/1.1
  8. @sienatime Facebook Corroborates Our Idea... “You can target one of

    these user agents to serve the crawler a nonpublic version of your page that has only metadata and no actual content. This helps optimize performance and is useful for keeping paywalled content secure.” https://developers.facebook.com/docs/sharing/webmasters/crawler/#identify
  9. @sienatime All Metadata, No Content New page: https://www.indiegogo.com/projects/2034858/updates/1 Are you

    the Facebook crawler? Have some metadata! You’re not? Redirect to the right Angular state!
  10. @sienatime Have a Flow Chart https://www.indiegogo.com/projects/2034858/updates/1 Facebook Crawler? Render metadata-only

    page Yes <head> <meta property="fb:app_id" content="fb_app_id"> <meta property="og:type" content="website"> <meta property="og:site_name" content="Indiegogo"> <meta property="og:title" content="Title for the share dialog"> <meta property="og:url" content="https://www.indiegogo.com/facebook_open_graph"> <meta property="og:description" content="This is the text that shows up in the share dialog"> <meta property="og:image" content="http://image_url"> <meta property="og:image:secure_url" content="https://image_url"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> </head> Redirect to normal page No
  11. @sienatime Some Controller Code 1 class FacebookOpenGraphController < ApplicationController 2

    before_filter :redirect_unless_facebook_bot, only: :show 3 4 def show 5 # layout: false will just render this template, not this template 6 # inside of your regular application layout (views/layouts/application.html.erb) 7 render "my_layout", layout: false 8 end 9 10 private 11 12 def facebook_social_crawler? 13 user_agent = request.env['HTTP_USER_AGENT'] 14 user_agent.present? && user_agent.include?('facebookexternalhit') 15 end 16 17 def redirect_unless_facebook_bot 18 return if facebook_social_crawler? 19 redirect_to url_within_single_page_app 20 end 21 end
  12. @sienatime New Share Dialog Share buttons on the same page,

    but they share different content! og:title og:description og:image og:url