Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Twitter Cards fix #145

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions auspice-client/customisations/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"navbarComponent": "navbar.js",
"splashComponent": "splash.js",
"socialComponent": "social.js",
"browserTitle": "Nextstrain",
"googleAnalyticsKey": "UA-92687617-1"
}
83 changes: 83 additions & 0 deletions auspice-client/customisations/social.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from 'react'; // eslint-disable-line
import { Helmet } from "react-helmet"; // eslint-disable-line
import ncovCards from "../../static-site/src/components/Cards/nCoVCards";
import communityCards from "../../static-site/src/components/Cards/communityCards";
import coreCards from "../../static-site/src/components/Cards/coreCards";
import narrativeCards from "../../static-site/src/components/Cards/narrativeCards";
import config from "../../static-site/data/SiteConfig";

const siteImage = config.siteLogo;
const allCards = [ncovCards, communityCards, coreCards, narrativeCards];
const imageList = generateImageLookup(allCards, siteImage);

/* This function creates a list that pairs path regexes to their splash images. */
// Example output:
// [
// [/^\/zika.*/, "/splash_images/zika.png"],
// [/^\/WNV.*/, "/splash_images/wnv.jpg"],
// [/.*/, "/logos/nextstrain-logo-small.png"]
// ]
function generateImageLookup(cards, defaultImage) {
let imageLookup = [].concat(...cards);
// Sort reverse alphabetically so that e.g. "/ncov/foo" precedes "/ncov"
imageLookup.sort((a, b) => b.url.localeCompare(a.url));
// Extract path and image from each card, making the path into a valid regex
imageLookup = imageLookup.map((el) => {
const escapedUrl = escapeRegExp(el.url);
const regexString = `^${escapedUrl}.*`;
const regex = new RegExp(regexString);
return [regex, `/splash_images/${el.img}`];
});
// Append the catch-all default image
imageLookup.push([new RegExp(".*"), defaultImage]);
return imageLookup;
}

/* Escapes any regex special characters from a string
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions */
function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&');
}

/* Iterates through the paths and returns the associated image
path if the regex matches the current window path. This will
return the default siteImage if no path is matched. */
function getSocialImage(windowPath, imageLookup=imageList, defaultImage=siteImage) {
for (const [regex, imagePath] of imageLookup) {
if (regex.test(windowPath)) {
return imagePath;
}
}
return defaultImage;
}

const SocialTags = ({metadata, pageTitle}) => {
const url = `${window.location.origin}${window.location.pathname}`;
const socialImagePath = getSocialImage(window.location.pathname);
const socialImageUrl = `${window.location.origin}${socialImagePath}`;

/* react-helmet combines these with existing header values.
These tags will override shared tags from earlier in the tree. */
return (
<Helmet>
{/* OpenGraph tags */}
<meta property="og:url" content={url} />
<meta property="og:type" content="website" />
<meta property="og:title" content={pageTitle} />
{metadata && metadata.title ?
<meta property="og:description" content={metadata.title} /> :
null}
<meta property="og:image" content={socialImageUrl} />

{/* Twitter tags */}
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content={pageTitle} />
{metadata && metadata.title ?
<meta name="twitter:description" content={metadata.title} /> :
null}
<meta name="twitter:image" content={socialImageUrl} />
</Helmet>
);
};

export default SocialTags;
2 changes: 1 addition & 1 deletion static-site/data/SiteConfig.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
siteTitle: "Nextstrain",
siteTitleAlt: "Real-time tracking of pathogen evolution", // Alternative site title for SEO.
siteLogo: "/static/logos/nextstrain-logo-small.png", // Logo used for SEO
siteLogo: "/logos/nextstrain-logo-small.png", // Logo used for SEO
siteUrl: "https://nextstrain.org",
pathPrefix: "/",
siteDescription: "Real-time tracking of pathogen evolution", // Website description used for RSS feeds/meta description tag.
Expand Down
20 changes: 15 additions & 5 deletions static-site/src/components/SEO/SEO.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class SEO extends Component {
return (
<Helmet>
{/* General tags */}
<meta charset="utf-8" />
<meta name="description" content={description} />
<meta name="image" content={image} />

Expand All @@ -80,14 +81,23 @@ class SEO extends Component {

{/* OpenGraph tags */}
<meta property="og:url" content={postSEO ? postURL : blogURL} />
{postSEO ? <meta property="og:type" content="article" /> : null}
{postSEO ?
<meta property="og:type" content="article" /> :
<meta property="og:type" content="website" />
}
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
<meta
property="fb:app_id"
content={config.siteFBAppID ? config.siteFBAppID : ""}
/>
{config.siteFBAppID ?
<meta property="fb:app_id" content={config.siteFBAppID} /> :
null
}

{/* Twitter Card tags */}
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={image} />
</Helmet>
);
}
Expand Down