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. Facebook Sharing for
    Single-Page Apps
    Siena Aguayo
    @sienatime
    Software Engineer
    Indiegogo

    View Slide

  2. @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

    View Slide

  3. @sienatime





    content="https://www.indiegogo.com/projects/2034858">






    OpenGraph Tags Live in

    View Slide

  4. @sienatime





    content="https://www.indiegogo.com/projects/2034858">






    OpenGraph Tags Live in

    View Slide

  5. @sienatime
    Works Great for Sharing the Whole Page
    og:url = https://www.indiegogo.com/projects/2034858

    View Slide

  6. @sienatime
    But what if our
    use case is more
    complicated?

    View Slide

  7. @sienatime
    The Problem: Multiple Share Buttons

    View Slide

  8. @sienatime
    Single-Page App: Angular States
    Default State (Story)
    indiegogo.com/…#/
    All Updates
    indiegogo.com/…#/updates/all
    Single Update
    indiegogo.com/…#/updates/1

    View Slide

  9. @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

    View Slide

  10. @sienatime
    What to do???

    View Slide

  11. @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

    View Slide

  12. @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

    View Slide

  13. @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!

    View Slide

  14. @sienatime
    Have a Flow Chart
    https://www.indiegogo.com/projects/2034858/updates/1
    Facebook Crawler?
    Render metadata-only page
    Yes












    Redirect to normal page
    No

    View Slide

  15. @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

    View Slide

  16. @sienatime
    The Solution: Multiple Share Buttons
    https://www.indiegogo.com/projects/2034858/updates/1
    https://www.indiegogo.com/projects/2034858

    View Slide

  17. @sienatime
    New Share Dialog
    Share buttons on the same page, but
    they share different content!
    og:title
    og:description
    og:image
    og:url

    View Slide

  18. @sienatime
    Other Handy Tools
    ● Facebook’s OpenGraph Debugger https://developers.facebook.com/tools/debug/sharing
    ● Test locally with localtunnel https://github.com/localtunnel/localtunnel

    View Slide

  19. @sienatime
    Thanks!

    View Slide