mozilla / ensemble

The platform that powers the Firefox Public Data Report :violin: :trumpet: :musical_keyboard:
https://data.firefox.com/
Mozilla Public License 2.0
21 stars 14 forks source link

Add OpenGraph/Twitter tags for better sharing #96

Open pdehaan opened 6 years ago

pdehaan commented 6 years ago

Here's a prettified version of the generated+minified build/index.html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no" />
    <meta name="theme-color" content="#ffffff" />
    <link rel="manifest" href="/manifest.json" />
    <link rel="icon" type="image/png" sizes="196x196" href="/icons/favicon-196.png" />
    <link rel="shortcut icon" href="/icons/favicon.ico" />
    <title>Firefox Public Data Report</title>
    <link href="/static/css/main.7337a89f.css" rel="stylesheet" />
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root" />
    <script type="text/javascript" src="/static/js/main.25ecaea0.js" />
  </body>
</html>

At a minimum, we should probably add a meta description tag, but the Facebook OpenGraph should probably add a few more og:* tags to be more "share" friendly. Similarly, here's the Twitter card validator: https://cards-dev.twitter.com/validator.

I think Open Graph/Facebook is able to infer some of the meta tags, but probably best to explicitly set them to the values you want/expect:

Based on the raw tags, we constructed the following Open Graph properties

NAME: VALUE:
og:url https://moz-ensemble.herokuapp.com/dashboard/user-activity
og:type website
og:title Firefox Public Data Report
og:updated_time 1523295522
og:description  

Here's a random copy-pasta of a mozilla.org meta tags:

    <meta name="description" content="Did you know? Mozilla — the maker of Firefox — fights to keep the Internet a global public resource, open and accessible to all.">
    <meta property="og:type" content="website">
    <meta property="og:site_name" content="Mozilla">
    <meta property="og:locale" content="en_US">
    <meta property="og:url" content="https://www.mozilla.org/en-US/">
    <meta property="og:image" content="https://www.mozilla.org/media/img/mozorg/mozilla-256.4720741d4108.jpg">
    <meta property="og:title" content="Internet for people, not profit">
    <meta property="og:description" content="Did you know? Mozilla — the maker of Firefox — fights to keep the Internet a global public resource, open and accessible to all.">
    <meta property="fb:page_id" content="262134952380">
    <meta name="twitter:card" content="summary">
    <meta name="twitter:site" content="@mozilla">
    <meta name="twitter:domain" content="mozilla.org">
    <meta name="twitter:app:name:googleplay" content="Firefox">
    <meta name="twitter:app:id:googleplay" content="org.mozilla.firefox">
    <meta name="twitter:app:name:iphone" content="Firefox">
    <meta name="twitter:app:id:iphone" content="989804926">
    <meta name="twitter:app:name:ipad" content="Firefox">
    <meta name="twitter:app:id:ipad" content="989804926">
pdehaan commented 6 years ago

These may be an OK starting point:

<meta name="description" content="The Firefox Public Data Report is a weekly public report on the activity, behavior, and hardware configuration of Firefox users." />
<meta property="og:description" content="The Firefox Public Data Report is a weekly public report on the activity, behavior, and hardware configuration of Firefox users." />
<meta property="og:image" content="??" />
<meta property="og:locale" content="en_US" />
<meta property="og:site_name" content="Firefox Public Data Report" />
<meta property="og:title" content="Firefox Public Data Report" />
<meta property="og:type" content="website" />
<meta property="og:url" content="??" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:description" content="The Firefox Public Data Report is a weekly public report on the activity, behavior, and hardware configuration of Firefox users." />
<meta name="twitter:domain" content="??" />
<meta name="twitter:site" content="@mozilla" />
<meta name="twitter:title" content="Firefox Public Data Report" />
<title>Firefox Public Data Report</title>

There is a fair bit of duplication between the HTML meta tags and the og:* and twitter:* tags, but not sure it's worth the overhead of trying to create ./public/index.html from default values in package.json using mustache or something.

A few open questions still though:

  1. Re: og:image, we may only need this if we want some thumbnail to appear on Facebook (and whatever other services may consume OpenGraph data, like Google, etc).
  2. Re: og:url, I think this needs to be a fully qualified canonical URL. Per http://ogp.me/#metadata, "The canonical URL of your object that will be used as its permanent ID in the graph, e.g., 'http://www.imdb.com/title/tt0117500/'.". I'm not sure how to get the canonical URL, given that this is currently deployed in two places (https://moz-ensemble.herokuapp.com and https://metrics.mozilla.com/protected/usage-report-demo/). But once this is released it will obviously only be at a single location, so maybe we can hardcode the domain since it looks like %PUBLIC_URL% is relative and not an absolute URL.
  3. Re: twitter:domain, same as above. Not sure what the final URL for this service will be.
  4. Note sure if we want a twitter:image. Probably depends if we (a) want og:image (see (1) above), and if we want a similar Facebook vs Twitter experience.

openjck commented 6 years ago

Good catch. Thank you.

pdehaan commented 6 years ago

Similarly, here are some random observations and <meta> style tags from the Firefox Hardware Report page:

<meta name="google-site-verification" content="YG61noZtCoZSUnSTYOkgdyYFK3HFXZSG8-ZMMnfGugU">
<script async="" src="//www.google-analytics.com/analytics.js"></script>

PS: I'm not saying those are needed or mandatory, just noting that the previous site had them, and wondered if we should do a similar Google Site Verification hash or if we need/have Google Analytics (or similar logging to track, whatever we're tracking with that metric).

openjck commented 6 years ago

The only tag that may be tricky might be og:image.

@rafrombrc, do we think we could get an artist to put together a pretty badge for the site for use on social media? Here's the one we use on the Hardware Report. I don't see a lot of documentation about the reccommended size for such an image (correct me if I'm wrong @pdehaan) other than Facebook's recommendation that shared images in general should be at least 1200 x 630.

openjck commented 6 years ago

Even before we get something professional, I could probably put something together that mirrors the Hardware Report image: that is, a blurred image of the site itself as the background with the words "Firefox Public Data Report" on top in Mozilla's preferred font.

pdehaan commented 6 years ago

Ah, I was going to file a new issue for this, but maybe I can just piggy back off this issue.

Was trying to run the Twitter Card validator and Open Graph validators against the pending Production site, and got the following curiousity from Open Graph:

Warnings That Should Be Fixed

TYPE DESCRIPTION
Inferred Property The 'og:image' property should be explicitly provided, even if a value can be inferred from other tags.
Missing Properties The following required properties are missing: og:url, og:type, og:title, og:image, og:description, fb:app_id

I was initially confused, because I recalled seeing an og:image tag in the <head>:

<link rel="og:image" href="/img/ogimage.png">

Although, I reckon that should be a <meta property="og:image /> and not a <link rel="">:

<meta property="og:image" content="/img/ogimage.png" />

I cannot recall the exact behavior for og:image, but some sources online seem to imply that it won't accept relative URLs and we'd need to make this absolute (either by hard-coding, or setting a custom domain via ENV var per server).


Actually, I can see the correct, fully qualified meta tag in the repo, so maybe we just dont have the latest bits on production's "coming soon".

openjck commented 6 years ago

Yes, exactly. Although it's true that we're not yet providing og:url and all the rest, I did correct og:image in 71664dca8bb299893a26b96163f5a85545dec3fe and f81509d292181c4d206ee1fb7e5270b6d5f848ba. We're going to push the latest master to stage and prod tomorrow morning.

Thanks for your attention to detail!

I'm hoping social media will make sensible inferences about the rest, but if you think there's a pressing need for them we can try to get them in before launch.

openjck commented 6 years ago

I went ahead and added a few more OpenGraph tags. I'll leave this issue open to remind myself to consider adding even more down the road.

pdehaan commented 6 years ago

This is mildly interesting...

https://developers.facebook.com/tools/debug/sharing/?q=https%3A%2F%2Fdata.firefox.com%2Fdashboard%2Fuser-activity

is reporting that we have the following missing properties:

The following required properties are missing: og:url, og:title, og:description, fb:app_id

In fact, here's a sorted+organized version of the rendered <head> element: ```html User Activity | Firefox Public Data Report ```

You can see that we definitely have an og:url, og:title, and og:description, so that's a real head scratcher.

Here's all the "Raw <meta> Tags" that Facebook's OpenGraph debugger tool is findin':

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no" />
<meta name="theme-color" content="#ffffff" />
<meta property="og:image" content="https://data.firefox.com/img/ogimage.png" />
<meta property="og:type" content="website" />

Based on the raw tags, we constructed the following Open Graph properties:

TAG VALUE
og:url https://data.firefox.com/
og:type website
og:title Firefox Public Data Report
og:image https://data.firefox.com/img/ogimage.png
og:updated_time 1535463858
og:description  
ia:markup_url  
ia:markup_url_dev  
ia:rules_url  
ia:rules_url_dev  
og:image:alt  

Looking at the value for og:title (versus the <title> tag and all the instances of the data-react-helmet="true" in the suspicious meta tags), I'm relatively certain what's happening is that the OpenGraph tool isn't executing any JavaScript, so it isn't getting our modified/injected values from the React-Helmet plugin, since it seems the only values it is seeing are the ones that are injected directly in the template.

openjck commented 6 years ago

Looking at the value for og:title (versus the tag and all the instances of the data-react-helmet="true" in the suspicious meta tags), I'm relatively certain what's happening is that the OpenGraph tool isn't executing any JavaScript, so it isn't getting our modified/injected values from the React-Helmet plugin, since it seems the only values it is seeing are the ones that are injected directly in the template.</p> </blockquote> <p>Yep, that explains it alright. But great catch. I'll see what we can do about this.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/pdehaan"><img src="https://avatars.githubusercontent.com/u/557895?v=4" />pdehaan</a> commented <strong> 6 years ago</strong> </div> <div class="markdown-body"> <blockquote> <p>I'll see what we can do about this.</p> </blockquote> <p>Yeah, <a href="https://survivejs.com/webpack/output/server-side-rendering/">SSR</a> (ref: #142; "Switch to Next.js?") is a pretty big hammer to wield, just to fix OG tags.</p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/openjck"><img src="https://avatars.githubusercontent.com/u/933396?v=4" />openjck</a> commented <strong> 5 years ago</strong> </div> <div class="markdown-body"> <p>react-snapshot could help here, acting as a simpler alternative to SSR. I tried setting up react-snapshot in the past and it ended up getting complicated, but it doesn't have to be. I think I was trying to do too much at once at that time.</p> <p><a href="https://github.com/geelen/react-snapshot">https://github.com/geelen/react-snapshot</a></p> </div> </div> <div class="comment"> <div class="user"> <a rel="noreferrer nofollow" target="_blank" href="https://github.com/pdehaan"><img src="https://avatars.githubusercontent.com/u/557895?v=4" />pdehaan</a> commented <strong> 5 years ago</strong> </div> <div class="markdown-body"> <p><strong>react-snapshot</strong> hasn't been updated since Nov '17, which could be somewhat concerning.</p> <p>Another library I've heard a lot about lately, but haven't tried yet is <a href="https://github.com/jaredpalmer/razzle"><strong>razzle</strong></a>:</p> <blockquote> <p>Razzle is a tool that abstracts all complex configuration needed for SSR into a single dependency--giving you the awesome developer experience of create-react-app, but then leaving the rest of your app's architectural decisions about frameworks, routing, and data fetching up to you. With this approach, Razzle not only works with React, but also Reason, Elm, Vue, Angular, and most importantly......whatever comes next.</p> </blockquote> </div> </div> <div class="page-bar-simple"> </div> <div class="footer"> <ul class="body"> <li>© <script> document.write(new Date().getFullYear()) </script> Githubissues.</li> <li>Githubissues is a development platform for aggregating issues.</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script> <script src="/githubissues/assets/js.js"></script> <script src="/githubissues/assets/markdown.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/highlight.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.4.0/build/languages/go.min.js"></script> <script> hljs.highlightAll(); </script> </body> </html>